import java.util.*;
import java.awt.*;
import java.applet.*;
import java.io.*;

public class DrawTest extends Applet {
    static About about;
    public static mainMenu themainMenu = new mainMenu();
    static boolean firstTime = true;

//------------------------------------------------------------------------------------
    public void init() {
        super.init();
        //{{INIT_CONTROLS
        setLayout(new BorderLayout());
        label1=new Label("Digital Simulator", Label.CENTER);
        label1.setFont(new Font("TimesRoman",Font.BOLD|Font.ITALIC,20));
        add("North",label1);
        label1.reshape(208,0,291,28);
        label2=new Label("Wellcome to the Digital Simulator", Label.CENTER);
        label2.setFont(new Font("TimesRoman",Font.BOLD,12));
        add("Center",label2);
        label2.reshape(242,32,227,19);
        button1=new Button("Continue");
        button1.setFont(new Font("TimesRoman",Font.BOLD,14));
        add("South",button1);
        button1.reshape(289,56,129,47);
        //}}
        resize(200,100);
    }

//------------------------------------------------------------------------------------
    public boolean handleEvent(Event e) {

	    if (e.id == Event.ACTION_EVENT && e.target == button1) {
	    	    clickedButton1();
	    	    return true;
	    }

	    switch (e.id) {
	        case Event.WINDOW_DESTROY:
	            System.exit(0);
	            return true;
	        default:
	            return false;
	    }
    }

    //{{DECLARE_CONTROLS
    Label label1;
    Label label2;
    Button button1;
    //}}

//------------------------------------------------------------------------------------
    public void clickedButton1() {

        // to do: put event handler code here.
        if (this.firstTime == true){
            DrawCanvas dp = new DrawCanvas();
	        themainMenu.add("Center", dp);
            themainMenu.add("East",new Our_Buttons(dp));
            this.firstTime = false;
        }
        themainMenu.resize(1000, 710);
        themainMenu.selectedNew();
        themainMenu.show();
    }
}

//*******************************************************************************************

class DrawCanvas extends Canvas{

    public static int SIZE       = 30;
    public static final int NONE       = -1;
    public static final int CLEAR      = 1;

    public static final int OR         = 0;
    public static final int AND        = 2;
    public static final int NOT        = 3;
    public static final int LED        = 4;
    public static final int FLIPFLOP   = 5;
    public static final int GROUND     = 6;
    public static final int VOLTAGE    = 7;
    public static final int SPLITTER   = 8;
    public static final int CLOCK      = 9;
    public static final int XOR        = 21;
    public static final int INPUT      = 22;

    public static final int DELETE     = 10;
    public static final int MOVE       = 11;
    public static final int CONNECT    = 12;
    public static final int DELETECONNECT = 13;
    public static final int FIRSTPORT  = 14;
    public static final int SECONDPORT = 15;
    public static final int OUTPORT    = 16;
    public static final int OUTPORT1   = 17;
    public static final int OUTPORT2   = 18;
    public static final int NEW        = 19;
    public static final int SIMULATION = 20;
    public static int selectedGateIndex = NONE;
    public static int mode = NONE;
    public static int counter  = 0;
    public static int sCounter = 0;
    public Color col = new Color(0, 0, 255);
    public static Vector gateVector = new Vector();
    public static int nof_gates = 0;
    public static int x = 0;
    public static int y = 0;
    public static int oldX = 0;
    public static int oldY = 0;
    public static int oldMode = NONE;
    static int drawMode = NONE;
    static int fgtc = NONE;
    static int sgtc = NONE;
    static int selectedPort1 = NONE;
    static int selectedPort2 = NONE;
    static int selectedPort = NONE;
    boolean nothing = false;

    Gate currentGate;

//------------------------------------------------------------------------------------
    public DrawCanvas() {
	    setBackground(col.black);
    }

//------------------------------------------------------------------------------------
    public boolean handleEvent(Event event) {

        if (event.id == Event.MOUSE_DOWN) {
           if (this.mode != this.SIMULATION)
                MouseDown(event, event.x, event.y);
           else
                simulationMouseDown(event, event.x, event.y);
           return true;
        }
        else if (event.id == Event.MOUSE_DRAG) {
           if (this.mode != this.SIMULATION)
                MouseDrag(event, event.x, event.y);
           return true;
        }
        else if (event.id == Event.MOUSE_UP) {
           if (this.mode != this.SIMULATION)
                MouseUp(event, event.x, event.y);
           return true;
        }
        return true;
        //repaint();
    }

//------------------------------------------------------------------------------------
    public void simulate(){

        int np = this.gateVector.size();

        for (int i=0; i<np; i++){
            Gate p = (Gate)this.gateVector.elementAt(i);
            if ((p.type == this.LED) || (p.type == this.INPUT))
                repaint(p.x + this.SIZE/5, p.y + this.SIZE/5, 4*this.SIZE/5, 4*this.SIZE/5);
        }

        this.sCounter = this.sCounter + 1;
    }

//------------------------------------------------------------------------------------
    public boolean simulationMouseDown(Event e, int x, int y){

	    for (int i=0; i < gateVector.size(); i++) {
	        Gate p = (Gate)gateVector.elementAt(i);

	        /* body of the gate is selected */
	        if ((x>p.x+(DrawCanvas.SIZE/5))&&(x<p.x -(DrawCanvas.SIZE/5)+this.SIZE)&&
	            (y>p.y+(DrawCanvas.SIZE/5))&&(y<p.y -(DrawCanvas.SIZE/5)+this.SIZE)&&(p.type==this.INPUT)){
                selectedGateIndex = i;
                if (p.changed == 0)
                    p.changed = 1;
                else
                    p.changed = 0;
                p.evaluateOutput();
                selectedPort = this.NONE;
                this.nothing = false;
                this.gateVector.setElementAt(p, i);
	        }
	        else
	            selectedGateIndex = this.NONE;
	    }
	    return true;
	}

//------------------------------------------------------------------------------------
    public void setDrawMode(int mode) {

	    switch (mode) {
	        case AND:
	        case OR:
	        case NOT:
	        case LED:
	        case GROUND:
	        case FLIPFLOP:
	        case VOLTAGE:
	        case SPLITTER:
	        case CLOCK:
	        case XOR:
	        case INPUT:
                this.nof_gates = this.nof_gates + 1;
	            this.mode = mode;
	            this.drawMode = this.NEW;
	            this.selectedGateIndex = this.NONE;
	            break;
	        case SIMULATION:
	            this.simulate();
	            this.mode = mode;
	            break;
	        case DELETE:
	        case CLEAR:
	        case NONE:
	        case DELETECONNECT:
	            this.mode = mode;
	            break;
	        default:
	            throw new IllegalArgumentException();
	    }
    }

//------------------------------------------------------------------------------------
    public boolean MouseDown(Event e, int x, int y){

	    oldX = x; oldY = y;
	    for (int i=0; i < gateVector.size(); i++) {
	        Gate p = (Gate)gateVector.elementAt(i);

	        /* body of the gate is selected */
	        if ((x>p.x+(DrawCanvas.SIZE/5))&&(x<p.x -(DrawCanvas.SIZE/5)+this.SIZE)&&
	            (y>p.y+(DrawCanvas.SIZE/5))&&(y<p.y -(DrawCanvas.SIZE/5)+this.SIZE)){
	            this.x = p.x; this.y = p.y;
	            this.mode = p.type;
                this.drawMode = this.MOVE;
                selectedGateIndex = i;
                selectedPort = this.NONE;
                this.nothing = false;
                return true;
	        }
	        /* upper input port is selected */
	        else if ((x>p.x)&&(x<p.x +(DrawCanvas.SIZE/5)) && (p.nofInputs==2)&&
	                (y>p.y+(DrawCanvas.SIZE/5))&&(y<p.y +(2*DrawCanvas.SIZE/5))){
                      selectedPort1 = this.FIRSTPORT;
                      selectedPort = selectedPort1;
                      fgtc = i;
                      selectedGateIndex = i;                     
                      if ( (p.Input1 == this.NONE)||(p.Led1 == this.NONE))
                         this.drawMode = this.CONNECT;
                      this.nothing = false;
                      return true;
            }
	        /* lower input port is selected */
            else if ((x>p.x)&&(x<p.x +(DrawCanvas.SIZE/5)) && (p.nofInputs==2)&&
                     (y>p.y+(3*DrawCanvas.SIZE/5))&&(y<p.y +(4*DrawCanvas.SIZE/5))){
                      selectedPort1 = this.SECONDPORT;
                      selectedPort = selectedPort1;
                      fgtc = i;
                      if ((p.Input2 == this.NONE)||(p.Led2 == this.NONE))
                         this.drawMode = this.CONNECT;
                      selectedGateIndex = i;
                      this.nothing = false;
                      return true;
	        }
	        /* output port of single output gates is selected */
            else if ((x>p.x+(4*DrawCanvas.SIZE/5))&&(x<p.x +(DrawCanvas.SIZE)) && (p.nofOutputs==1)&&
                     (y>p.y+(2*DrawCanvas.SIZE/5))&&(y<p.y +(3*DrawCanvas.SIZE/5))){
                        selectedPort1 = this.OUTPORT;
                        fgtc = i;
                        selectedPort = selectedPort1;
                        selectedGateIndex = i;
                        if ((p.Output == this.NONE)||(p.Led3 == this.NONE))
                            this.drawMode = this.CONNECT;
                        this.nothing = false;
                        return true;
            }
	        /* upper output port of splitter is selected */
            else if ((x>p.x+(4*DrawCanvas.SIZE/5))&&(x<p.x +(DrawCanvas.SIZE)) && (p.nofOutputs==2)&&
                     (y>p.y+(DrawCanvas.SIZE/5))&&(y<p.y +(2*DrawCanvas.SIZE/5))){
                        selectedPort1 = this.OUTPORT1;
                        selectedPort = selectedPort1;
                        fgtc = i;
                        selectedGateIndex = i;
                        if ((p.sOutput1 == this.NONE)||(p.Led3 == this.NONE))
                           this.drawMode = this.CONNECT;
                        this.nothing = false;
                        return true;
            }
	        /* lower output port of splitter is selected */
            else if ((x>p.x+(4*DrawCanvas.SIZE/5))&&(x<p.x +(DrawCanvas.SIZE)) && (p.nofOutputs==2)&&
                     (y>p.y+(3*DrawCanvas.SIZE/5))&&(y<p.y +(4*DrawCanvas.SIZE/5))){
                        selectedPort1 = this.OUTPORT2;
                        selectedPort = selectedPort1;
                        fgtc = i;
                        selectedGateIndex = i;
                        if ((p.sOutput2 == this.NONE)||(p.Led4 == this.NONE))
                           this.drawMode = this.CONNECT;
                        this.nothing = false;
                        return true;
            }
	        /* input port of single input gates is selected */
            else if ((x>p.x)&&(x<p.x +(DrawCanvas.SIZE/5)) && (p.nofInputs==1) &&
                     (y>p.y+(2*DrawCanvas.SIZE/5))&&(y<p.y +(3*DrawCanvas.SIZE/5))){
                      selectedPort1 = this.FIRSTPORT;
                      selectedPort = selectedPort1;
                      fgtc = i;
                      selectedGateIndex = i;
                      if ((p.Input1 == this.NONE)||(p.Led1 == this.NONE))
                         this.drawMode = this.CONNECT;
                      this.nothing = false;
                      return true;
            }
            else
                this.nothing = true;
    }
        if (this.drawMode == this.NEW)
            this.nothing = false;
        this.selectedGateIndex = this.NONE;
        this.selectedPort = this.NONE;
        return true;
    }

//------------------------------------------------------------------------------------
    public boolean MouseDrag(Event e, int x, int y){

        if (((x - oldX > 5) || (x - oldX < -5)) ||
            ((y - oldY > 5) || (y - oldY < -5)) ){
            this.x = x; this.y = y;
        }
        if (this.drawMode == this.CONNECT){
            this.x = x; this.y = y;
        }


        if ((selectedGateIndex != this.NONE)&&(this.drawMode == this.MOVE )){
            Gate p = (Gate)gateVector.elementAt(selectedGateIndex);
            p.x = this.x;
            p.y = this.y;
            gateVector.setElementAt(p,selectedGateIndex);
        }


        if (this.nothing == false)
            repaint();

        return true;
    }

//------------------------------------------------------------------------------------
    public boolean MouseUp(Event e, int x, int y){

      if (((x - oldX > 5) || (x - oldX < -5)) ||
            ((y - oldY > 5) || (y - oldY < -5)) ){
           this.x = x; this.y = y;
      }

      if (this.drawMode == this.CONNECT){
            this.x = x; this.y = y;
      }

      int runningMan = 0;

      if (this.drawMode == this.CONNECT){
        this.drawMode = this.NONE;
	    for (int i=0; i < gateVector.size(); i++) {
	        Gate p = (Gate)gateVector.elementAt(i);
	        /* upper input port of double input gates is to be connected */
	        if ((x>p.x)&&(x<p.x +(DrawCanvas.SIZE/5)) && (p.nofInputs==2)&&
	                (y>p.y+(DrawCanvas.SIZE/5))&&(y<p.y +(2*DrawCanvas.SIZE/5))){
                      selectedPort2 = this.FIRSTPORT;
                      this.selectedPort = selectedPort2;
                      sgtc = i;
                      selectedGateIndex = i;
                      runningMan = 1;
            }
	        /* lower input port of double input gates is to be connected */
            else if ((x>p.x)&&(x<p.x +(DrawCanvas.SIZE/5)) && (p.nofInputs==2)&&
                     (y>p.y+(3*DrawCanvas.SIZE/5))&&(y<p.y +(4*DrawCanvas.SIZE/5))){
                      selectedPort2 = this.SECONDPORT;
                      this.selectedPort = selectedPort2;
                      sgtc = i;
                      selectedGateIndex = i;
                      runningMan = 1;
	        }
	        /* output port of single output gates is to be connected */
            else if ((x>p.x+(4*DrawCanvas.SIZE/5))&&(x<p.x +(DrawCanvas.SIZE)) && (p.nofOutputs==1)&&
                     (y>p.y+(2*DrawCanvas.SIZE/5))&&(y<p.y +(3*DrawCanvas.SIZE/5))){
                        selectedPort2 = this.OUTPORT;
                        this.selectedPort = selectedPort2;
                        sgtc = i;
                        selectedGateIndex = i;
                        runningMan = 1;
            }
	        /* upper output port of splitter is to be connected */
            else if ((x>p.x+(4*DrawCanvas.SIZE/5))&&(x<p.x +(DrawCanvas.SIZE)) &&(p.nofOutputs==2)&&
                     (y>p.y+(DrawCanvas.SIZE/5))&&(y<p.y +(2*DrawCanvas.SIZE/5))){
                        selectedPort2 = this.OUTPORT1;
                        this.selectedPort = selectedPort2;
                        sgtc = i;
                        selectedGateIndex = i;
                        runningMan = 1;
            }
	        /* lower output port of splitter is to be connected */
            else if ((x>p.x+(4*DrawCanvas.SIZE/5))&&(x<p.x +(DrawCanvas.SIZE)) &&(p.nofOutputs==2)&&
                     (y>p.y+(3*DrawCanvas.SIZE/5))&&(y<p.y +(4*DrawCanvas.SIZE/5))){
                        selectedPort2 = this.OUTPORT2;
                        this.selectedPort = selectedPort2;
                        sgtc = i;
                        selectedGateIndex = i;
                        runningMan = 1;
            }
            /* output port of single output gates is to be connected */
            else if ((x>p.x)&&(x<p.x +(DrawCanvas.SIZE/5)) && (p.nofInputs==1) &&
                     (y>p.y+(2*DrawCanvas.SIZE/5))&&(y<p.y +(3*DrawCanvas.SIZE/5))){
                      selectedPort2 = this.FIRSTPORT;
                      this.selectedPort = selectedPort2;
                      sgtc = i;
                      selectedGateIndex = i;
                      runningMan = 1;
            }
     }

     if ( (runningMan == 1) ) {

        Gate q = (Gate)gateVector.elementAt(fgtc);
        Gate t = (Gate)gateVector.elementAt(sgtc);

        if ( ( (selectedPort1 == this.FIRSTPORT) || (selectedPort1 == this.SECONDPORT) ) &&
            ( (selectedPort2 == this.FIRSTPORT) || (selectedPort2 == this.SECONDPORT) ) )
            if ( ( (q.type != this.LED) && (t.type == this.LED))||((q.type == this.LED) && (t.type != this.LED)))
                runningMan = 1;
            else
                runningMan = 0;

        if ( ( (selectedPort1 == this.OUTPORT) || (selectedPort1 == this.OUTPORT1) || (selectedPort1 == this.OUTPORT2) ) &&
            ( (selectedPort2 == this.OUTPORT) || (selectedPort2 == this.OUTPORT1)|| (selectedPort2 == this.OUTPORT2) ) )
            runningMan = 0;


        if ( (q.type == this.CLOCK) && !( (t.type == this.FLIPFLOP) && (selectedPort2 == this.SECONDPORT) ) )
            runningMan = 0;

        if ( (t.type == this.CLOCK) && !( (q.type == this.FLIPFLOP) && (selectedPort1 == this.SECONDPORT) ) )
             runningMan = 0;

        if ( (selectedPort2 == this.FIRSTPORT) && (t.Input1 != this.NONE) && (q.type != this.LED) )
             runningMan = 0;

        if ( (selectedPort2 == this.FIRSTPORT) && (t.Input1 == this.NONE) && (q.type == this.LED) && (t.Led1 != this.NONE))
             runningMan = 0;

        if ( (selectedPort2 == this.SECONDPORT) && (t.Input2 != this.NONE)&& (q.type != this.LED) )
             runningMan = 0;

        if ( (selectedPort2 == this.SECONDPORT) && (t.Input2 == this.NONE) && (q.type == this.LED) && (t.Led2 != this.NONE))
             runningMan = 0;

        if ( (selectedPort2 == this.OUTPORT) && (t.Output != this.NONE)&& (q.type != this.LED) )
             runningMan = 0;

        if ( (selectedPort2 == this.OUTPORT) && (t.Output == this.NONE) && (q.type == this.LED) && (t.Led3 != this.NONE))
             runningMan = 0;

        if ( (selectedPort2 == this.OUTPORT1) && (t.sOutput1 != this.NONE)&& (q.type != this.LED) )
             runningMan = 0;

        if ( (selectedPort2 == this.OUTPORT1) && (t.sOutput1 == this.NONE) && (q.type == this.LED) && (t.Led3 != this.NONE))
             runningMan = 0;

        if ( (selectedPort2 == this.OUTPORT2) && (t.sOutput2 != this.NONE)&& (q.type != this.LED) )
             runningMan = 0;

        if ( (selectedPort2 == this.OUTPORT2) && (t.sOutput2 == this.NONE) && (q.type == this.LED) && (t.Led4 != this.NONE))
             runningMan = 0;

        if ( (fgtc==sgtc) && (q.type!=this.FLIPFLOP) )
             runningMan = 0;

        if ( (selectedPort1 == this.FIRSTPORT) && (q.Input1 != this.NONE) && (t.type!= this.LED) )
             runningMan = 0;

        if ( (selectedPort1 == this.FIRSTPORT) && (q.Input1 == this.NONE) && (t.type == this.LED) && (q.Led1 != this.NONE))
             runningMan = 0;

        if ( (selectedPort1 == this.SECONDPORT) && (q.Input2 != this.NONE)&& (t.type!= this.LED) )
             runningMan = 0;

        if ( (selectedPort1 == this.SECONDPORT) && (q.Input2 == this.NONE) && (t.type == this.LED) && (q.Led2 != this.NONE))
             runningMan = 0;

        if ( (selectedPort1 == this.OUTPORT) && (q.Output != this.NONE)&& (t.type!= this.LED) )
             runningMan = 0;

        if ( (selectedPort1 == this.OUTPORT) && (q.Output == this.NONE) && (t.type == this.LED) && (q.Led3 != this.NONE))
             runningMan = 0;

        if ( (selectedPort1 == this.OUTPORT1) && (q.sOutput1 != this.NONE)&& (t.type!= this.LED) )
             runningMan = 0;

        if ( (selectedPort1 == this.OUTPORT1) && (q.sOutput1 == this.NONE) && (t.type == this.LED) && (q.Led3 != this.NONE))
             runningMan = 0;

        if ( (selectedPort1 == this.OUTPORT2) && (q.sOutput2 != this.NONE)&& (t.type!= this.LED) )
             runningMan = 0;

        if ( (selectedPort1 == this.OUTPORT2) && (q.sOutput2 == this.NONE) && (t.type == this.LED) && (q.Led4 != this.NONE))
             runningMan = 0;

        if ( ( (q.type == this.AND) || (q.type == this.OR) || (q.type == this.NOT) || (q.type == this.SPLITTER) || (q.type == this.XOR))&&
            ( (t.type == this.AND) || (t.type == this.OR) || (t.type == this.NOT) || (t.type == this.SPLITTER) || (q.type == this.XOR)) ){
                if (((selectedPort1 == this.FIRSTPORT) || (selectedPort1 == this.SECONDPORT) )&&
                    ((selectedPort2 == this.OUTPORT) || (selectedPort2 == this.OUTPORT1) || (selectedPort2 == this.OUTPORT2))){
                        if (q.isCircle(fgtc, sgtc)){
                            runningMan = 0;
                        }
                    }

                if (((selectedPort2 == this.FIRSTPORT) || (selectedPort2 == this.SECONDPORT) )&&
                    ((selectedPort1 == this.OUTPORT) || (selectedPort1 == this.OUTPORT1) || (selectedPort1 == this.OUTPORT2))){
                        if (q.isCircle(sgtc, fgtc)){
                            runningMan = 0;
                        }
                    }
          }
     }

     if (runningMan == 1){

        Gate p = (Gate)gateVector.elementAt(sgtc);
        Gate q = (Gate)gateVector.elementAt(fgtc);

        if (q.type != this.LED){
            switch (selectedPort2){
                case FIRSTPORT:
                    p.Input1 = fgtc;
                    p.Port1 = selectedPort1;
                    break;
                case SECONDPORT:
                    p.Input2 = fgtc;
                    p.Port2 = selectedPort1;
                    break;
                case OUTPORT:
                    p.Output = fgtc;
                    p.Port3 = selectedPort1;
                    break;
                case OUTPORT1:
                    p.sOutput1 = fgtc;
                    p.Port3 = selectedPort1;
                    break;
                case OUTPORT2:
                    p.sOutput2 = fgtc;
                    p.Port4 = selectedPort1;
                    break;
            }
        }
        else{
            switch (selectedPort2){
                case FIRSTPORT:
                    p.Led1 = fgtc;
                    break;
                case SECONDPORT:
                    p.Led2 = fgtc;
                    break;
                case OUTPORT:
                case OUTPORT1:
                    p.Led3 = fgtc;
                    break;
                case OUTPORT2:
                    p.Led4 = fgtc;
                    break;
            }
           }

        gateVector.setElementAt(p,sgtc);

        if (p.type != this.LED){
            switch (selectedPort1){
                case FIRSTPORT:
                    q.Input1 = sgtc;
                    q.Port1 = selectedPort2;
                    break;
                case SECONDPORT:
                    q.Input2 = sgtc;
                    q.Port2 = selectedPort2;
                    break;
                case OUTPORT:
                    q.Output = sgtc;
                    q.Port3 = selectedPort2;
                    break;
                case OUTPORT1:
                    q.sOutput1 = sgtc;
                    q.Port3 = selectedPort2;
                    break;
                case OUTPORT2:
                    q.sOutput2 = sgtc;
                    q.Port4 = selectedPort2;
                    break;
            }
        }
        else{
            switch (selectedPort1){
                case FIRSTPORT:
                    q.Led1 = sgtc;
                    break;
                case SECONDPORT:
                    q.Led2 = sgtc;
                    break;
                case OUTPORT:
                case OUTPORT1:
                    q.Led3 = sgtc;
                    break;
                case OUTPORT2:
                     q.Led4 = sgtc;
                    break;
            }
        }
        gateVector.setElementAt(q,fgtc);
     }
   }

        if ((this.mode != this.NONE)&&(this.mode != this.DELETE)){
            if (this.drawMode == this.NEW){
                gateVector.addElement(new Gate(this.x, this.y, this.mode));
                selectedGateIndex = gateVector.size()-1;
            }
        }

        if ((selectedGateIndex != this.NONE)&&(this.drawMode == this.MOVE )){
            Gate p = (Gate)gateVector.elementAt(selectedGateIndex);
            p.x = this.x;
            p.y = this.y;
            gateVector.setElementAt(p,selectedGateIndex);
        }


        this.mode = this.NONE;
        this.drawMode = this.NONE;
        this.x = 0; this.y = 0;
        repaint();
        return true;
    }

//------------------------------------------------------------------------------------
    public void paint(Graphics g) {

        Dimension my_size = new Dimension();

        my_size = this.size();
        g.setColor(Color.white);
        if ((this.mode == this.DELETE) && (selectedGateIndex != this.NONE)){
          Gate p = (Gate)gateVector.elementAt(selectedGateIndex);
          Gate r = (Gate)gateVector.elementAt(0);
          if (p.type != this.LED){
             if (p.Input1 != this.NONE){
                r = (Gate)gateVector.elementAt(p.Input1);
                switch (p.Port1){
                    case this.FIRSTPORT:
                      r.Input1 = this.NONE;
                      r.Port1 = this.NONE;
                      break;
                    case this.SECONDPORT:
                      r.Input2 = this.NONE;
                      r.Port2 = this.NONE;
                      break;
                    case this.OUTPORT:
                      r.Output = this.NONE;
                      r.Port3 = this.NONE;
                      break;
                    case this.OUTPORT1:
                      r.sOutput1 = this.NONE;
                      r.Port3 = this.NONE;
                      break;
                    case this.OUTPORT2:
                      r.sOutput2 = this.NONE;
                      r.Port4 = this.NONE;
                      break;
                }
                gateVector.setElementAt(r, p.Input1);
            }

            if (p.Input2 != this.NONE){
                r = (Gate)gateVector.elementAt(p.Input2);
                switch (p.Port2){
                    case this.FIRSTPORT:
                      r.Input1 = this.NONE;
                      r.Port1 = this.NONE;
                      break;
                    case this.SECONDPORT:
                      r.Input2 = this.NONE;
                      r.Port2 = this.NONE;
                      break;
                    case this.OUTPORT:
                      r.Output = this.NONE;
                      r.Port3 = this.NONE;
                      break;
                    case this.OUTPORT1:
                      r.sOutput1 = this.NONE;
                      r.Port3 = this.NONE;
                      break;
                    case this.OUTPORT2:
                      r.sOutput2 = this.NONE;
                      r.Port4 = this.NONE;
                      break;
                }
                gateVector.setElementAt(r, p.Input2);
            }

            if (p.Output != this.NONE){
                r = (Gate)gateVector.elementAt(p.Output);
                switch (p.Port3){
                    case this.FIRSTPORT:
                      r.Input1 = this.NONE;
                      r.Port1 = this.NONE;
                      break;
                    case this.SECONDPORT:
                      r.Input2 = this.NONE;
                      r.Port2 = this.NONE;
                      break;
                    case this.OUTPORT:
                      r.Output = this.NONE;
                      r.Port3 = this.NONE;
                      break;
                    case this.OUTPORT1:
                      r.sOutput1 = this.NONE;
                      r.Port3 = this.NONE;
                      break;
                    case this.OUTPORT2:
                      r.sOutput2 = this.NONE;
                      r.Port4 = this.NONE;
                      break;
                }
                gateVector.setElementAt(r, p.Output);
            }

            if (p.sOutput1 != this.NONE){
                r = (Gate)gateVector.elementAt(p.sOutput1);
                switch (p.Port3){
                    case this.FIRSTPORT:
                      r.Input1 = this.NONE;
                      r.Port1 = this.NONE;
                      break;
                    case this.SECONDPORT:
                      r.Input2 = this.NONE;
                      r.Port2 = this.NONE;
                      break;
                    case this.OUTPORT:
                      r.Output = this.NONE;
                      r.Port3 = this.NONE;
                      break;
                    case this.OUTPORT1:
                      r.sOutput1 = this.NONE;
                      r.Port3 = this.NONE;
                      break;
                    case this.OUTPORT2:
                      r.sOutput2 = this.NONE;
                      r.Port4 = this.NONE;
                      break;
                }
                gateVector.setElementAt(r, p.sOutput1);
            }

            if (p.sOutput2 != this.NONE){
                r = (Gate)gateVector.elementAt(p.sOutput2);
                switch (p.Port4){
                    case this.FIRSTPORT:
                      r.Input1 = this.NONE;
                      r.Port1 = this.NONE;
                      break;
                    case this.SECONDPORT:
                      r.Input2 = this.NONE;
                      r.Port2 = this.NONE;
                      break;
                    case this.OUTPORT:
                      r.Output = this.NONE;
                      r.Port3 = this.NONE;
                      break;
                    case this.OUTPORT1:
                      r.sOutput1 = this.NONE;
                      r.Port3 = this.NONE;
                      break;
                    case this.OUTPORT2:
                      r.sOutput2 = this.NONE;
                      r.Port4 = this.NONE;
                      break;
                }
                gateVector.setElementAt(r, p.sOutput2);
            }
            if (p.Led1 != this.NONE){
                r = (Gate)gateVector.elementAt(p.Led1);
                r.Input1 = this.NONE;
                r.Port1 = this.NONE;
                gateVector.setElementAt(r, p.Led1);
            }

            if (p.Led2 != this.NONE){
                r = (Gate)gateVector.elementAt(p.Led2);
                r.Input1 = this.NONE;
                r.Port1 = this.NONE;
                gateVector.setElementAt(r, p.Led2);
            }
            if (p.Led3 != this.NONE){
                r = (Gate)gateVector.elementAt(p.Led3);
                r.Input1 = this.NONE;
                r.Port1 = this.NONE;
                gateVector.setElementAt(r, p.Led3);
            }
            if (p.Led4 != this.NONE){
                r = (Gate)gateVector.elementAt(p.Led4);
                r.Input1 = this.NONE;
                r.Port1 = this.NONE;
                gateVector.setElementAt(r, p.Led4);
            }

          }
          else{
             if (p.Input1 != this.NONE){
                r = (Gate)gateVector.elementAt(p.Input1);
                switch (p.Port1){
                    case this.FIRSTPORT:
                      r.Led1 = this.NONE;
                      break;
                    case this.SECONDPORT:
                      r.Led2 = this.NONE;
                      break;
                    case this.OUTPORT:
                    case this.OUTPORT1:
                      r.Led3 = this.NONE;
                      break;
                    case this.OUTPORT2:
                      r.Led4 = this.NONE;
                      break;
                }
                gateVector.setElementAt(r, p.Input1);
            }

          }
      if (this.selectedGateIndex != (gateVector.size()-1)){
            p = (Gate)gateVector.elementAt((gateVector.size()-1));
          if (p.type != this.LED){
            if (p.Input1 != this.NONE){
                r = (Gate)gateVector.elementAt(p.Input1);
                switch (p.Port1){
                    case this.FIRSTPORT:
                      r.Input1 = selectedGateIndex;
                      break;
                    case this.SECONDPORT:
                      r.Input2 = selectedGateIndex;
                      break;
                    case this.OUTPORT:
                      r.Output = selectedGateIndex;
                      break;
                    case this.OUTPORT1:
                      r.sOutput1 = selectedGateIndex;
                      break;
                    case this.OUTPORT2:
                      r.sOutput2 = selectedGateIndex;
                      break;
                }
                gateVector.setElementAt(r, p.Input1);
            }

            if (p.Input2 != this.NONE){
                r = (Gate)gateVector.elementAt(p.Input2);
                switch (p.Port2){
                    case this.FIRSTPORT:
                      r.Input1 = selectedGateIndex;
                      break;
                    case this.SECONDPORT:
                      r.Input2 = selectedGateIndex;
                      break;
                    case this.OUTPORT:
                      r.Output = selectedGateIndex;
                      break;
                    case this.OUTPORT1:
                      r.sOutput1 = selectedGateIndex;
                      break;
                    case this.OUTPORT2:
                      r.sOutput2 = selectedGateIndex;
                      break;
                }
                gateVector.setElementAt(r, p.Input2);
            }

            if (p.Output != this.NONE){
                r = (Gate)gateVector.elementAt(p.Output);
                switch (p.Port3){
                    case this.FIRSTPORT:
                      r.Input1 = selectedGateIndex;
                      break;
                    case this.SECONDPORT:
                      r.Input2 = selectedGateIndex;
                      break;
                    case this.OUTPORT:
                      r.Output = selectedGateIndex;
                      break;
                    case this.OUTPORT1:
                      r.sOutput1 = selectedGateIndex;
                      break;
                    case this.OUTPORT2:
                      r.sOutput2 = selectedGateIndex;
                      break;
                }
                gateVector.setElementAt(r, p.Output);
            }
            if (p.sOutput1 != this.NONE){
                r = (Gate)gateVector.elementAt(p.sOutput1);
                switch (p.Port3){
                    case this.FIRSTPORT:
                      r.Input1 = selectedGateIndex;
                      break;
                    case this.SECONDPORT:
                      r.Input2 = selectedGateIndex;
                      break;
                    case this.OUTPORT:
                      r.Output = selectedGateIndex;
                      break;
                    case this.OUTPORT1:
                      r.sOutput1 = selectedGateIndex;
                      break;
                    case this.OUTPORT2:
                      r.sOutput2 = selectedGateIndex;
                      break;
                }
                gateVector.setElementAt(r, p.sOutput1);
            }

            if (p.sOutput2 != this.NONE){
                r = (Gate)gateVector.elementAt(p.sOutput2);
                switch (p.Port4){
                    case this.FIRSTPORT:
                      r.Input1 = selectedGateIndex;
                      break;
                    case this.SECONDPORT:
                      r.Input2 = selectedGateIndex;
                      break;
                    case this.OUTPORT:
                      r.Output = selectedGateIndex;
                      break;
                    case this.OUTPORT1:
                      r.sOutput1 = selectedGateIndex;
                      break;
                    case this.OUTPORT2:
                      r.sOutput2 = selectedGateIndex;
                      break;
                }
                gateVector.setElementAt(r, p.sOutput2);
            }

            if (p.Led1 != this.NONE){
                r = (Gate)gateVector.elementAt(p.Led1);
                r.Input1 = selectedGateIndex;
                gateVector.setElementAt(r, p.Led1);
            }

            if (p.Led2 != this.NONE){
                r = (Gate)gateVector.elementAt(p.Led2);
                r.Input1 = selectedGateIndex;
                gateVector.setElementAt(r,p.Led2);
            }
            if (p.Led3 != this.NONE){
                r = (Gate)gateVector.elementAt(p.Led3);
                r.Input1 = selectedGateIndex;
                gateVector.setElementAt(r, p.Led3);
            }
            if (p.Led4 != this.NONE){
                r = (Gate)gateVector.elementAt(p.Led4);
                r.Input1 = selectedGateIndex;
                gateVector.setElementAt(r, p.Led4);
            }
          }
          else{
             if (p.Input1 != this.NONE){
                r = (Gate)gateVector.elementAt(p.Input1);
                switch (p.Port1){
                    case this.FIRSTPORT:
                      r.Led1 = selectedGateIndex;
                      break;
                    case this.SECONDPORT:
                      r.Led2 = selectedGateIndex;
                      break;
                    case this.OUTPORT:
                    case this.OUTPORT1:
                      r.Led3 = selectedGateIndex;
                      break;
                    case this.OUTPORT2:
                      r.Led4 = selectedGateIndex;
                      break;
                }
                gateVector.setElementAt(r, p.Input1);
            }
          }
          gateVector.setElementAt(p, selectedGateIndex);
          gateVector.removeElementAt((gateVector.size()-1));
      }
      else{
          gateVector.removeElementAt(selectedGateIndex);
      }
      selectedGateIndex = this.NONE;
      selectedPort = this.NONE;
      this.mode = this.NONE;
      }
        // deleting the connection between two gates
        int a = this.NONE, b = this.NONE;
        if ((this.mode == this.DELETECONNECT)&&(selectedGateIndex != this.NONE)
            &&(selectedPort != this.NONE)){

         Gate r = (Gate)gateVector.elementAt(0);
         Gate q = (Gate)gateVector.elementAt(selectedGateIndex);
         // deleting the connection of the first gate
         if (q.type != this.LED){
            switch (selectedPort){
                case this.FIRSTPORT:
                    if (q.Input1!=NONE){
                        r = (Gate)gateVector.elementAt(q.Input1);
                        a = q.Port1;
                        b = q.Input1;
                        q.Port1  = this.NONE;
                        q.Input1 = this.NONE;
                    }
                    break;
                case this.SECONDPORT:
                    if (q.Input2!=NONE){
                        r = (Gate)gateVector.elementAt(q.Input2);
                        a = q.Port2;
                        b = q.Input2;
                        q.Port2  = this.NONE;
                        q.Input2 = this.NONE;
                    }
                    break;
                case this.OUTPORT:
                    if (q.Output!=NONE){
                        r = (Gate)gateVector.elementAt(q.Output);
                        a = q.Port3;
                        b = q.Output;
                        q.Port3  = this.NONE;
                        q.Output = this.NONE;
                    }
                    break;
                case this.OUTPORT1:
                    if (q.sOutput1!=NONE){
                        r = (Gate)gateVector.elementAt(q.sOutput1);
                        a = q.Port3;
                        b = q.sOutput1;
                        q.Port3    = this.NONE;
                        q.sOutput1 = this.NONE;
                    }
                    break;
                case this.OUTPORT2:
                    if (q.sOutput2!=NONE){
                        r = (Gate)gateVector.elementAt(q.sOutput2);
                        a = q.Port4;
                        b = q.sOutput2;
                        q.Port4    = this.NONE;
                        q.sOutput2 = this.NONE;
                    }
                    break;
            } // end switch
            // deleting the connection of the second gate
            if (a != this.NONE){
                switch (a){
                    case this.FIRSTPORT:
                        r.Port1  = this.NONE;
                        r.Input1 = this.NONE;
                        break;
                    case this.SECONDPORT:
                        r.Port2  = this.NONE;
                        r.Input2 = this.NONE;
                        break;
                    case this.OUTPORT:
                        r.Port3  = this.NONE;
                        r.Output = this.NONE;
                        break;
                    case this.OUTPORT1:
                        r.Port3    = this.NONE;
                        r.sOutput1 = this.NONE;
                        break;
                    case this.OUTPORT2:
                        r.Port4    = this.NONE;
                        r.sOutput2 = this.NONE;
                        break;
                } // end switch
            } // end if
         }
         else{ // if type is equal to led
           if (q.Input1!=NONE){
             r = (Gate)gateVector.elementAt(q.Input1);
             a = q.Port1;
             b = q.Input1;
             q.Port1  = this.NONE;
             q.Input1 = this.NONE;
           }
            if (a != this.NONE){
                switch (a){
                    case this.FIRSTPORT:
                        r.Led1  = this.NONE;
                        break;
                    case this.SECONDPORT:
                        r.Led2  = this.NONE;
                        break;
                    case this.OUTPORT:
                    case this.OUTPORT1:
                        r.Led3  = this.NONE;
                        break;
                    case this.OUTPORT2:
                        r.Led4    = this.NONE;
                        break;
                } // end switch
            } // end if

         }
            // writing back the gates to the vector
          gateVector.setElementAt(q, selectedGateIndex);
          if (b != this.NONE)
             gateVector.setElementAt(r, b);
          this.mode = this.NONE;
        } // end if*/

        int np = gateVector.size();
        Gate p; //= (Gate)gateVector.elementAt(0);
        // evaluating the outputs and the inputs of the gates if the current mode is SIMULATION
        if (this.mode == this.SIMULATION){
                for (int i=0; i < np; i++){
                    p = (Gate)gateVector.elementAt(i);
                    if ( (p.type == this.GROUND)||(p.type == this.CLOCK)||
                         (p.type == this.VOLTAGE)||(p.type == this.INPUT)){
                        p.evaluateOutput();
                        gateVector.setElementAt(p,i);
                    }
                } // end for

                for (int i=0; i < np; i++){
                    p = (Gate)gateVector.elementAt(i);
                    if (p.type == this.FLIPFLOP){
                        p.evaluateOutput();
                        gateVector.setElementAt(p,i);
                    }
                } // end for

                for (int i=0; i < np; i++)
                   for (int j=0; j < np; j++){
                    p = (Gate)gateVector.elementAt(j);
                    if ( (p.type != this.GROUND)||(p.type != this.CLOCK)||
                         (p.type != this.VOLTAGE) || (p.type != this.FLIPFLOP)||(p.type != this.INPUT)){
                        p.evaluateOutput();
                        gateVector.setElementAt(p,j);
                    }
                   }


        }

        // drawing the current gates
	    for (int i=0; i < np; i++) {

	        p = (Gate)gateVector.elementAt(i);
            if (this.mode == this.SIMULATION){
                if (p.type == this.LED){
                  switch(p.in1){
                     case Gate.ONE:
                          g.setColor(Color.red);
                          g.fillOval(p.x + DrawCanvas.SIZE/5, p.y + 3*DrawCanvas.SIZE/10, (2*DrawCanvas.SIZE/5), (2*DrawCanvas.SIZE/5));
                          break;
                     case Gate.ZERO:
                          g.setColor(Color.green);
                          g.fillOval(p.x + DrawCanvas.SIZE/5, p.y + 3*DrawCanvas.SIZE/10, (2*DrawCanvas.SIZE/5), (2*DrawCanvas.SIZE/5));
                          break;
                  }// end switch
                  g.setColor(Color.white);
                }//end if
            }// end if

	        if (i == selectedGateIndex){
                g.setColor(Color.yellow);
            }

            p.drawGate(g);

            g.setColor(Color.white);
            Gate r = (Gate)gateVector.elementAt(0);
            if (p.type != this.LED){
	            switch(p.nofInputs){
                    case 0:
                        if ( ((selectedGateIndex == i)&& (selectedPort == this.OUTPORT) )||
                            ((p.Output==selectedGateIndex) && (p.Port3 == selectedPort)))
                            g.setColor(Color.yellow);
                        else
                            g.setColor(Color.white);

            	        if  (p.Output != this.NONE) {
            	            r = (Gate)gateVector.elementAt(p.Output);
            	        if (p.Port3 == this.FIRSTPORT){
            	            if (r.nofInputs == 1){
                	            g.drawLine(p.x+this.SIZE, p.y + (this.SIZE/2), r.x, r.y + (this.SIZE/2));
            	            }
            	            else if (r.nofInputs == 2){
                	            g.drawLine(p.x+this.SIZE, p.y + (this.SIZE/2), r.x, r.y + (3*this.SIZE/10));
            	            }
            	        }
            	        else if (p.Port3 == this.SECONDPORT){
            	            g.drawLine(p.x+this.SIZE, p.y + (this.SIZE/2), r.x, r.y + (7*this.SIZE/10));
            	        }
            	    }
                   break;
	            case 1:
                    if ( ( (selectedGateIndex == i) && (selectedPort == this.FIRSTPORT) )||
                        ((p.Input1==selectedGateIndex) && (p.Port1 == selectedPort)))
                        g.setColor(Color.yellow);
                    else
                        g.setColor(Color.white);

	                if ((p.Input1 != this.NONE) ){
            	        r = (Gate)gateVector.elementAt(p.Input1);
            	        if (p.Port1 == this.OUTPORT){
            	            g.drawLine(p.x, p.y + (this.SIZE/2), r.x+this.SIZE, r.y + (this.SIZE/2));
            	        }
            	        else if (p.Port1 == this.OUTPORT1){
            	            g.drawLine(p.x, p.y + (this.SIZE/2), r.x+this.SIZE, r.y + (3*this.SIZE/10));
            	        }
            	        else if (p.Port1 == this.OUTPORT2){
            	            g.drawLine(p.x, p.y + (this.SIZE/2), r.x+this.SIZE, r.y + (7*this.SIZE/10));
            	        }
            	    }

                    if ( ( (selectedGateIndex == i) &&(selectedPort == this.OUTPORT) )||
                        ((p.Output==selectedGateIndex) && (p.Port3 == selectedPort)))
                        g.setColor(Color.yellow);
                    else
                        g.setColor(Color.white);

            	    if (p.Output != this.NONE){
            	        r = (Gate)gateVector.elementAt(p.Output);
            	        if (p.Port3 == this.FIRSTPORT){
            	            if (r.nofInputs == 1){
                	            g.drawLine(p.x+this.SIZE, p.y + (this.SIZE/2), r.x, r.y + (this.SIZE/2));
            	            }
            	            else if (r.nofInputs == 2){
                	            g.drawLine(p.x+this.SIZE, p.y + (this.SIZE/2), r.x, r.y + (3*this.SIZE/10));
            	            }
            	        }
            	        else if (p.Port3 == this.SECONDPORT){
            	            g.drawLine(p.x+this.SIZE, p.y + (this.SIZE/2), r.x, r.y + (7*this.SIZE/10));
            	        }
            	    }

                    if ( ( (selectedGateIndex == i)&& (selectedPort == this.OUTPORT1) )||
                        ((p.sOutput1 == selectedGateIndex) && (p.Port3 == selectedPort)))
                        g.setColor(Color.yellow);
                    else
                        g.setColor(Color.white);

            	    if (p.sOutput1 != this.NONE){
            	        r = (Gate)gateVector.elementAt(p.sOutput1);
            	        if (p.Port3 == this.FIRSTPORT){
            	            if (r.nofInputs == 1){
                	            g.drawLine(p.x+this.SIZE, p.y + (3*this.SIZE/10), r.x, r.y + (this.SIZE/2));
            	            }
            	            else if (r.nofInputs == 2){
                	            g.drawLine(p.x+this.SIZE, p.y + (3*this.SIZE/10), r.x, r.y + (3*this.SIZE/10));
            	            }
            	        }
            	        else if (p.Port3 == this.SECONDPORT){
            	            g.drawLine(p.x+this.SIZE, p.y + (3*this.SIZE/10), r.x, r.y + (7*this.SIZE/10));
            	        }
            	    }

                    if (((selectedGateIndex == i)&& (selectedPort == this.OUTPORT2) )||
                        ((p.sOutput2 == selectedGateIndex) && (p.Port4 == selectedPort)))
                        g.setColor(Color.yellow);
                    else
                        g.setColor(Color.white);

            	    if (p.sOutput2 != this.NONE){
            	        r = (Gate)gateVector.elementAt(p.sOutput2);
            	        if (p.Port4 == this.FIRSTPORT){
            	            if (r.nofInputs == 1){
                	            g.drawLine(p.x+this.SIZE, p.y + (7*this.SIZE/10), r.x, r.y + (this.SIZE/2));
            	            }
            	            else if (r.nofInputs == 2){
                	            g.drawLine(p.x+this.SIZE, p.y + (7*this.SIZE/10), r.x, r.y + (3*this.SIZE/10));
            	            }
            	        }
            	        else if (p.Port4 == this.SECONDPORT){
            	            g.drawLine(p.x+this.SIZE, p.y + (7*this.SIZE/10), r.x, r.y + (7*this.SIZE/10));
            	        }
            	    }

	                break;
	            case 2:
                    if (((selectedGateIndex == i)&&(selectedPort == this.FIRSTPORT) )||
                        ((p.Input1==selectedGateIndex) && (p.Port1 == selectedPort)))
                        g.setColor(Color.yellow);
                    else
                        g.setColor(Color.white);

	                if (p.Input1 != this.NONE){

            	        r = (Gate)gateVector.elementAt(p.Input1);
            	        if (p.Port1 == this.OUTPORT){
            	            g.drawLine(p.x, p.y + (3*this.SIZE/10), r.x+this.SIZE, r.y + (this.SIZE/2));
            	        }
            	        else if (p.Port1 == this.OUTPORT1){
            	            g.drawLine(p.x, p.y + (3*this.SIZE/10), r.x+this.SIZE, r.y + (3*this.SIZE/10));
            	        }
            	        else if (p.Port1 == this.OUTPORT2){
            	            g.drawLine(p.x, p.y + (3*this.SIZE/10), r.x+this.SIZE, r.y + (7*this.SIZE/10));
            	        }
            	    }

                    if (((selectedGateIndex == i) && (selectedPort == this.SECONDPORT) )||
                        ((p.Input2==selectedGateIndex) && (p.Port2 == selectedPort)))
                        g.setColor(Color.yellow);
                    else
                        g.setColor(Color.white);

	                if (p.Input2 != this.NONE){
            	        r = (Gate)gateVector.elementAt(p.Input2);
            	        if (p.Port2 == this.OUTPORT){
            	            g.drawLine(p.x, p.y + (7*this.SIZE/10), r.x+this.SIZE, r.y + (this.SIZE/2));
            	        }
            	        else if (p.Port2 == this.OUTPORT1){
            	            g.drawLine(p.x, p.y + (7*this.SIZE/10), r.x+this.SIZE, r.y + (3*this.SIZE/10));
            	        }
            	        else if (p.Port2 == this.OUTPORT2){
            	            g.drawLine(p.x, p.y + (7*this.SIZE/10), r.x+this.SIZE, r.y + (7*this.SIZE/10));
            	        }
            	    }

                    if (((selectedGateIndex == i) && (selectedPort == this.OUTPORT) )||
                        ((p.Output==selectedGateIndex) && (p.Port3 == selectedPort)))
                        g.setColor(Color.yellow);
                    else
                        g.setColor(Color.white);

            	    if (p.Output != this.NONE){
            	        r = (Gate)gateVector.elementAt(p.Output);
            	        if (p.Port3 == this.FIRSTPORT){
            	            if (r.nofInputs == 1){
                	            g.drawLine(p.x+this.SIZE, p.y + (this.SIZE/2), r.x, r.y + (this.SIZE/2));
            	            }
            	            else if (r.nofInputs == 2){
                	            g.drawLine(p.x+this.SIZE, p.y + (this.SIZE/2), r.x, r.y + (3*this.SIZE/10));
            	            }
            	        }
            	        else if (p.Port3 == this.SECONDPORT){
            	            g.drawLine(p.x+this.SIZE, p.y + (this.SIZE/2), r.x, r.y + (7*this.SIZE/10));
            	        }
            	    }
	                break;
	        }
          }
          else{
            if (i==selectedGateIndex)
               g.setColor(Color.yellow);
            else
               g.setColor(Color.white);

            if ((p.Input1 != this.NONE) ){
            	        r = (Gate)gateVector.elementAt(p.Input1);
            	        if (p.Port1 == this.OUTPORT){
            	            g.drawLine(p.x, p.y + (this.SIZE/2), r.x+this.SIZE, r.y + (this.SIZE/2));
            	        }
            	        else if (p.Port1 == this.OUTPORT1){
            	            g.drawLine(p.x, p.y + (this.SIZE/2), r.x+this.SIZE, r.y + (3*this.SIZE/10));
            	        }
            	        else if (p.Port1 == this.OUTPORT2){
            	            g.drawLine(p.x, p.y + (this.SIZE/2), r.x+this.SIZE, r.y + (7*this.SIZE/10));
            	        }
            	        else if (p.Port1 == this.FIRSTPORT){
            	            if (r.nofInputs == 2)
            	                g.drawLine(p.x, p.y + (this.SIZE/2), r.x, r.y + (3*this.SIZE/10));
            	            else
            	                g.drawLine(p.x, p.y + (this.SIZE/2), r.x, r.y + (this.SIZE/2));
            	        }
            	        else if (p.Port1 == this.SECONDPORT){
            	            g.drawLine(p.x, p.y + (this.SIZE/2), r.x, r.y + (7*this.SIZE/10));
            	        }
            	    }
          }
          g.setColor(Color.white);
	    }// end for

	    // connecting the ports of two gates
	    if (this.drawMode == this.CONNECT){
            g.setColor(Color.yellow);
	        p = (Gate)gateVector.elementAt(fgtc);
	        switch(p.nofInputs){
	            case 0:
	                if (selectedPort1 == OUTPORT)
	                   g.drawLine(p.x + (this.SIZE), p.y + (this.SIZE/2), this.x, this.y);
	                break;
	            case 1:
	                if (selectedPort1 == FIRSTPORT)
	                   g.drawLine(p.x, p.y + (this.SIZE/2), this.x, this.y);
	                else if (selectedPort1 == OUTPORT)
	                   g.drawLine(p.x + this.SIZE, p.y + (this.SIZE/2), this.x, this.y);
	                else if (selectedPort1 == OUTPORT1)
	                   g.drawLine(p.x + this.SIZE, p.y + (3*this.SIZE/10), this.x, this.y);
	                else if (selectedPort1 == OUTPORT2)
	                   g.drawLine(p.x + this.SIZE, p.y + (7*this.SIZE/10), this.x, this.y);
	                break;
	            case 2:
	                if (selectedPort1 == FIRSTPORT)
	                   g.drawLine(p.x, p.y + (3*this.SIZE/10), this.x, this.y);
	                else if (selectedPort1 == SECONDPORT)
	                   g.drawLine(p.x, p.y + (7*this.SIZE/10), this.x, this.y);
	                else if (selectedPort1 == OUTPORT)
	                   g.drawLine(p.x + this.SIZE, p.y + (this.SIZE/2), this.x, this.y);
	                break;
	        }
            g.setColor(Color.white);
	    }

	    // clearing the gates, in fact everything
	    if (this.mode == this.CLEAR){
	        g.setColor(col.black);
            g.fillRect(0,0, my_size.width, my_size.height);
            g.setColor(col.white);
            gateVector.removeAllElements();
            this.mode = this.NONE;
            this.selectedGateIndex = this.NONE;
            this.x = 0;
            this.y = 0;
	    }

        g.setColor(Color.yellow);
        currentGate = new Gate(this.x, this.y, this.mode);
        currentGate.drawGate(g);

  Date ourDate = new Date();
  long remainder = ourDate.getTime();
  long aa        = remainder;
  if (this.mode == this.SIMULATION){
        while (aa-remainder<Gate.frequency/2){
            Date ourDate1 = new Date();
            aa = ourDate1.getTime();
        }
        this.simulate();
  }

    }//end of paint() method
}

//*******************************************************************************************

class Our_Buttons extends Panel{

    public static DrawCanvas target;

//------------------------------------------------------------------------------------
    public Our_Buttons(DrawCanvas target) {
	    this.target = target;
	    //{{INIT_CONTROLS
	    setLayout(null);
	    resize(insets().left + insets().right + 166, insets().top + insets().bottom + 659);
	    button1=new Button("ABOUT");
	    button1.setFont(new Font("TimesRoman",Font.BOLD|Font.ITALIC,14));
	    add(button1);
	    button1.reshape(insets().left + 7,insets().top + 8,154,22);
	    and_button=new Button("AND Gate");
	    and_button.setFont(new Font("TimesRoman",Font.BOLD,12));
	    add(and_button);
	    and_button.reshape(insets().left + 9,insets().top + 208,152,21);
	    or_button=new Button("OR Gate");
	    or_button.setFont(new Font("TimesRoman",Font.BOLD,12));
	    add(or_button);
	    or_button.reshape(insets().left + 9,insets().top + 234,152,19);
	    not_button=new Button("NOT Gate");
	    not_button.setFont(new Font("TimesRoman",Font.BOLD,12));
	    add(not_button);
	    not_button.reshape(insets().left + 9,insets().top + 289,152,20);
	    flip_flop_button=new Button("FLIP-FLOP");
	    flip_flop_button.setFont(new Font("TimesRoman",Font.BOLD,12));
	    add(flip_flop_button);
	    flip_flop_button.reshape(insets().left + 9,insets().top + 180,152,21);
	    zero_input_button=new Button("GROUND");
	    zero_input_button.setFont(new Font("TimesRoman",Font.BOLD,12));
	    add(zero_input_button);
	    zero_input_button.reshape(insets().left + 9,insets().top + 99,152,19);
	    one_input_button=new Button("HIGH-VOLTAGE");
	    one_input_button.setFont(new Font("TimesRoman",Font.BOLD,12));
	    add(one_input_button);
	    one_input_button.reshape(insets().left + 9,insets().top + 71,152,21);
	    clear_button=new Button("CLEAR ALL");
	    clear_button.setFont(new Font("TimesRoman",Font.BOLD,12));
	    add(clear_button);
	    clear_button.reshape(insets().left + 9,insets().top + 480,154,23);
	    delete_button=new Button("DELETE GATE");
	    delete_button.setFont(new Font("TimesRoman",Font.BOLD,12));
	    add(delete_button);
	    delete_button.reshape(insets().left + 9,insets().top + 420,154,23);
	    exit_button=new Button("EXIT");
	    exit_button.setFont(new Font("TimesRoman",Font.BOLD,12));
	    add(exit_button);
	    exit_button.reshape(insets().left + 7,insets().top + 608,154,37);
	    led_button=new Button("LED");
	    led_button.setFont(new Font("TimesRoman",Font.BOLD,12));
	    add(led_button);
	    led_button.reshape(insets().left + 9,insets().top + 341,152,23);
	    splitter_button=new Button("SPLITTER");
	    splitter_button.setFont(new Font("TimesRoman",Font.BOLD,12));
	    add(splitter_button);
	    splitter_button.reshape(insets().left + 9,insets().top + 315,152,23);
	    clock_button=new Button("CLOCK");
	    clock_button.setFont(new Font("TimesRoman",Font.BOLD,12));
	    add(clock_button);
	    clock_button.reshape(insets().left + 9,insets().top + 152,152,21);
	    label1=new Label("Available Gates", Label.CENTER);
	    label1.setFont(new Font("TimesRoman",Font.BOLD,14));
	    add(label1);
	    label1.reshape(insets().left + 9,insets().top + 45,152,21);
	    label2=new Label("Gate Operations", Label.CENTER);
	    label2.setFont(new Font("TimesRoman",Font.BOLD,14));
	    add(label2);
	    label2.reshape(insets().left + 9,insets().top + 398,154,15);
	    dconnect_button=new Button("DELETE CONNECTION");
	    dconnect_button.setFont(new Font("TimesRoman",Font.BOLD,12));
	    add(dconnect_button);
	    dconnect_button.reshape(insets().left + 9,insets().top + 450,154,23);
	    simulate_button=new Button("SIMULATION");
	    simulate_button.setFont(new Font("Dialog",Font.BOLD|Font.ITALIC,14));
	    add(simulate_button);
	    simulate_button.reshape(insets().left + 9,insets().top + 525,154,38);
	    xor_button=new Button("XOR Gate");
	    xor_button.setFont(new Font("TimesRoman",Font.BOLD,12));
	    add(xor_button);
	    xor_button.reshape(insets().left + 9,insets().top + 261,152,22);
	    input_button=new Button("1 BIT Input");
	    input_button.setFont(new Font("TimesRoman",Font.BOLD,12));
	    add(input_button);
	    input_button.reshape(insets().left + 9,insets().top + 126,152,20);
	    //}}
    }

//------------------------------------------------------------------------------------
    public void paint(Graphics g) {

	    Rectangle r = bounds();
	    g.setColor(Color.gray);
    }

//------------------------------------------------------------------------------------
    public boolean action(Event e, Object arg) {
	    String choice = (String)arg;

	    if (e.target instanceof Button) {
	        if (e.target == and_button){
	            target.setDrawMode(target.AND);
            }
            else if (e.target == or_button){
                target.setDrawMode(target.OR);
            }
            else if (e.target == not_button){
                target.setDrawMode(target.NOT);
            }
            else if (e.target == clear_button){
                target.setDrawMode(target.CLEAR);
            }
            else if (e.target == delete_button){
                target.setDrawMode(target.DELETE);
            }
            else if (e.target == zero_input_button){
                target.setDrawMode(target.GROUND);
            }
            else if (e.target == one_input_button){
                target.setDrawMode(target.VOLTAGE);
            }
            else if (e.target == flip_flop_button){
                target.setDrawMode(target.FLIPFLOP);
            }
            else if (e.target == splitter_button){
                target.setDrawMode(target.SPLITTER);
            }
            else if (e.target == led_button){
                target.setDrawMode(target.LED);
            }
            else if (e.target == clock_button){
                target.setDrawMode(target.CLOCK);
            }
            else if (e.target == exit_button){
                if (target.mode != target.SIMULATION){
                        DrawTest.themainMenu.hide();
                }
            }
            else if (e.target == xor_button){
                target.setDrawMode(target.XOR);
            }
            else if (e.target == input_button){
                target.setDrawMode(target.INPUT);
            }
            else if (e.target == dconnect_button){
                target.setDrawMode(target.DELETECONNECT);
            }
            else if (e.target == simulate_button){
                if (DrawCanvas.mode != target.SIMULATION){
                    target.setDrawMode(target.SIMULATION);
                simulate_button.setLabel("STOP SIMULATION");
                and_button.disable();
                or_button.disable();
                not_button.disable();
                flip_flop_button.disable();
                zero_input_button.disable();
                one_input_button.disable();
                clear_button.disable();
                delete_button.disable();
                exit_button.disable();
                led_button.disable();
                splitter_button.disable();
                clock_button.disable();
                dconnect_button.disable();
                xor_button.disable();
                input_button.disable();
                }
                else{
                    target.setDrawMode(target.NONE);
                    simulate_button.setLabel("SIMULATION");
                    and_button.enable();
                    or_button.enable();
                    not_button.enable();
                    flip_flop_button.enable();
                    zero_input_button.enable();
                    one_input_button.enable();
                    clear_button.enable();
                    delete_button.enable();
                    exit_button.enable();
                    led_button.enable();
                    splitter_button.enable();
                    clock_button.enable();
                    dconnect_button.enable();
                    xor_button.enable();
                    input_button.enable();
                }
            }
	    }
        target.repaint();
	    return true;
    }

    //{{DECLARE_CONTROLS
    Button button1;
    Button and_button;
    Button or_button;
    Button not_button;
    Button flip_flop_button;
    Button zero_input_button;
    Button one_input_button;
    Button clear_button;
    Button delete_button;
    Button exit_button;
    Button led_button;
    Button splitter_button;
    Button clock_button;
    Label label1;
    Label label2;
    Button dconnect_button;
    Button simulate_button;
    Button xor_button;
    Button input_button;
    //}}

//------------------------------------------------------------------------------------
    public void clickedButton1() {
        // to do: put event handler code here.
        DrawTest.about = new About();
        DrawTest.about.show();
    }

//------------------------------------------------------------------------------------
    public boolean handleEvent(Event event) {

        if (event.id == Event.ACTION_EVENT && event.target == button1) {
            clickedButton1();
            return true;
        }

        return super.handleEvent(event);
    }
}

//*******************************************************************************************

class Gate{
    public static final int ZERO       = 0;
    public static final int ONE        = 1;
    public static final int UNKNOWN    = 2;
    public static int frequency = 1000;
    int x;
    int y;
    int type;
    int nofInputs, nofOutputs;
    int Input1, Input2, Output, sOutput1, sOutput2;
    int Port1, Port2, Port3, Port4;
    int Led1, Led2, Led3, Led4;
    int in1, in2, out1, out2;
    int changed;

//------------------------------------------------------------------------------------
    Gate(int x, int y, int type){
        this.x = x;
        this.y = y;
        this.type = type;
        this.Input1   = DrawCanvas.NONE;
        this.Input2   = DrawCanvas.NONE;
        this.Output   = DrawCanvas.NONE;
        this.sOutput1 = DrawCanvas.NONE;
        this.sOutput2 = DrawCanvas.NONE;
        this.Port1    = DrawCanvas.NONE;
        this.Port2    = DrawCanvas.NONE;
        this.Port3    = DrawCanvas.NONE;
        this.Port4    = DrawCanvas.NONE;
        this.Led1     = DrawCanvas.NONE;
        this.Led2     = DrawCanvas.NONE;
        this.Led3     = DrawCanvas.NONE;
        this.Led4     = DrawCanvas.NONE;
        this.in1      = this.UNKNOWN;
        this.in2      = this.UNKNOWN;
        this.out1     = this.UNKNOWN;
        this.out2     = this.UNKNOWN;
        this.changed  = 0;
        switch (type){
            case DrawCanvas.AND:
            case DrawCanvas.OR:
            case DrawCanvas.XOR:
                nofInputs  = 2;
                nofOutputs = 1;
                break;
            case DrawCanvas.FLIPFLOP:
                nofInputs  = 2;
                nofOutputs = 1;
                this.out1  = 0;
                break;
            case DrawCanvas.LED:
            case DrawCanvas.NOT:
                nofInputs  = 1;
                nofOutputs = 1;
                break;
            case DrawCanvas.SPLITTER:
                nofInputs  = 1;
                nofOutputs = 2;
                break;
            case DrawCanvas.GROUND:
            case DrawCanvas.VOLTAGE:
            case DrawCanvas.CLOCK:
                nofInputs  = 0;
                nofOutputs = 1;
                break;
            case DrawCanvas.INPUT:
                nofInputs  = 0;
                nofOutputs = 1;
                this.changed = 0;
                break;
        }// end of switch
    }// end of constructor

//------------------------------------------------------------------------------------
    void drawGate(Graphics g){
        switch (this.type){
            case DrawCanvas.AND:
                    g.drawLine( x + (DrawCanvas.SIZE/5), y + (DrawCanvas.SIZE/5),
                                x + (DrawCanvas.SIZE/5), y + (4*DrawCanvas.SIZE/5));
                    g.drawArc(x-(2*DrawCanvas.SIZE/5), y + (DrawCanvas.SIZE/5),(6*DrawCanvas.SIZE/5)
                             ,(3*DrawCanvas.SIZE/5), 270, 180);
                    g.drawOval(x, y+(DrawCanvas.SIZE/5),(DrawCanvas.SIZE/5),(DrawCanvas.SIZE/5));
                    g.drawOval(x, y+(3*DrawCanvas.SIZE/5),(DrawCanvas.SIZE/5),(DrawCanvas.SIZE/5));
                    g.drawOval(x + (4*DrawCanvas.SIZE)/5 , y+(2*DrawCanvas.SIZE/5),
                              (DrawCanvas.SIZE/5),(DrawCanvas.SIZE/5));
                break;
            case DrawCanvas.OR:
                    g.drawArc(x-(2*DrawCanvas.SIZE/5), y+(DrawCanvas.SIZE/5), (6*DrawCanvas.SIZE/5), (3*DrawCanvas.SIZE/5), 270, 180);
                    g.drawArc(x, y+(DrawCanvas.SIZE/5), (3*DrawCanvas.SIZE/10), (3*DrawCanvas.SIZE/5), 270, 180);
                    g.drawOval(x, y+(DrawCanvas.SIZE/5), (DrawCanvas.SIZE/5), (DrawCanvas.SIZE/5));
                    g.drawOval(x, y+(3*DrawCanvas.SIZE/5), (DrawCanvas.SIZE/5), (DrawCanvas.SIZE/5));
                    g.drawOval(x+(4*DrawCanvas.SIZE/5), y+(2*DrawCanvas.SIZE/5), (DrawCanvas.SIZE/5), (DrawCanvas.SIZE/5));
                break;
            case DrawCanvas.XOR:
                    g.drawArc(x-(2*DrawCanvas.SIZE/5), y+(DrawCanvas.SIZE/5), (6*DrawCanvas.SIZE/5), (3*DrawCanvas.SIZE/5), 270, 180);
                    g.drawArc(x, y+(DrawCanvas.SIZE/5), (3*DrawCanvas.SIZE/10), (3*DrawCanvas.SIZE/5), 270, 180);
                    g.drawArc(x+DrawCanvas.SIZE/5, y+(DrawCanvas.SIZE/5), (3*DrawCanvas.SIZE/10), (3*DrawCanvas.SIZE/5), 270, 180);
                    g.drawOval(x, y+(DrawCanvas.SIZE/5), (DrawCanvas.SIZE/5), (DrawCanvas.SIZE/5));
                    g.drawOval(x, y+(3*DrawCanvas.SIZE/5), (DrawCanvas.SIZE/5), (DrawCanvas.SIZE/5));
                    g.drawOval(x+(4*DrawCanvas.SIZE/5), y+(2*DrawCanvas.SIZE/5), (DrawCanvas.SIZE/5), (DrawCanvas.SIZE/5));
                break;
            case DrawCanvas.NOT:
                    g.drawLine(x+(DrawCanvas.SIZE/5), y+(DrawCanvas.SIZE/5), x+(DrawCanvas.SIZE/5), y+(4*DrawCanvas.SIZE/5));
                    g.drawLine(x+(DrawCanvas.SIZE/5), y+(DrawCanvas.SIZE/5), x+(4*DrawCanvas.SIZE/5), y+(DrawCanvas.SIZE/2));
                    g.drawLine(x+(DrawCanvas.SIZE/5), y+(4*DrawCanvas.SIZE/5), x+(4*DrawCanvas.SIZE/5), y+(DrawCanvas.SIZE/2));
                    g.drawOval(x, y+(2*DrawCanvas.SIZE/5), (DrawCanvas.SIZE/5), (DrawCanvas.SIZE/5));
                    g.drawOval(x+DrawCanvas.SIZE-(DrawCanvas.SIZE/5), y+(2*DrawCanvas.SIZE/5), (DrawCanvas.SIZE/5), (DrawCanvas.SIZE/5));
                break;
            case DrawCanvas.LED:
                    g.drawOval(x, y+(2*DrawCanvas.SIZE/5), (DrawCanvas.SIZE/5), (DrawCanvas.SIZE/5));
                    g.drawOval(x + DrawCanvas.SIZE/5, y + 3*DrawCanvas.SIZE/10, (2*DrawCanvas.SIZE/5), (2*DrawCanvas.SIZE/5));
                break;
            case DrawCanvas.FLIPFLOP:
                    g.drawOval(x, y + (DrawCanvas.SIZE/5), (DrawCanvas.SIZE/5), (DrawCanvas.SIZE/5));
                    g.drawOval(x, y + (3*DrawCanvas.SIZE/5), (DrawCanvas.SIZE/5), (DrawCanvas.SIZE/5));
                    g.drawOval(x + (4*DrawCanvas.SIZE/5) , y + (2*DrawCanvas.SIZE/5), (DrawCanvas.SIZE/5),(DrawCanvas.SIZE/5));
                    g.drawRect(x + (DrawCanvas.SIZE/5), y , (3*DrawCanvas.SIZE/5), DrawCanvas.SIZE);
                    g.drawLine(x + (DrawCanvas.SIZE/5), y + (3*DrawCanvas.SIZE/5), x + (2*DrawCanvas.SIZE/5), y + (7*DrawCanvas.SIZE/10));
                    g.drawLine(x + (DrawCanvas.SIZE/5), y + (4*DrawCanvas.SIZE/5), x + (2*DrawCanvas.SIZE/5), y + (7*DrawCanvas.SIZE/10));
                    g.drawString("F", x + (2*DrawCanvas.SIZE/5)+2, y + (2*DrawCanvas.SIZE/5));
                    g.drawString("F", x + (2*DrawCanvas.SIZE/5)+2, y + (4*DrawCanvas.SIZE/5)+2);
                break;
            case DrawCanvas.GROUND:
                    g.drawLine(x+(DrawCanvas.SIZE/2), y+(DrawCanvas.SIZE/2), x+(4*DrawCanvas.SIZE/5), y+(DrawCanvas.SIZE/2));
                    g.drawLine(x+(DrawCanvas.SIZE/2), y+(DrawCanvas.SIZE/2), x+(DrawCanvas.SIZE/2), y+(3*DrawCanvas.SIZE/5));
                    g.drawLine(x+(DrawCanvas.SIZE/5), y+(3*DrawCanvas.SIZE/5), x+(4*DrawCanvas.SIZE/5), y+(3*DrawCanvas.SIZE/5));
                    g.drawLine(x+(3*DrawCanvas.SIZE/10), y+(7*DrawCanvas.SIZE/10), x+(7*DrawCanvas.SIZE/10), y+(7*DrawCanvas.SIZE/10));
                    g.drawLine(x+(4*DrawCanvas.SIZE/10), y+(8*DrawCanvas.SIZE/10), x+(6*DrawCanvas.SIZE/10), y+(8*DrawCanvas.SIZE/10));
                    g.drawOval(x+DrawCanvas.SIZE-(DrawCanvas.SIZE/5), y+(2*DrawCanvas.SIZE/5), (DrawCanvas.SIZE/5), (DrawCanvas.SIZE/5));
                    break;
            case DrawCanvas.VOLTAGE:
                    g.drawLine(x+(DrawCanvas.SIZE/5), y+(DrawCanvas.SIZE/2), x+(4*DrawCanvas.SIZE/5), y+(DrawCanvas.SIZE/2));
                    g.drawLine(x+(DrawCanvas.SIZE/2), y+(DrawCanvas.SIZE/2), x+(DrawCanvas.SIZE/2), y+(4*DrawCanvas.SIZE/5));
                    g.drawOval(x+DrawCanvas.SIZE-(DrawCanvas.SIZE/5), y+(2*DrawCanvas.SIZE/5), (DrawCanvas.SIZE/5), (DrawCanvas.SIZE/5));
                    break;
            case DrawCanvas.SPLITTER:
                    g.drawLine(x+(DrawCanvas.SIZE/5), y+(DrawCanvas.SIZE/2), x+(DrawCanvas.SIZE/2), y+(DrawCanvas.SIZE/2));
                    g.drawLine(x+(DrawCanvas.SIZE/2), y+(DrawCanvas.SIZE/2), x+(4*DrawCanvas.SIZE/5), y+(3*DrawCanvas.SIZE/10));
                    g.drawLine(x+(DrawCanvas.SIZE/2), y+(DrawCanvas.SIZE/2), x+(4*DrawCanvas.SIZE/5), y+(7*DrawCanvas.SIZE/10));
                    g.drawOval(x, y+(2*DrawCanvas.SIZE/5), (DrawCanvas.SIZE/5), (DrawCanvas.SIZE/5));
                    g.drawOval(x+DrawCanvas.SIZE-(DrawCanvas.SIZE/5), y+(DrawCanvas.SIZE/5), (DrawCanvas.SIZE/5), (DrawCanvas.SIZE/5));
                    g.drawOval(x+DrawCanvas.SIZE-(DrawCanvas.SIZE/5), y+(3*DrawCanvas.SIZE/5), (DrawCanvas.SIZE/5), (DrawCanvas.SIZE/5));
                    break;
            case DrawCanvas.CLOCK:
                    g.drawRect(x+(DrawCanvas.SIZE/5), y, (3*DrawCanvas.SIZE/5), (DrawCanvas.SIZE));
                    g.drawOval(x+4*DrawCanvas.SIZE/5, y+(2*DrawCanvas.SIZE/5), (DrawCanvas.SIZE/5), (DrawCanvas.SIZE/5));
                    g.drawString("C", x + (2*DrawCanvas.SIZE/5), y + (DrawCanvas.SIZE/5)+4);
                    g.drawString("L", x + (2*DrawCanvas.SIZE/5), y + (3*DrawCanvas.SIZE/5));
                    g.drawString("K", x + (2*DrawCanvas.SIZE/5), y + (5*DrawCanvas.SIZE/5)-3);
                    break;
            case DrawCanvas.INPUT:
                    g.drawRect(x+(DrawCanvas.SIZE/5), y + (DrawCanvas.SIZE/5), (3*DrawCanvas.SIZE/5), (3*DrawCanvas.SIZE/5));
                    g.drawOval(x+4*DrawCanvas.SIZE/5, y+(2*DrawCanvas.SIZE/5), (DrawCanvas.SIZE/5), (DrawCanvas.SIZE/5));
                    Integer i = new Integer(this.changed);
                    g.drawString(i.toString(), x + (2*DrawCanvas.SIZE/5), y + (3*DrawCanvas.SIZE/5)+2);
            break;
        }
    }

//------------------------------------------------------------------------------------
    void evaluateOutput(){

    Gate r = (Gate)DrawCanvas.gateVector.elementAt(0);
    switch (this.type){
            case DrawCanvas.AND:
                if (this.Input1 != DrawCanvas.NONE){
                    r = (Gate)DrawCanvas.gateVector.elementAt(this.Input1);
                    switch(this.Port1){
                        case DrawCanvas.FIRSTPORT:
                            this.in1 = r.in1;
                            break;
                        case DrawCanvas.SECONDPORT:
                            this.in1 = r.in2;
                            break;
                        case DrawCanvas.OUTPORT:
                            this.in1 = r.out1;
                            break;
                        case DrawCanvas.OUTPORT1:
                            this.in1 = r.out1;
                            break;
                        case DrawCanvas.OUTPORT2:
                            this.in1 = r.out2;
                            break;
                    }
                }
                else
                  this.in1 = this.UNKNOWN;

                if (this.Input2 != DrawCanvas.NONE){
                    r = (Gate)DrawCanvas.gateVector.elementAt(this.Input2);
                    switch(this.Port1){
                        case DrawCanvas.FIRSTPORT:
                            this.in2 = r.in1;
                            break;
                        case DrawCanvas.SECONDPORT:
                            this.in2 = r.in2;
                            break;
                        case DrawCanvas.OUTPORT:
                            this.in2 = r.out1;
                            break;
                        case DrawCanvas.OUTPORT1:
                            this.in2 = r.out1;
                            break;
                        case DrawCanvas.OUTPORT2:
                            this.in2 = r.out2;
                            break;
                    }
                }
                else
                  this.in2 = this.UNKNOWN;

                if ((this.in1 == this.ZERO) || (this.in2 == this.ZERO))
                    this.out1 = this.ZERO;
                else if ((this.in1 == this.ONE) && (this.in2 == this.ONE))
                    this.out1 = this.ONE;
                else
                    this.out1 = this.UNKNOWN;

                break;

            case DrawCanvas.OR:
                if (this.Input1 != DrawCanvas.NONE){
                    r = (Gate)DrawCanvas.gateVector.elementAt(this.Input1);
                    switch(this.Port1){
                        case DrawCanvas.FIRSTPORT:
                            this.in1 = r.in1;
                            break;
                        case DrawCanvas.SECONDPORT:
                            this.in1 = r.in2;
                            break;
                        case DrawCanvas.OUTPORT:
                            this.in1 = r.out1;
                            break;
                        case DrawCanvas.OUTPORT1:
                            this.in1 = r.out1;
                            break;
                        case DrawCanvas.OUTPORT2:
                            this.in1 = r.out2;
                            break;
                    }
                }
                else
                  this.in1 = this.UNKNOWN;

                if (this.Input2 != DrawCanvas.NONE){
                    r = (Gate)DrawCanvas.gateVector.elementAt(this.Input2);
                    switch(this.Port1){
                        case DrawCanvas.FIRSTPORT:
                            this.in2 = r.in1;
                            break;
                        case DrawCanvas.SECONDPORT:
                            this.in2 = r.in2;
                            break;
                        case DrawCanvas.OUTPORT:
                            this.in2 = r.out1;
                            break;
                        case DrawCanvas.OUTPORT1:
                            this.in2 = r.out1;
                            break;
                        case DrawCanvas.OUTPORT2:
                            this.in2 = r.out2;
                            break;
                    }
                }
                else
                  this.in2 = this.UNKNOWN;

                if ((this.in1 == this.ONE) || (this.in2 == this.ONE))
                    this.out1 = this.ONE;
                else if ((this.in1 == this.ZERO) && (this.in2 == this.ZERO))
                    this.out1 = this.ZERO;
                else
                    this.out1 = this.UNKNOWN;

                break;

            case DrawCanvas.XOR:
                if (this.Input1 != DrawCanvas.NONE){
                    r = (Gate)DrawCanvas.gateVector.elementAt(this.Input1);
                    switch(this.Port1){
                        case DrawCanvas.FIRSTPORT:
                            this.in1 = r.in1;
                            break;
                        case DrawCanvas.SECONDPORT:
                            this.in1 = r.in2;
                            break;
                        case DrawCanvas.OUTPORT:
                            this.in1 = r.out1;
                            break;
                        case DrawCanvas.OUTPORT1:
                            this.in1 = r.out1;
                            break;
                        case DrawCanvas.OUTPORT2:
                            this.in1 = r.out2;
                            break;
                    }
                }
                else
                  this.in1 = this.UNKNOWN;

                if (this.Input2 != DrawCanvas.NONE){
                    r = (Gate)DrawCanvas.gateVector.elementAt(this.Input2);
                    switch(this.Port1){
                        case DrawCanvas.FIRSTPORT:
                            this.in2 = r.in1;
                            break;
                        case DrawCanvas.SECONDPORT:
                            this.in2 = r.in2;
                            break;
                        case DrawCanvas.OUTPORT:
                            this.in2 = r.out1;
                            break;
                        case DrawCanvas.OUTPORT1:
                            this.in2 = r.out1;
                            break;
                        case DrawCanvas.OUTPORT2:
                            this.in2 = r.out2;
                            break;
                    }
                }
                else
                  this.in2 = this.UNKNOWN;

                if ((this.in1 == this.in2) && (this.in2 != this.UNKNOWN) && (this.in2 != this.UNKNOWN))
                    this.out1 = this.ZERO;
                else if ((this.in1 != this.in2) && (this.in2 != this.UNKNOWN) && (this.in2 != this.UNKNOWN))
                    this.out1 = this.ONE;
                else
                    this.out1 = this.UNKNOWN;

                break;

            case DrawCanvas.FLIPFLOP:
                if ((this.Input1 != DrawCanvas.NONE)){
                    r = (Gate)DrawCanvas.gateVector.elementAt(this.Input1);
                    switch(this.Port1){
                        case DrawCanvas.FIRSTPORT:
                            this.in1 = r.in1;
                            break;
                        case DrawCanvas.SECONDPORT:
                            this.in1 = r.in2;
                            break;
                        case DrawCanvas.OUTPORT:
                            this.in1 = r.out1;
                            break;
                        case DrawCanvas.OUTPORT1:
                            this.in1 = r.out1;
                            break;
                        case DrawCanvas.OUTPORT2:
                            this.in1 = r.out2;
                            break;
                    }
                }
                else
                  this.in1 = this.UNKNOWN;

                if (this.Input2 != DrawCanvas.NONE){
                    r = (Gate)DrawCanvas.gateVector.elementAt(this.Input2);
                    switch(this.Port1){
                        case DrawCanvas.FIRSTPORT:
                            this.in2 = r.in1;
                            break;
                        case DrawCanvas.SECONDPORT:
                            this.in2 = r.in2;
                            break;
                        case DrawCanvas.OUTPORT:
                            this.in2 = r.out1;
                            break;
                        case DrawCanvas.OUTPORT1:
                            this.in2 = r.out1;
                            break;
                        case DrawCanvas.OUTPORT2:
                            this.in2 = r.out2;
                            break;
                    }
                }
                else
                  this.in2 = this.UNKNOWN;

                switch (this.in2){
                    case this.ONE:
                        this.changed = this.ZERO;
                        break;
                    case this.ZERO:
                        if (this.changed == 0){
                            if (this.in1 == this.UNKNOWN){
                                this.out1 = this.ZERO;
                                this.changed  = 1;
                                }
                             else{
                                this.out1 = this.in1;
                                this.changed  = 1;
                             }
                        }
                        break;
                    case this.UNKNOWN:
                        break;
                }
                break;

            case DrawCanvas.LED:
                if (this.Input1 != DrawCanvas.NONE){
                    r = (Gate)DrawCanvas.gateVector.elementAt(this.Input1);
                    switch(this.Port1){
                        case DrawCanvas.FIRSTPORT:
                            this.in1 = r.in1;
                            break;
                        case DrawCanvas.SECONDPORT:
                            this.in1 = r.in2;
                            break;
                        case DrawCanvas.OUTPORT:
                            this.in1 = r.out1;
                            break;
                        case DrawCanvas.OUTPORT1:
                            this.in1 = r.out1;
                            break;
                        case DrawCanvas.OUTPORT2:
                            this.in1 = r.out2;
                            break;
                    }
                }
                else
                  this.in1 = this.UNKNOWN;
                break;

            case DrawCanvas.NOT:
                if (this.Input1 != DrawCanvas.NONE){
                    r = (Gate)DrawCanvas.gateVector.elementAt(this.Input1);
                    switch(this.Port1){
                        case DrawCanvas.FIRSTPORT:
                            this.in1 = r.in1;
                            break;
                        case DrawCanvas.SECONDPORT:
                            this.in1 = r.in2;
                            break;
                        case DrawCanvas.OUTPORT:
                            this.in1 = r.out1;
                            break;
                        case DrawCanvas.OUTPORT1:
                            this.in1 = r.out1;
                            break;
                        case DrawCanvas.OUTPORT2:
                            this.in1 = r.out2;
                            break;
                    }
                }
                else
                  this.in1 = this.UNKNOWN;

                if (this.in1 == this.ONE)
                    this.out1 = this.ZERO;
                else if (this.in1 == this.ZERO)
                    this.out1 = this.ONE;
                else
                    this.out1 = this.UNKNOWN;

                break;

            case DrawCanvas.SPLITTER:
                if (this.Input1 != DrawCanvas.NONE){
                    r = (Gate)DrawCanvas.gateVector.elementAt(this.Input1);
                    switch(this.Port1){
                        case DrawCanvas.FIRSTPORT:
                            this.in1 = r.in1;
                            break;
                        case DrawCanvas.SECONDPORT:
                            this.in1 = r.in2;
                            break;
                        case DrawCanvas.OUTPORT:
                            this.in1 = r.out1;
                            break;
                        case DrawCanvas.OUTPORT1:
                            this.in1 = r.out1;
                            break;
                        case DrawCanvas.OUTPORT2:
                            this.in1 = r.out2;
                            break;
                    }
                }
                else
                  this.in1 = this.UNKNOWN;

                this.out1 = this.in1;
                this.out2 = this.in1;
                break;

            case DrawCanvas.GROUND:
                this.out1 = this.ZERO;
                break;

            case DrawCanvas.VOLTAGE:
                this.out1 = this.ONE;
                break;

            case DrawCanvas.INPUT:
                if (this.changed == this.ZERO)
                    this.out1 = this.ZERO;
                else if (this.changed == this.ONE)
                    this.out1 = this.ONE;
                break;

            case DrawCanvas.CLOCK:
                Date ourDate = new Date();
                if ((ourDate.getTime()%((long)this.frequency))<((long)this.frequency/2))
                    this.out1 = 0;
                else
                    this.out1 = 1;
                break;
        }// end of switch
    }

//------------------------------------------------------------------------------------
    boolean isCircle(int a, int b){

        Gate p = (Gate)DrawCanvas.gateVector.elementAt(a);
        Gate r = (Gate)DrawCanvas.gateVector.elementAt(0);
        switch (p.nofOutputs){
            case 0:
                return false;
            case 1:
                if (p.Output == DrawCanvas.NONE)
                    return false;
                else{
                    if (p.Output == b)
                        return true;
                    else{
                       r = (Gate)DrawCanvas.gateVector.elementAt(p.Output);
                       if (r.type != DrawCanvas.FLIPFLOP)
                            return(isCircle(p.Output, b));
                       return false;
                    }
                }

            case 2:
                if ((p.sOutput1 == DrawCanvas.NONE) && (p.sOutput2 == DrawCanvas.NONE))
                    return false;

                if ((p.sOutput1 != DrawCanvas.NONE) && (p.sOutput2 == DrawCanvas.NONE))
                    if (p.sOutput1 == b)
                        return true;
                    else{
                       r = (Gate)DrawCanvas.gateVector.elementAt(p.sOutput1);
                       if (r.type != DrawCanvas.FLIPFLOP)
                            return(isCircle(p.sOutput1, b));
                       return false;
                    }

                if ((p.sOutput2 != DrawCanvas.NONE) && (p.sOutput1 == DrawCanvas.NONE))
                    if (p.sOutput2 == b)
                        return true;
                    else{
                       r = (Gate)DrawCanvas.gateVector.elementAt(p.sOutput2);
                       if (r.type != DrawCanvas.FLIPFLOP)
                            return(isCircle(p.sOutput2, b));
                       return false;
                    }

                if ((p.sOutput1 != DrawCanvas.NONE) && (p.sOutput2 != DrawCanvas.NONE))
                    if ((p.sOutput1 == b) || (p.sOutput2 == b))
                        return true;
                    else{
                       r = (Gate)DrawCanvas.gateVector.elementAt(p.sOutput1);
                       Gate q = (Gate)DrawCanvas.gateVector.elementAt(p.sOutput2);
                       if ((r.type != DrawCanvas.FLIPFLOP) && (q.type != DrawCanvas.FLIPFLOP))
                            return(isCircle(p.sOutput1, b)||isCircle(p.sOutput2, b));

                       if ((r.type == DrawCanvas.FLIPFLOP) && (q.type != DrawCanvas.FLIPFLOP))
                            return(isCircle(p.sOutput2, b));

                       if ((r.type != DrawCanvas.FLIPFLOP) && (q.type == DrawCanvas.FLIPFLOP))
                            return(isCircle(p.sOutput1, b));

                       return false;
                    }
        }
        return false;
    }
}

//*******************************************************************************************

class mainMenu extends Frame {

    Our_Buttons buttons;
    public static MenuBar mb = new MenuBar();
    public static int mode = -1;
//------------------------------------------------------------------------------------
    public mainMenu() {

        super("Digital Simulator [untitled.circuit]");
        //{{INIT_MENUS
        MenuBar mb = new MenuBar();
        menu3 = new Menu("File");
        menu3.add(new MenuItem("New"));
        menu3.add(new MenuItem("Open"));
        menu3.add(new MenuItem("Save"));
        menu3.addSeparator();
        menu3.add(new MenuItem("Exit"));
        mb.add(menu3);
        menu6 = new Menu("Utilities");
        menu6.add(new MenuItem("Gate Size"));
        menu6.addSeparator();
        menu6.add(new MenuItem("Clock Period"));
        mb.add(menu6);
        menu2 = new Menu("Gates");
        menu5 = new Menu("Combinational Gates");
        menu5.add(new MenuItem("AND Gate"));
        menu5.add(new MenuItem("OR Gate"));
        menu5.add(new MenuItem("XOR Gate"));
        menu5.add(new MenuItem("NOT Gate"));
        menu5.add(new MenuItem("Splitter"));
        menu5.add(new MenuItem("Ground"));
        menu5.add(new MenuItem("High Voltage"));
        menu5.add(new MenuItem("One Bit Input"));
        menu5.add(new MenuItem("Led"));
        menu2.add(menu5);
        menu4 = new Menu("Sequential Gates");
        menu4.add(new MenuItem("Clock"));
        menu4.add(new MenuItem("D Flip-Flop"));
        menu2.add(menu4);
        mb.add(menu2);
        menu1 = new Menu("Help");
        menu1.add(new MenuItem("Help"));
        menu1.addSeparator();
        menu1.add(new MenuItem("About"));
        mb.add(menu1);
        setMenuBar(mb);
        //}}
        buttons = new Our_Buttons(Our_Buttons.target);
    }

//------------------------------------------------------------------------------------
    public synchronized void show() {
    	move(50, 50);
    	super.show();
    }

    //{{DECLARE_MENUS
    Menu menu3;
    Menu menu6;
    Menu menu2;
    Menu menu5;
    Menu menu4;
    Menu menu1;
    //}}

//------------------------------------------------------------------------------------
    public void selectedAbout() {

        // to do: put event handler code here.
        buttons.clickedButton1();
    }

//------------------------------------------------------------------------------------
    public boolean action(Event event, Object arg) {
    if (event.target instanceof MenuItem) {
        String label = (String) arg;
        if (label.equalsIgnoreCase("Clock Period")) {
                                                                                    selectedClockPeriod();
                                                                                    return true;
                                                                                } else if (label.equalsIgnoreCase("New")) {
                                                                                selectedNew();
                                                                                return true;
                                                                            } else if (label.equalsIgnoreCase("Clock Frequency")) {
                                                                            selectedClockFrequency();
                                                                            return true;
                                                                        } else if (label.equalsIgnoreCase("Gate Size")) {
                                                                        selectedGateSize();
                                                                        return true;
                                                                    } else if (label.equalsIgnoreCase("XOR Gate")) {
                                                                    selectedXORGate();
                                                                    return true;
                                                                } else if (label.equalsIgnoreCase("One Bit Input")) {
                                                                selectedOneBitInput();
                                                                return true;
                                                            } else if (label.equalsIgnoreCase("Save")) {
                                                            try {
                                                               selectedSave();
                                                            }
                                                            catch(IOException e){
                                                            }
                                                            return true;
                                                        } else if (label.equalsIgnoreCase("Open")) {
                                                         try {
                                                             selectedOpen();
                                                         }
                                                         catch(IOException ee){
                                                         }
                                                        return true;
                                                    } else if (label.equalsIgnoreCase("Clock")) {
                                                    selectedClock();
                                                    return true;
                                                } else if (label.equalsIgnoreCase("D Flip-Flop")) {
                                                selectedDFlipFlop();
                                                return true;
                                            } else if (label.equalsIgnoreCase("Led")) {
                                            selectedLed();
                                            return true;
                                        } else if (label.equalsIgnoreCase("High Voltage")) {
                                        selectedHighVoltage();
                                        return true;
                                    } else if (label.equalsIgnoreCase("Ground")) {
                                    selectedGround();
                                    return true;
                                } else if (label.equalsIgnoreCase("Splitter")) {
                                selectedSplitter();
                                return true;
                            } else if (label.equalsIgnoreCase("NOT Gate")) {
                            selectedNOTGate();
                            return true;
                        } else if (label.equalsIgnoreCase("OR Gate")) {
                        selectedORGate();
                        return true;
                    } else if (label.equalsIgnoreCase("AND Gate")) {
                    selectedANDGate();
                    return true;
                } else if (label.equalsIgnoreCase("Exit")) {
                selectedExit();
                return true;
            } else if (label.equalsIgnoreCase("About")) {
            selectedAbout();
            return true;
        }
        else if (event.id == Event.WINDOW_DESTROY){
	         System.exit(0);
	         return true;
	    }
    }
    return false;
    }

//------------------------------------------------------------------------------------
    public void selectedExit() {

        // to do: put event handler code here.
        if (DrawCanvas.mode != DrawCanvas.SIMULATION){
                DrawTest.themainMenu.hide();

        }
    }

//------------------------------------------------------------------------------------
    public void selectedANDGate() {

        // to do: put event handler code here.
        if (DrawCanvas.mode != DrawCanvas.SIMULATION){
            Our_Buttons.target.setDrawMode(DrawCanvas.AND);
            Our_Buttons.target.repaint();
        }
    }

//------------------------------------------------------------------------------------
    public void selectedORGate() {

        // to do: put event handler code here.
        if (DrawCanvas.mode != DrawCanvas.SIMULATION){
            Our_Buttons.target.setDrawMode(DrawCanvas.OR);
            Our_Buttons.target.repaint();
        }
    }

//------------------------------------------------------------------------------------
    public void selectedNOTGate() {

        // to do: put event handler code here.
        if (DrawCanvas.mode != DrawCanvas.SIMULATION){
            Our_Buttons.target.setDrawMode(DrawCanvas.NOT);
            Our_Buttons.target.repaint();
        }
    }

//------------------------------------------------------------------------------------
    public void selectedSplitter() {

        // to do: put event handler code here.
        if (DrawCanvas.mode != DrawCanvas.SIMULATION){
            Our_Buttons.target.setDrawMode(DrawCanvas.SPLITTER);
            Our_Buttons.target.repaint();
        }
    }

//------------------------------------------------------------------------------------
    public void selectedGround() {

        // to do: put event handler code here.
        if (DrawCanvas.mode != DrawCanvas.SIMULATION){
            Our_Buttons.target.setDrawMode(DrawCanvas.GROUND);
            Our_Buttons.target.repaint();
        }
    }

//------------------------------------------------------------------------------------
    public void selectedHighVoltage() {

        // to do: put event handler code here.
        if (DrawCanvas.mode != DrawCanvas.SIMULATION){
            Our_Buttons.target.setDrawMode(DrawCanvas.VOLTAGE);
            Our_Buttons.target.repaint();
        }
    }

//------------------------------------------------------------------------------------
    public void selectedLed() {

        // to do: put event handler code here.
        if (DrawCanvas.mode != DrawCanvas.SIMULATION){
            Our_Buttons.target.setDrawMode(DrawCanvas.LED);
            Our_Buttons.target.repaint();
        }
    }

//------------------------------------------------------------------------------------
    public void selectedDFlipFlop() {

        // to do: put event handler code here.
        if (DrawCanvas.mode != DrawCanvas.SIMULATION){
            Our_Buttons.target.setDrawMode(DrawCanvas.FLIPFLOP);
            Our_Buttons.target.repaint();
        }
    }

//------------------------------------------------------------------------------------
    public void selectedClock() {

        // to do: put event handler code here.
        if (DrawCanvas.mode != DrawCanvas.SIMULATION){
            Our_Buttons.target.setDrawMode(DrawCanvas.CLOCK);
            Our_Buttons.target.repaint();
        }
    }

//------------------------------------------------------------------------------------
    public void selectedOpen() throws IOException{

      // to do: put event handler code here.
      if (DrawCanvas.mode != DrawCanvas.SIMULATION){
      FileDialog ourDialog = new FileDialog(this, "Open Circuit", FileDialog.LOAD);
      FilenameFilter a = new filter("circuit");
      ourDialog.setFile("*.circuit");
      ourDialog.setFilenameFilter(a);
      ourDialog.show();
      StringBuffer str = new StringBuffer(ourDialog.getDirectory() + ourDialog.getFile());

        if (str.toString().startsWith("nullnull") == false){
            if  ((str.toString()).endsWith(".*.*"))
               str.setLength(str.length()-4);
            if (!(str.toString().endsWith(".circuit")))
               str.append(".circuit");
            File openFile = new File(str.toString());
            if (openFile.exists()){
                DrawCanvas.gateVector.removeAllElements();
                DrawCanvas.mode = DrawCanvas.NONE;
                DrawCanvas.selectedGateIndex = DrawCanvas.NONE;
                DrawCanvas.x = 0;
                DrawCanvas.y = 0;
    	        RandomAccessFile input;
	            input = new RandomAccessFile(str.toString(),"r");
	            int np=input.readInt();
	            for (int i=0; i<np; i++){
	                Gate p = new Gate(0,0,0);
                    p.x = input.readInt();
                    p.y = input.readInt();
                    p.type = input.readInt();
                    p.Input1 = input.readInt();
                    p.Input2 = input.readInt();
                    p.Output = input.readInt();
                    p.sOutput1 = input.readInt();
                    p.sOutput2 = input.readInt();
                    p.Port1 = input.readInt();
                    p.Port2 = input.readInt();
                    p.Port3 = input.readInt();
                    p.Port4 = input.readInt();
                    p.Led1 = input.readInt();
                    p.Led2 = input.readInt();
                    p.Led3 = input.readInt();
                    p.Led4 = input.readInt();
                    p.in1 = input.readInt();
                    p.in2 = input.readInt();
                    p.out1 = input.readInt();
                    p.out2 = input.readInt();
                    p.changed = input.readInt();
                    p.nofInputs = input.readInt();
                    p.nofOutputs = input.readInt();
	                DrawCanvas.gateVector.addElement(p);
	            }
	            input.close();
	            repaint();
	            this.setTitle("Digital Simulator [" + str.toString() + "]");
            }
        }
        Our_Buttons.target.repaint();
        }

    }

//------------------------------------------------------------------------------------
    public static void selectedSave() throws IOException {

        // to do: put event handler code here.
        if (DrawCanvas.mode != DrawCanvas.SIMULATION){
        FileDialog ourDialog = new FileDialog(DrawTest.themainMenu/*this*/, "Save Circuit", FileDialog.SAVE);
        FilenameFilter a = new filter("circuit");
        ourDialog.setFile("untitled.circuit");
        ourDialog.setFilenameFilter(a);
        ourDialog.show();
        StringBuffer str = new StringBuffer(ourDialog.getDirectory() + ourDialog.getFile());
        if (str.toString().startsWith("nullnull") == false){
            if  ((str.toString()).endsWith(".*.*"))
               str.setLength(str.length()-4);
            if (!(str.toString().endsWith(".circuit")))
             str.append(".circuit");
            File saveFile = new File(str.toString());

	        RandomAccessFile output;
	        output = new RandomAccessFile(str.toString(),"rw");
	        int np = DrawCanvas.gateVector.size();
	        output.writeInt(np);
	        for (int i=0; i<np; i++){
	            Gate p  = (Gate)DrawCanvas.gateVector.elementAt(i);
                output.writeInt(p.x);
                output.writeInt(p.y);
                output.writeInt(p.type);
                output.writeInt(p.Input1);
                output.writeInt(p.Input2);
                output.writeInt(p.Output);
                output.writeInt(p.sOutput1);
                output.writeInt(p.sOutput2);
                output.writeInt(p.Port1);
                output.writeInt(p.Port2);
                output.writeInt(p.Port3);
                output.writeInt(p.Port4);
                output.writeInt(p.Led1);
                output.writeInt(p.Led2);
                output.writeInt(p.Led3);
                output.writeInt(p.Led4);
                output.writeInt(p.in1);
                output.writeInt(p.in2);
                output.writeInt(p.out1);
                output.writeInt(p.out2);
                output.writeInt(p.changed);
                output.writeInt(p.nofInputs);
                output.writeInt(p.nofOutputs);
	        }
	        output.close();
            DrawTest.themainMenu.setTitle("Digital Simulator [" + str.toString() + "]");
        }
        }
    }


//------------------------------------------------------------------------------------
    public void selectedOneBitInput() {

        // to do: put event handler code here.
        if (DrawCanvas.mode != DrawCanvas.SIMULATION){
            Our_Buttons.target.setDrawMode(DrawCanvas.INPUT);
            Our_Buttons.target.repaint();
        }
    }

//------------------------------------------------------------------------------------
    public void selectedXORGate() {

        // to do: put event handler code here.
        if (DrawCanvas.mode != DrawCanvas.SIMULATION){
            Our_Buttons.target.setDrawMode(DrawCanvas.XOR);
            Our_Buttons.target.repaint();
        }
    }

//------------------------------------------------------------------------------------
    public void selectedGateSize() {

        // to do: put event handler code here.
        this.mode = 0;
        ourDialogClass theourDialogClass;
        theourDialogClass = new ourDialogClass(this);
        theourDialogClass.cc = Our_Buttons.target;
        theourDialogClass.gate.show();
        theourDialogClass.label1.setText("Gate Size");
        theourDialogClass.setTitle("Change Gate Size");
        theourDialogClass.show();
        /*Our_Buttons.target.*/repaint();
    }

//------------------------------------------------------------------------------------
    public void selectedClockFrequency() {

        // to do: put event handler code here.
    }

//------------------------------------------------------------------------------------
    public void selectedNew() {

        // to do: put event handler code here.
        if (DrawCanvas.mode != DrawCanvas.SIMULATION){
            Our_Buttons.target.setDrawMode(DrawCanvas.CLEAR);
            Our_Buttons.target.repaint();
            DrawTest.themainMenu.setTitle("Digital Simulator [untitled.circuit]");
        }
    }

//------------------------------------------------------------------------------------
    public void selectedClockPeriod() {
        // to do: put event handler code here.
        this.mode = 1;
        ourDialogClass theourDialogClass;
        theourDialogClass = new ourDialogClass(this);
        theourDialogClass.cc = Our_Buttons.target;
        theourDialogClass.clock.show();
        theourDialogClass.label1.setText("Clock Period");
        theourDialogClass.setTitle("Change Clock Period");
        theourDialogClass.show();
    }
}

//*******************************************************************************************
class filter implements java.io.FilenameFilter{

    String ext;

    public filter(String ext){

        this.ext = "." + ext;
    }

    public boolean accept(File infile, String str){

        return str.endsWith(ext);
    }
}

//*******************************************************************************************
class ourDialogClass extends Dialog {

    DrawCanvas cc;
    public ourDialogClass(Frame parent) {

	    super(parent, "Change Clock Frequency", true);

	    //{{INIT_CONTROLS
        setLayout(null);
        addNotify();
        resize(insets().left + insets().right + 238, insets().top + insets().bottom + 135);
        ok_button=new Button("Ok");
        ok_button.setFont(new Font("TimesRoman",Font.PLAIN,12));
        add(ok_button);
        ok_button.reshape(insets().left + 119,insets().top + 75,105,30);
        clock= new Choice();
        clock.setFont(new Font("TimesRoman",Font.PLAIN,12));
        clock.hide();
        add(clock);
        clock.reshape(insets().left + 7,insets().top + 38,105,67);
        clock.addItem("500 ms");
        clock.addItem("1000 ms");
        clock.addItem("1500 ms");
        clock.addItem("2000 ms");
        clock.addItem("2500 ms");
        label1=new Label("Clock Frequency", Label.CENTER);
        label1.setFont(new Font("Dialog",Font.BOLD,14));
        add(label1);
        label1.reshape(insets().left + 7,insets().top + 8,217,18);
        gate= new Choice();
        gate.hide();
        add(gate);
        gate.reshape(insets().left + 7,insets().top + 38,105,75);
        gate.addItem("30");
        gate.addItem("40");
        gate.addItem("50");
        gate.addItem("60");
        gate.addItem("70");
        gate.addItem("80");
        //}}
	    clock.select(1);
	    gate.select(1);
    	setResizable(false);
    }

    public synchronized void show() {
    	Rectangle bounds = getParent().bounds();
    	Rectangle abounds = bounds();

    	move(bounds.x + (bounds.width - abounds.width)/ 2,
    	     bounds.y + (bounds.height - abounds.height)/2);

    	super.show();
    }

    public synchronized void wakeUp() {
    	notify();
    }

    public boolean handleEvent(Event event) {
    	if (event.id == Event.ACTION_EVENT && event.target == clock) {
    	    	selectedClock();
    	    	return true;
    	}
    	else
    	if (event.id == Event.ACTION_EVENT && event.target == gate) {
    	    	selectedGate();
    	    	return true;
    	}
    	else
    	if (event.id == Event.ACTION_EVENT && event.target == ok_button) {
    	    	clickedOkButton();
    	    	return true;
    	}
    	else

    	if (event.id == Event.WINDOW_DESTROY) {
    	    hide();
    	    return true;
    	}
    	return super.handleEvent(event);
    }

    //{{DECLARE_CONTROLS
    Button ok_button;
    Choice clock;
    Label label1;
    Choice gate;
    //}}

    public void clickedOkButton() {

        // to do: put event handler code here.
        if (mainMenu.mode == 1){
        switch (this.clock.getSelectedIndex()){
            case 0:
                Gate.frequency = 500;
                break;
            case 1:
                Gate.frequency = 1000;
                break;
            case 2:
                Gate.frequency = 1500;
                break;
            case 3:
                Gate.frequency = 2000;
                break;
            case 4:
                Gate.frequency = 2500;
                break;
        }
        }
        else if (mainMenu.mode == 0){
        switch (this.gate.getSelectedIndex()){
            case 0:
                DrawCanvas.SIZE = 30;
                break;
            case 1:
                DrawCanvas.SIZE = 40;
                break;
            case 2:
                DrawCanvas.SIZE = 50;
                break;
            case 3:
                DrawCanvas.SIZE = 60;
                break;
            case 4:
                DrawCanvas.SIZE = 70;
                break;
            case 5:
                DrawCanvas.SIZE = 80;
                break;
        }
        }
        this.gate.hide();
        this.clock.hide();
        this.dispose();
        mainMenu.mode = -1;
        cc.repaint();
    }

    public void selectedGate() {
        // to do: put event handler code here.
    }

    public void selectedClock() {
        // to do: put event handler code here.
        //
    }
}

//*******************************************************************************************
class About extends Frame {

    public About() {

        super("About the authors");

        //{{INIT_CONTROLS
        setLayout(null);
        addNotify();
        resize(insets().left + insets().right + 246, insets().top + insets().bottom + 225);
        label1=new Label("This program is made by:", Label.CENTER);
        label1.setFont(new Font("TimesRoman",Font.BOLD,16));
        add(label1);
        label1.reshape(insets().left + 7,insets().top + 8,224,30);
        label2=new Label("Tolga Aydin");
        label2.setFont(new Font("TimesRoman",Font.BOLD,14));
        add(label2);
        label2.reshape(insets().left + 28,insets().top + 38,133,22);
        label3=new Label("Abdurrahman Battal");
        label3.setFont(new Font("TimesRoman",Font.BOLD,14));
        add(label3);
        label3.reshape(insets().left + 28,insets().top + 58,182,23);
        label4=new Label("Osman Ozturk");
        label4.setFont(new Font("TimesRoman",Font.BOLD,14));
        add(label4);
        label4.reshape(insets().left + 28,insets().top + 79,133,20);
        label5=new Label("Serdar Unal");
        label5.setFont(new Font("TimesRoman",Font.BOLD,14));
        add(label5);
        label5.reshape(insets().left + 28,insets().top + 98,133,15);
        button1=new Button("Return to the program");
        button1.setFont(new Font("TimesRoman",Font.PLAIN,12));
        add(button1);
        button1.reshape(insets().left + 7,insets().top + 173,231,22);
        label6=new Label("For more information you can visit:");
        label6.setFont(new Font("TimesRoman",Font.PLAIN,12));
        add(label6);
        label6.reshape(insets().left + 28,insets().top + 120,203,23);
        label7=new Label("http://www.ug.bcc.bilkent.edu.tr/~battal");
        label7.setFont(new Font("TimesRoman",Font.ITALIC,12));
        add(label7);
        label7.reshape(insets().left + 28,insets().top + 143,203,15);
        //}}

        //{{INIT_MENUS
        //}}
    }

    public synchronized void show() {
    	move(50, 50);
    	super.show();
    }

    public boolean handleEvent(Event event) {
    	if (event.id == Event.ACTION_EVENT && event.target == button1) {
    	    	clickedButton1();
    	    	return true;
    	}
    	else

    	if (event.id == Event.WINDOW_DESTROY) {
    	    hide();
    	    return true;
    	}
    	return super.handleEvent(event);
    }

    //{{DECLARE_MENUS
    //}}

    //{{DECLARE_CONTROLS
    Label label1;
    Label label2;
    Label label3;
    Label label4;
    Label label5;
    Button button1;
    Label label6;
    Label label7;
    //}}
    public void clickedButton1() {
        // to do: put event handler code here.
        hide();
    }
}
//*******************************************************************************************

