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

public class Euclid extends Applet{
    Button cont,buttonRE;
    int number = 0;
    int P_array[] = new int[20];
    int Q_array[] = new int[20];
    int count = 0;
    Panel introPanel,cards,euclidPanel,leftCard,doubleCard;
    TextField P_Field, Q_Field ;
    int P,Q;
    int P_start,Q_start;
    TopCanvas topCanvas;
    LeftCanvas leftCanvas;
    MiddleCanvas middleCanvas;
    RightCanvas rightCanvas;
    BottomCanvas bottomCanvas, otherbottomCanvas;
    SubstituePanel substitutePanel;
    AnimateCanvas animateCanvas;
    final static String INTROPANEL =  "Start Panel" ;
    final static String EUCLIDPANEL = "Euclid Panel" ;
    final static String SUBSTITUTEPANEL = "Substitute Panel" ;
    final static String RECTANGLE = "Rectangle Canvas" ;
    final static String ANIMATE = "Animate Canvas" ;
 
    public String getAppletInfo(){
    return "Name: Euclid\n" +
      "Author: Steve Traylen\n";
    }

    public void init(){
	Graphics g = getGraphics();
	// Set Up The Intro Page.
	Dimension dim = size();
	introPanel = new Panel();
	introPanel.setBackground(Color.white);
	introPanel.setLayout(new GridLayout(4,1));
	introPanel.setFont(new Font("Helvetica", Font.PLAIN,14));
	introPanel.setBackground(Color.yellow);
	// Question Panel.
	Panel questionPanel = new Panel();
	
	//questionPanel.setLayout(new GridLayout(1,2));
	Label question = new Label("Enter two co-prime numbers, P and Q,  to solve\n");
	questionPanel.add(question);
	questionPanel.add(new Label("Px + Qy = 1"));
	introPanel.add(questionPanel);

	// Values Panels.
	Panel P_Panel = new Panel();
	Label P_label = new Label("P    =");
	P_Field = new TextField("19",5);
	P_Field.setBackground(Color.white);
	P_Panel.add(P_label);
        P_Panel.add(P_Field);
        introPanel.add(P_Panel);
        Panel Q_Panel = new Panel();
	Label Q_label = new Label("Q    =");
	P_Field.setBackground(Color.white);
	Q_Field = new TextField("83",5);
	Q_Field.setBackground(Color.white);
	Q_Panel.add(Q_label);
	Q_Panel.add(Q_Field);
	introPanel.add(Q_Panel);
	
	// Continue Panel
	Panel contPanel = new Panel();
	cont = new Button("Continue");
	cont.setBackground(Color.white);
	contPanel.add(cont);
	introPanel.add(contPanel);

        //Euclid Panel to make up the other card.
        
	euclidPanel = new Panel();
	euclidPanel.setBackground(Color.yellow);
	euclidPanel.setFont(new Font("Helvetica", Font.PLAIN,12));
	
	euclidPanel.setLayout(new BorderLayout());
        // Top Panel
	Panel topPanel = new Panel();
        topCanvas = new TopCanvas(4*Globals.Width/5,1*Globals.Height/20);
	//topCanvas.setBackground(Color.green);
	topPanel.add(topCanvas);
	buttonRE = new Button("Restart");
	buttonRE.setBackground(Color.white);
	//buttonRE.setForeground(Color.white);
	//buttonRE.setBackground(Color.black);
	topPanel.add(buttonRE);
        euclidPanel.add("North",topPanel);
	
        
        // Left Rectangle Canvas
        leftCanvas = new LeftCanvas(4*Globals.Width/10,15*Globals.Height/20);
	//leftCanvas.setBackground(Color.white);
	// Animate Canvas
	animateCanvas = new AnimateCanvas(4*Globals.Width/10,15*Globals.Height/20);
	//animateCanvas.setBackground(Color.white);
	// Left Cards.
	leftCard = new Panel();
	leftCard.setLayout(new CardLayout());
        leftCard.add(RECTANGLE,leftCanvas);
	leftCard.add(ANIMATE,animateCanvas);
        euclidPanel.add("West",leftCard);

	// Middle Canvas
        middleCanvas = new MiddleCanvas(3*Globals.Width/10,15*Globals.Height/20);
	//middleCanvas.setBackground(Color.yellow);
        euclidPanel.add("Center",middleCanvas);
	// Right Canvas
        rightCanvas = new RightCanvas(3*Globals.Width/10,15*Globals.Height/20);
	//rightCanvas.setBackground(Color.red);
        euclidPanel.add("East",rightCanvas);
        // Bottom Panel
        bottomCanvas = new BottomCanvas(Globals.Width,4*Globals.Height/20);
        bottomCanvas.setBackground(Color.yellow);
	//bottomCanvas.setBackground(Color.green);
        euclidPanel.add("South",bottomCanvas);
       
	// Substitute Panel
	cards = new Panel();
	cards.setLayout(new CardLayout ());

	substitutePanel = new SubstituePanel(Globals.Width,Globals.Height,cards);
	substitutePanel.setBackground(Color.yellow);
        substitutePanel.setFont(new Font("Helvetica", Font.PLAIN,10));

        // Cards Panel
	cards.add(INTROPANEL, introPanel);
	cards.add(EUCLIDPANEL, euclidPanel);
	cards.add(SUBSTITUTEPANEL, substitutePanel);
	cards.setBackground(Color.white);
	setBackground(Color.white);
	add(cards);
	validate();
	g.dispose();
    }

	
    public boolean action(Event event,Object arg){
      if (event.target == cont){
        String P_string = P_Field.getText();
        String Q_string = Q_Field.getText();
	P = Integer.valueOf(P_string).intValue();
        Q = Integer.valueOf(Q_string).intValue();
        // Force P to be the Largest.
        if ( Q > P ){
          int dummy ;
          dummy = P ; P = Q ; Q = dummy ;
        }
        //Graphics g = topPanel.getGraphics ;
	P_start = P;
	Q_start = Q;
        //cont.disable();
	rightCanvas.disable();
	bottomCanvas.messageAdd('A');
	number = 0;
	count = 0 ;
	leftCanvas.displayBoxes(P,Q,number);
	leftCanvas.enable();
        topCanvas.displayEquation(P,Q);
	middleCanvas.displayEquation(P,Q,number);
        ((CardLayout)cards.getLayout()).show(cards,EUCLIDPANEL);
	((CardLayout)leftCard.getLayout()).show(leftCard,RECTANGLE);

        return(true);
      }  
      if ( event.target == buttonRE ){
	  ((CardLayout)cards.getLayout()).show(cards,INTROPANEL);
	  cont.enable();
	  // Set things back to the start.
	  count = 0;
	  number = 0;
	  return(true);
      }
      return(true);
    }
    public void start(){
	count = 0 ;
	number = 0;
	cont.enable();
	((CardLayout)cards.getLayout()).show(cards,INTROPANEL);
    }

    public boolean mouseDown(Event event, int x, int y){
	int remainder;
	remainder = P - (number*Q) ;
	if(event.target == leftCanvas){
	    if( remainder > Q ){
		number = number + 1 ;
		leftCanvas.displayBoxes(P,Q,number);
		middleCanvas.displayEquation(P,Q,number);
	    }
	    if( remainder < 2*Q && remainder > Q ){
		P_array[count] = P;
		Q_array[count] = Q;
                bottomCanvas.messageAdd('B');
		rightCanvas.addStuff(P_array,Q_array,count);
		count = count + 1;
		return(true);
	    }
	    if( remainder < Q && remainder != 1 ){
	        ((CardLayout)leftCard.getLayout()).show(leftCard,ANIMATE);
		animateCanvas.slide(P,Q);
		bottomCanvas.messageAdd('C');
		return(true);
	    }
	    if(remainder == 1){
		bottomCanvas.messageAdd('D');
		leftCanvas.disable();
		rightCanvas.enable();
		return(true);
	    }
	    if(remainder == Q){
		bottomCanvas.messageAdd('E');
		return(true);
	    }
	    return(true);
	}
	if(event.target == animateCanvas){
	    P = Q;
	    Q = remainder;
	    number = 0;
	    ((CardLayout)leftCard.getLayout()).show(leftCard,RECTANGLE);
	    leftCanvas.displayBoxes(P,Q,number);
	    middleCanvas.displayEquation(P,Q,number);
	    return(true);
	}
	if(event.target == rightCanvas){
	    substitutePanel.go(P_array,Q_array,count,0);
	    ((CardLayout)cards.getLayout()).show(cards,SUBSTITUTEPANEL);
	    return(true);
	}
	return(true);
    }
 


    
}
    
class TopCanvas extends Canvas {	
    int P,Q;
    Euclid display ;
    int width,height ;
    public TopCanvas (int width,int height){
	super();
	this.width = width ;
	this.height = height ;
    }
    public void displayEquation(int P,int Q){
       this.P = P ;
       this.Q = Q ;
       repaint();
    }
    public void paint(Graphics g){
	//g.fillRect(0,0,200,200);
	Dimension d = size();
        g.drawString("Your Problem:    " + P+"x + "+Q+"y = 1", 50, 20);
	
    }
    public Dimension preferredSize(){
    	return new Dimension(width,height);
    }
    public synchronized Dimension minimumSize(){
    	return new Dimension(width,height);
    }
}



class LeftCanvas extends Canvas {
    int P,Q ;
    int number;
    float dummy ;
    int width,height;
    Euclid display;
    Dimension d;
    public LeftCanvas (int width,int height){
	super();
	this.width = width;
	this.height = height;
       
    }
    public void displayBoxes(int P, int Q, int number){
	this.P = P;
	this.Q = Q;
	this.number = number;
	repaint();
    }
    public void paint(Graphics g){
	g.setColor(Color.white);
	g.fillRect(2,2,width-5,height-3);
	g.setColor(Color.black);
	Dimension d = size();
	float moveup = 0 ; float moveright = 0;
	int border = 20;
	float boxwidth = (float)width - ((float)2 * (float)border);
	float boxheight =  ((float)P/(float)Q)*boxwidth ;
	if(boxheight > (float)height - ((float)2*(float)border)){
	    dummy  = ((float)height-((float)2*(float)border))/(float)boxheight ; 
            dummy = dummy * (float)boxwidth ;
	    boxwidth = dummy ;
	    boxheight = (float)height-((float)2*(float)border);

	}

	
	moveright = (((float)width  - ((float)2*(float)border)) - (float)boxwidth)/(float)2 ;
	moveright = (float)border+moveright ;
	moveup  = (((float)height - ((float)2*(float)border)) - boxheight)/(float)2 ;
        moveup = (float)border + moveup;
	g.setColor(Color.blue);
	g.fillRect((int)(moveright+1),(int)(moveup+1),(int)(boxwidth+1),(int)(boxheight+1));
	
	if( number > 0){
	    g.setColor(Color.yellow);
	    g.fillRect((int)(moveright+1),(int)(moveup+1),(int)(boxwidth+1),(int)((number*boxwidth)));
	}
	g.setColor(Color.black);
	g.drawString(""+P+"",(int)((width/2)-(boxwidth/2)-((3*border)/4))-4,(int)((height/2)+1));
	g.drawString(""+Q+"",(int)((width/2)+1)-3,(int)((height/2)-(boxheight/2)-(border/4)));
	for(int i = 0; i < number; i++){
	    g.drawLine((int)(moveright+boxwidth+1),(int)(moveup+((i+1)*boxwidth)),(int)(moveright+1),(int)(moveup+((i+1)*boxwidth)));
	    g.drawString(""+Q+"",(int)(moveright+3),(int)(moveup+(i+0.5)*boxwidth+5));
	}
	
	
	g.drawRect((int)(moveright+1),(int)(moveup+1),(int)(boxwidth+1),(int)(boxheight+1));
	g.drawRect(2,2,width-5,height-3);
    }
	
    public Dimension preferredSize(){
    	return new Dimension(width,height);
    }
    public synchronized Dimension minimumSize(){
    	return new Dimension(width,height);
    }
}


class MiddleCanvas extends Canvas {
    int width;
    int height;
    int number;
    int P,Q;
    public MiddleCanvas (int width,int height){
	this.width = width;
	this.height = height;
         
    }
    public void displayEquation(int P,int Q, int number){
	this.P = P;
	this.Q = Q;
	this.number = number;
	repaint();
    }
    public void paint(Graphics g){
	int x = 20 ; 
	int y = 20 ;
	int step = 20;
	int value = 0;
	g.setColor(Color.white);
	g.fillRect(2,2,width-3,height-3);
	g.setColor(Color.black);
	for(int i = 0; i<=number ; i++){
	    value = P - (i*Q);
	    g.drawString(""+P+" = "+i+"("+Q+") + "+value+"",x,y);
	    y = y + step;
	}
	g.drawRect(2,2,width-3,height-3);
    }



    public Dimension preferredSize(){
    	return new Dimension(width,height);
    }
    public synchronized Dimension minimumSize(){
    	return new Dimension(width,height);
    }

}


class RightCanvas extends Canvas {
    int width;
    int height;
    int count;
    int P,Q;
    int P_array[] = new int[20];
    int Q_array[] = new int[20];
    public RightCanvas (int width,int height){
	this.width = width;
	this.height = height;

    }
    public void addStuff(int P_array[],int Q_array[],int count){
	this.P_array = P_array;
	this.Q_array = Q_array;
	this.count = count;
	repaint ();
    }
    public void paint(Graphics g){
	int x = 5;
	int y = 20;
	int step = 20;
	int remainder = 0 ;
	int devisor = 0 ;
	g.setColor(Color.white);
	g.fillRect(2,2,width-5,height-3);
	g.setColor(Color.black);
	for(int i = 0;i<=count;i++){
	    
	    P = P_array[i];
	    Q = Q_array[i];
	    if( Q != 0){
		remainder = P%Q;
		devisor = P/Q;
	    }
	    if ( remainder != 0){
		g.drawString(""+remainder+" = "+P+" - "+devisor+"("+Q+")",x,y);
		y = y + step;
	    }
	}
	g.drawRect(2,2,width-5,height-3);
    }
    public Dimension preferredSize(){
    	return new Dimension(width,height);
    }
    public synchronized Dimension minimumSize(){
    	return new Dimension(width,height);
    }


}





class AnimateCanvas extends Canvas {
    int P,Q ;
    int number;
    int j;
    int width,height;
    float vec_x[] = new float[4];
    float vec_y[] = new float[4];

    boolean frozen = false;
    int start_x[] = new int[4];  //top_l,top_r,bott_r,bott_l
    int start_y[] = new int[4];
    int end_x[] = new int[4];
    int end_y[] = new int[4];

    // Double Buffer Stuff
    Dimension offDimension;
    Image offImage;
    Graphics offGraphics;

    public AnimateCanvas (int width,int height){
	super();
	this.width = width;
	this.height = height;
    }
    public void slide(int P, int Q){
	this.P = P;
	this.Q = Q;
	int border = 20;
	int delay = 1;
	float boxwidth = 0;
	float boxheight = 0;
	float moveright = 0;
	float movedown = 0 ;
	int devisor = 1 ;
	int steps = 150;
	int remainder = 1;
	devisor = P/Q;
	remainder = P%Q;
	boxwidth = width - ( 2*border);
	boxheight = ((float)P/(float)Q)*boxwidth;
	if(boxheight > height - ( 2*border)){
	    boxwidth = ((height-(2*border))/boxheight * boxwidth) ;
	    boxheight = height-(2*border);
	}
	moveright = border + ((width -2*border) - boxwidth)/2;
	movedown = border + ((height -2*border) - boxheight)/2;
	start_x[0] = (int)(moveright) ;
	start_y[0] = (int)(movedown + ((float)devisor * boxwidth));
	start_x[1] = (int)(moveright + boxwidth);
	start_y[1] = (int)(movedown + ((float)devisor * boxwidth));
	start_x[2] = (int)(moveright + boxwidth);
	start_y[2] = (int)(movedown + boxheight);
	start_x[3] = (int)(moveright );
	start_y[3] = (int)(movedown + boxheight);
	
	boxwidth = width - ( 2*border);
	boxheight = ((float)Q/(float)remainder)*boxwidth;
	if(boxheight > height - ( 2*border)){
	    boxwidth = ((height-(2*border))/boxheight * boxwidth) ;
	    boxheight = height-(2*border);
	}
	moveright = border + ((width -2*border) - boxwidth)/2;
	movedown = border + ((height -2*border) - boxheight)/2;
	end_x[0] = (int)(moveright) ;
	end_y[0] = (int)(movedown );
	end_x[1] = (int)(moveright + boxwidth);
	end_y[1] = (int)(movedown );
	end_x[2] = (int)(moveright + boxwidth);
	end_y[2] = (int)(movedown + boxheight);
	end_x[3] = (int)(moveright );
	end_y[3] = (int)(movedown + boxheight);
	for(int i = 0 ; i<=4-1;i++){
	    vec_x[i] = (float)(end_x[(i+1)%4] - start_x[i])/(float)steps;
	    vec_y[i] = (float)(end_y[(i+1)%4] - start_y[i])/(float)steps;
	}
	long startTime = System.currentTimeMillis();

	
	for ( j = 0 ; j<= steps ; j++){
	     startTime   = startTime + delay;
	     while(System.currentTimeMillis() < startTime);
             Graphics g = getGraphics();
	     update(g);
	}
    }
    public void paint(Graphics g){
	update(g);
    }

    public void update(Graphics g){
	float x[] = new float[4];
	float y[] = new float[4];
	Polygon poly = new Polygon();

	Dimension d = size();

	if ( (offGraphics == null)
	     || (d.width != offDimension.width )
	     || (d.height != offDimension.height ) ){
	    offDimension = d;
	    offImage = createImage(d.width,d.height);
	    offGraphics = offImage.getGraphics();
	}

        offGraphics.setColor(Color.white);
        offGraphics.fillRect(0,0,width,height);
	for(int i = 0;i<=4-1;i++){
	    x[i] = start_x[i] + ((float)j*vec_x[i] + 1);
	    y[i] = start_y[i] + ((float)j*vec_y[i] + 1);
	    poly.addPoint((int)(x[i]+1),(int)(y[i]+1));
	}
	offGraphics.setColor(Color.blue);
	offGraphics.fillPolygon(poly);
	offGraphics.setColor(Color.black);
	offGraphics.drawRect(2,2,width-3,height-3);
	g.drawImage(offImage,0,0,this);
    }
    public Dimension preferredSize(){
    	return new Dimension(width,height);
    }
    public synchronized Dimension minimumSize(){
    	return new Dimension(width,height);
    }
}
class SubstituePanel extends Panel {	
    int P,Q;
    int solution = 1;
    int low = 0;
    int w_last = 0;
    int x_last = 0;
    int y_last = 0;
    int z_last = 0;
    int width,height ;
    int num_x,num_y;
    Panel cards;
    String buff[] = new String[6];
    Button butt[] = new Button[20];
    Button button,cont,restart,down;
    TextField W_field,Y_field;
    int W_real;
    int Y_real;
    Panel leftSub;
    BottomCanvas messages;
    Sub rightSub;
    int a[] = new int[20];
    int b[] = new int[20];
    int c[] = new int[20];
    int d[] = new int[20];
    int f[] = new int[20];
    int X_array[] = new int[20];
    int Z_array[] = new int[20];
    int count = 0;
    int index = 0;
    int stage = 0;
    public SubstituePanel (int width,int height,Panel cards){
	super();
	this.cards = cards;
	this.width = width;
	this.height = height;
	setLayout(new BorderLayout());
    }
    public void go(int P_array[],int Q_array[],int count,int index ){
	
	this.X_array = X_array;
	this.Z_array = Z_array;
	this.count = count ;
	this.index = index ;
        int j;
        int P,Q;
        Label A;
        Sub bitPanel;
	leftSub = new Sub(3*width/4,5*height/6);
        leftSub.setLayout(new CardLayout());
        leftSub.setFont(new Font("Helvetica", Font.PLAIN,14));
	rightSub = new Sub(width/4,5*height/6);
	rightSub.setLayout(new GridLayout(10,1));
	messages = new BottomCanvas(width,height/5);
	messages.setBackground(Color.yellow);
	messages.setFont(new Font("Helvetica", Font.PLAIN,14));
	add("West",leftSub);
	add("East",rightSub);
	add("South",messages);
	messages.messageAdd('F');
        f[0] = 1;
        for(int i = 0;i<count; i++){
	  P = P_array[i];
          Q = Q_array[i];
          a[i] = P%Q;
          b[i] = P;
          c[i] = P/Q;
          d[i] = Q;
          butt[i] = new Button(a[i]+" = 1("+b[i]+") - "+c[i]+"("+d[i]+")");
	  butt[i].setBackground(Color.white);
          rightSub.add(butt[i]);
        }
	butt[count-1].disable();
	index = count -1;
        drawALine(a,b,c,d,f,count,index,0);
	if ( count == 1 ){
	    solution = 1;
	    wellDone(1,b[0],c[0],d[0],0,solution);
	    messages.messageAdd('H');
	}
         
    }
    public boolean action(Event event,Object arg){
       if ( index > 0){
	   if(event.target == butt[index-1]){
	       for (int i = index - 1; i >= 0; i--)
		   butt[i].disable();
	       index--;
	       messages.messageAdd('G');
	       messages.show();
	       drawALine(a,b,c,d,f,count,index,1);
	       leftSub.show();
	       return(true);
	   }
	   for( int i = index-2 ; i >= 0 ;i--){  //They clicked the wrong button.
 	       if ( event.target == butt[i] ){
		   messages.messageAdd('I');
		   return(true);
	       }
	   }
       }
       if(event.target == button){
	   int w, y;
	   String string;
	   
	   
	   try{
	       string = W_field.getText();
	       w = Integer.valueOf(string).intValue();
	       string = Y_field.getText();
	       y = Integer.valueOf(string).intValue();
	   }
	   catch (NumberFormatException err){
	       w = -1;
	       y = -1;
	   }
	   
	   if ( W_real == w && Y_real == y ){
	       if(index != 0){ 
		   messages.messageAdd('F');
		   drawALine(a,b,c,d,f,count,index,2);
		   for ( int i = 0 ; i <=index -1 ;i++)
		       butt[i].enable();
	       }
	       if(index == 0){
		   solution = 1;
		   low = 1;
		   wellDone(w,P,y,Q,low,solution);
		   messages.messageAdd('H');
	       }
	       return(true);
	   }
	   else{
	       messages.messageAdd('J');
	       return(true);
	   }
	   
       } 
       if ( event.target == cont ){
	   if ( count == 1 ){
	       wellDone(1,b[0],c[0],d[0],low,++solution);
	   }
	   if ( count > 1 ){
	       wellDone(W_real,P,Y_real,Q,low,++solution);
	   }
	   return(true);
       }
       if ( event.target == down){
	   if ( count == 1 ){
	       wellDone(1,b[0],c[0],d[0],--low,solution);
	   }
	   if ( count > 1 ){
	       wellDone(W_real,P,Y_real,Q,--low,solution);
	   }
	   return(true);
       }

       if ( event.target == restart ){
	   //Applet a = getAppletContext().getApplet(Euclid);
	   removeAll();
	   count = 0 ;
	   index = 0 ;
	   ((CardLayout)cards.getLayout()).show(cards,"Start Panel");
	   return(true);
       }
       
       return(true);
    }
    public void wellDone(int w, int P, int y, int Q,int low,int solution){
	this.solution = solution;
	this.low = low;
	LinePanel linePanel;
	Panel bitPanel = new Panel();
	bitPanel.setLayout(new BorderLayout());
	Sub topPanel = new Sub(3*width/4,3*height/12);
	topPanel.setLayout(new GridLayout(0,1));
	topPanel.add(new Label("WELL DONE YOU HAVE SOLVED",Label.CENTER));
	topPanel.add(new Label(P+"x + "+Q+"y = 1",Label.CENTER));
	topPanel.add(new Label("Your solution is",Label.CENTER));
	topPanel.add(new Label(P+"("+w+") + "+Q+"(-"+y+") = 1",Label.CENTER));
	bitPanel.add("North",topPanel);
	Sub bottomPanel = new Sub(3*width/4,7*height/12);
	bottomPanel.setLayout(new BorderLayout());
	bottomPanel.setForeground(Color.blue);
	Sub L_pan = new Sub(2*width/12,3*height/12);
	Sub C_pan = new Sub(1*width/12,3*height/12);
	Sub R_pan = new Sub(6*width/12,3*height/12);
	
	L_pan.setLayout(new GridLayout(0,1));
	C_pan.setLayout(new GridLayout(0,1));
	R_pan.setLayout(new GridLayout(0,1));
	L_pan.add(new Label(""));
	C_pan.add(new Label(""));
	R_pan.add(new Label(""));
	L_pan.add(new Label("x",Label.CENTER));
	C_pan.add(new Label("y",Label.CENTER));
	R_pan.add(new Label("Equation",Label.CENTER));
	L_pan.add(new Label("---",Label.CENTER));
	C_pan.add(new Label("---",Label.CENTER));
	R_pan.add(new Label("---",Label.CENTER));


        
	for (int i = low ; i< solution ;i++){
	    int one = w - (i * Q);
	    int two = -y + (i * P);
	    
	    if ( i > solution - 8 +low ){
		L_pan.add(new Label(one+"",Label.CENTER));
		C_pan.add(new Label(two+"",Label.CENTER));
		if ( two < 0 ){
		    Label equ = new Label(P+"("+one+") + "+Q+"("+two+") = 1",Label.CENTER);
		    R_pan.add(equ);
		}
		if ( two >= 0 ){
		    Label equ = new Label(P+"("+one+") + "+Q+"("+two+") = 1",Label.CENTER);
		    R_pan.add(equ);
		}
	    }
	}
	cont = new Button("Up");
	down = new Button("Down");
	restart = new Button("Restart");
	cont.setForeground(Color.black);
        down.setForeground(Color.black);
	restart.setForeground(Color.black);
	cont.setBackground(Color.white);
	down.setBackground(Color.white);
	restart.setBackground(Color.white);
	L_pan.add(cont);
	C_pan.add(down);
	R_pan.add(restart);
	//C_pan.add(new Label(""));
	//R_pan.add(new Label(""));
	for ( int i = solution ;i<=8 ; i++){
	    L_pan.add(new Label(""));
	    C_pan.add(new Label(""));
	    R_pan.add(new Label(""));
	}
	bottomPanel.add("West",L_pan);
	bottomPanel.add("Center",C_pan);
	bottomPanel.add("East",R_pan);
	bitPanel.add("South",bottomPanel);
	leftSub.add("BITSPANEL",bitPanel);
	
	((CardLayout)leftSub.getLayout()).show(leftSub,"BITSPANEL");
    }

    public void drawALine(int a[],int b[],int c[],int d[],int f[],int count,int index,int stage){
	this.a = a;
	this.b = b;
	this.c = c;
	this.d = d;
	this.f = f;
	this.count = count;
	this.index = index;
	this.stage = stage;
	int w,x,y,z ;
	w = 1; x = b[count-1]; y = c[count-1]; z = d[count-1];
	int which = 0;
	int last = 0;
	Panel  bitPanel = new Panel();
	bitPanel.setLayout(new GridLayout(13,1));
	LinePanel linePanel = new LinePanel();
	if ( count != 1 ){
	    if( x==a[count-2] && index == count - 1)
		which=1;
	    if( z==a[count-2] && index == count - 1)
		which=2;
	}
	linePanel.addWXYZ(w,x,y,z,which );
	bitPanel.add(linePanel);
	w_last = w ; x_last = x ; y_last = y ; z_last = z ;
	for ( int i = count-2 ; i >= index ; i-- ){
	    f[i] = 1;
	    if (x_last == a[i]){
		which = 1;
		z = z_last ;
		if ( z_last == d[i] ){
		    w = w_last * f[i];
		    x = b[i];
		    last = y_last;
		    y = w_last * c[i] + y_last;
		}  
	    }
	    if (z_last == a[i]){
		which = 2 ;
		x = x_last;
		if ( x_last == d[i]){
		    last = w_last;
		    w = w_last + y_last*c[i];
		    z = b[i];
		    y = y_last*f[i];
		}
	    }
	    if ( stage == 1 && i == index){
		linePanel = new LinePanel();
		linePanel.addWXYXsub(last,w,x,y,z,f[i],b[i],c[i],d[i],which);
		bitPanel.add(linePanel);
		linePanel = new LinePanel();
	    }
	    if ( i != index )
		which = 0;
	    if ( i != index || stage == 2){
		int newwhich = 0;
		linePanel = new LinePanel();
		if (which == 1)
		    newwhich = 2;
		if (which == 2)
		    newwhich = 1;
		linePanel.addWXYZ(w,x,y,z,newwhich);
		bitPanel.add(linePanel);
	    }	   	
	    if ( index == i && stage == 1){
		linePanel = new LinePanel();
		linePanel.add(new Label("1 ="));
		W_field = new TextField("?",3);
		W_field.setBackground(Color.white);
		linePanel.add(W_field);
		linePanel.add(new Label("("+x+")  -"));
		Y_field = new TextField("?",3);
		Y_field.setBackground(Color.white);
		linePanel.add(Y_field);
		linePanel.add(new Label("("+z+")"));
		button = new Button("Continue");
		button.setBackground(Color.white);
		linePanel.add(button);
		bitPanel.add(linePanel);
		W_real = w ; Y_real = y;
		if ( index == 0 ){
		    P = x;
		    Q = z;
		}
	    }	    
	    w_last = w ;
	    x_last = x ;
	    y_last = y ;
	    z_last = z ;
	}
	leftSub.add("BITSPANEL",bitPanel);
	((CardLayout)leftSub.getLayout()).show(leftSub,"BITSPANEL");
    }
    
    
    public Dimension preferredSize(){
    	return new Dimension(width,height);
    }
    public synchronized Dimension minimumSize(){
    	return new Dimension(width,height);
    } 
}

class LinePanel extends Panel {
    public LinePanel(){
    }

    public void addWXYXsub(int last,int w,int x,int y,int z,int f,int b,int c,int d,int which){
	//Label X,Z;
	add(new Label("1 ="));
	
	if ( which == 1 ){
	    Label W = new Label(""+w,Label.RIGHT);
	    Label X = new Label("("+f+"("+b+") - "+c+"("+d+"))",Label.LEFT);
	    X.setForeground(Color.red);
	    Label Y = new Label("- "+last,Label.RIGHT);
	    Label Z = new Label("("+z+")",Label.LEFT);
	    add(W); add(X); add(Y) ; add(Z);
	}
	if ( which == 2 ){
	     Label W = new Label(""+last,Label.RIGHT);
	    Label X = new Label("("+x+")",Label.LEFT);
	    Label Y = new Label("- "+y,Label.RIGHT);
	    Label Z = new Label("("+f+"("+b+") - "+c+"("+d+"))",Label.LEFT);
	    Z.setForeground(Color.red);
	    add(W); add(X); add(Y) ; add(Z);
	}
	//add(W); add(X); add(Y) ; add(Z);
    }

    public void addWXYZ(int w,int x, int y, int z,int which){
	Label W = new Label(""+w,Label.RIGHT);
	Label X = new Label("("+x+")",Label.LEFT);
	if ( which == 1 )
	    X.setForeground(Color.red);
	Label Y = new Label(" - "+y,Label.RIGHT);
	Label Z = new Label("("+z+")",Label.LEFT);
	if ( which == 2 )
	    Z.setForeground(Color.red);
	add(new Label("1 ="));
	add(W);
	add(X);
	add(Y);
	add(Z);
    }
}

class Sub extends Panel {
    int width,height;
    public Sub(int width,int height){
	this.width = width;
	this.height = height;
        //setLayout(new GridLayout(20,2));
    }
    public Dimension preferredSize(){
    	return new Dimension(width,height);
    }
    public synchronized Dimension minimumSize(){
    	return new Dimension(width,height);
    } 
}


class Globals{
  static final int Width = 500 ;
  static final int Height = 500 ;
}



class BottomCanvas extends Canvas {
    int width;
    int height;
    int length = 5;
    char letter;
    String buff[] = new String[5];
    public BottomCanvas (int width, int height){
	this.width = width;
	this.height = height;
    }
    public void messageAdd(char letter){
	this.letter = letter ;
       
	if ( letter == 'A' ){
	    buff[0] =  "(A) Above you can see a rectangle representing";
	    buff[1] =  "the expression shown in the middle.";
	    buff[2] =  "Click on the rectangle to proceed";
	    length = 3 ;
	}
	if ( letter == 'B' ){
	    buff[0] =  "(B) This is the final result with this rectangle";
	    buff[1] =  "It will be useful later so we have.";
	    buff[2] =  "made a note of it to the right.";
	    buff[3] =  "Click on the rectangle to proceed";
	    length = 4 ;
	}
	if ( letter == 'C' ){
	    buff[0] =  "(C) We now repeat the process. ";
	    buff[1] =  "Click on the rectangle to proceed.";
	    length = 2 ;
	}
	if ( letter == 'D' ){
	    buff[0] = "(D) Since we now have a remainder of one we have";
	    buff[1] = "finished the algorithm and we have obtained all";
	    buff[2] = "the information in the right column to solve" ;
	    buff[3] = "the problem" ;
	    buff[4] = "Click on the right column to proceed";
	    length = 5 ;
	}
	if ( letter == 'E' ){
	    buff[0] = "(E) You have just shown that the two numbers";
	    buff[1] = "you chose have a  common prime factor.";
	    buff[2] = "Click the restart button and this time use two co-prime";
	    buff[3] = "numbers to start the algorithm with.";
	    length = 4 ;
	}
	if ( letter == 'F' ){
	    buff[0] = "(F) On the right are the results you found from the";
	    buff[1] = "previous section.";
	    buff[2] = "You can replace the value in red brackets by";
	    buff[3] = "clicking on one of the equations on the right";
	    length = 4 ;
	}
	if ( letter == 'G' ){
	    buff[0] = "(G) Replace each of the \"?\" with";
	    buff[1] = "values so the expression is true.";
	    buff[2] = "Simplify the line above to do this.";
	    buff[3] = "Click on Continue.";
	    length = 4 ;
	}
	if ( letter == 'H' ){
	    buff[0] = "(H) Well done. You have solved the problem";
	    buff[1] = "You can obtain furthur solutions by clicking";
	    buff[2] = "on up or down.";
	    buff[3] = "Restart to choose different numbers";
	    length = 3;
	}
	if ( letter == 'I' ){
	    buff[0] ="(I) You selected the wrong button. Try again";
	    length = 1;
	}
	if ( letter == 'J'){
	    buff[0] = "(J) You entered the wrong numbers." ;
	    buff[1] = "Please try again";
	    length = 2 ;
	}
	repaint();
    }
    public void paint(Graphics g){
	int x = 30;
	int y = 20;
	int step = 15;
	g.setColor(Color.black);
	for(int i = 0 ;i<=length-1;i++){
	    g.drawString(buff[i],x,y);
	    y = y + step;
	}
	g.dispose();
    }
    public Dimension preferredSize(){
    	return new Dimension(width,height);
    }
    public synchronized Dimension minimumSize(){
    	return new Dimension(width,height);
    }
}




