// © Copyright 1995, Joseph Bergin. All rights reserved.

#ifndef __LogicGate__
#define __LogicGate__

#include "Boolean.h"

// These classes simulate individual logic gates and can
// be connected together to form logic circuits.  To
// connect the output of A to the input of B, execute
//    B.connect(&A);
//	Output will compute the output of any gate, given its
// inputs.
// Improperly connected gates will produce some output,
// but the value is undefined.  

class Gate      // Constant output
{	public:
		Gate(Boolean output = true);
		virtual Boolean output();
		virtual void connect(Gate *);
			// NO-op in this class.
	protected:
		Boolean _level;
};

class UnaryGate: public Gate    	// Identity gate unless
											// overridden
{	public:
		UnaryGate();
		Boolean output();
		void connect(Gate * g);
			// Connect g to input
	protected:
		Gate * _input;

};

class BinaryGate:public Gate
{	public:
		BinaryGate();
		Boolean output();  // true unless overridden
		void connect(Gate * g);
			// First execution connects g to left input
			// Others connect g to right input
	protected:
		Gate * _leftInput;
    		Gate * _rightInput;

};

class AndGate: public BinaryGate
{	public:
		AndGate();
		Boolean output();
			// And of the two inputs
	protected:

};

class OrGate: public BinaryGate
{	public:
		OrGate();
		Boolean output();
			// Or of the two inputs
	protected:

};

class NotGate: public UnaryGate
{	public:
		NotGate();
		Boolean output();
			// Switches input
	protected:

};

// EXERCISE 
class Switch: public Gate
{ 	public:
		Switch(Boolean state = false); // false = off, true = on;
		void flip();
		void on();
		void off();
	protected:

};
#endif

// exercises. Build an nand gate, an xor gate
// build a 1 bit adder with carry.

// build 3 1 bit adders and feed the carries properly
// to build a 3 bit adder. 

