/**
 * Instances of this class receive remote control codes and answer like a TI does.
 * <BR>	-Pin 1 : input 0.
 * <BR>	-Pin 2 : input 1.
 * <BR>	-Pin 3 : output 0.
 * <BR>	-Pin 4 : output 1.
 * <BR>You can read the source of this class <A HREF="./RemotedTI.java.html"> here</A>.
 */
public class RemotedTI extends DigitalComponent_std implements DigitalComponent {

	public RemotedTI(DigitalComponentUI dui) {
		super(4, dui);
		nbits = 0;
		received = "";
		receiving = true;
		nbytes = 0;
		nbCycles = 0;
		KeyCodeLow = 0;
	}

	public RemotedTI() {
		super(4);
		nbits = 0;
		received = "";
		receiving = true;
		nbytes = 0;
		nbCycles = 0;
		KeyCodeLow = 0;
	}

	public void setPinStateDontNotify(int p, boolean state) {
		if((p == 3) || (p == 4)) return;
		if(receiving) {
			if(Pins[1 - 1].getState() && Pins[2 - 1].getState() && !state) {
				switch(p) {
					case 1 : buffer >>= 1; nbits++; setPinState(4, false); break;
					case 2 : buffer = (buffer >> 1) + 128; nbits++; setPinState(3, false); break;
				}
				if(nbits == 8) {
					received += " " + Utils.hex(buffer, 2, 2);
					refreshDisplay();
					nbytes++;
					if(nbytes == 3)
						KeyCodeLow = buffer;
					nbits = 0;
					buffer = 0;
				}
			}
			else if(!(Pins[1 - 1].getState() && Pins[2 - 1].getState()) && state)
				switch(p) {
					case 1 : setPinState(4, true); break;
					case 2 : setPinState(3, true); break;
			}
		}
		else {
			if((Pins[1 - 1].getState() && Pins[2 - 1].getState()) && !state)
				setPinState(3, true);
			else if(!(Pins[1 - 1].getState() && Pins[2 - 1].getState()) && state && (p == 2)) {
				nbits ++;
				if(nbits == 8) {
					nbits = 0;
					nbytes++;
				}
				setPinState(3, false);
			}
		}
		super.setPinStateDontNotify(p, state);
	}

	public String getState() {
		return received;
	}

	public void notifyOneCycle() {
		nbCycles++;
		if(receiving) {
			if(((nbytes % 4) == 0) && (nbytes != 0)) {
				if(nbCycles > 10) nbCycles = 0;
				if(nbCycles == 10) {
					received += " : \"" + (char)KeyCodeLow + "\"\n";
					refreshDisplay();
					receiving = false;
					nbCycles = 0;
					nbytes = 0;
					nbits++;
					setPinState(3, false);
				}
			}
		}
		else {
			if(((nbytes % 4) == 0) && (nbytes != 0)) {
				if(nbCycles > 20) nbCycles = 0;
				if(nbCycles == 20) {
					nbytes = 0;
					receiving = true;
					nbCycles = 0;
					nbits = 0;
					setPinState(3, true);
				}
			}
		}
	}

	protected int buffer, nbits, nbytes, nbCycles, KeyCodeLow;
	protected String received;
	protected boolean receiving;
}