import java.applet.*;
import java.awt.*;
import java.lang.Integer;

public class Fortran extends Applet
{
//for ease in finding, set the constants for this specific program

	final int NUMLINES = 5;  //lines of code in example

	final int MINI = 1;      //I starting value
	final int MAXI = 5;      //I ending value
	final int MINJ = 6;      //J starting value
	final int MAXJ = 10;     //J ending value
	final int INNSIZE = 3;   //number of code lines in innerloop
	final int OUTSIZE = 3;   //number of code lines in outerloop (in=1)
	final int XMAX = 450;    //width of image
	final int YMAX = 400;    //height of image
	

	final int BASE = 110;    //number indicating top of example
	final int FONTSIZE = 18; //size of font to indicate spacing
	final String FONTTYPE = "TimesRoman";
	final int ALIGN = 20;    //aligning values in from edge
	final int MAXOUT = 15;   //allowed lines of output (make dynamic?)

	final int OFFSET = FONTSIZE + 6;  //sets offset of lines

//set nonconstant values of program

	String program[] =
        {"       DO 20 I = 1, 5",
         "           DO 10 J = 6, 10, 2",
         "                PRINT *, I, J",
         " 10        CONTINUE",
         " 20    CONTINUE"};   

	int i, j;                 //counting values for # of loops
	Font theFont = new Font(FONTTYPE, Font.BOLD, FONTSIZE);
	int count;                //what step we're on
	int firstclick;           //tells if mouse has been clicked

//set nonconstant values for messages
	String msg;              //what is the help message
	String msg2;		 //help message cont'd
	int output[][] = new int[2][MAXOUT];
	int amtout;              //how many lines of output are there


//set nonconstant values for pointer
	int pointat;             //current position of pointer
	Image pointer;           //the image used as a pointer


/* methods:
	init()
	mousedown()
	reset()
	paint()

*/ 

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

    public void init()
    {
/*	    program[] = 
	{"       DO 20 I = 1, 5",
	 "           DO 10 J = 6, 10, 2",
	 "                PRINT *, I, J",
         " 10        CONTINUE",
	 " 20    CONTINUE"};
*/
	pointer = getImage(getCodeBase(), "images/arrow.gif");

	msg = "";
        msg2 = "";
	amtout = 0;
	count=0;
	firstclick=0;
	pointat = BASE;
	i = -1;
	j = -1;

	setBackground(Color.white);
	nextstep();	//this takes care of step 0!
// don't paint here. repaint() must be called on the load?
//	repaint();                     //get initial values.
   }

//Reminder: no animation, so no run, stop or start


//*********************************************************
    public boolean mouseDown(Event e, int x, int y)
    {
// tell the event loop that we are in next stage before calling it
	count++;
	nextstep();	//change variables for each click
	repaint();	//see all new in
	if (firstclick == 0)
	  firstclick=1;

	return true;       //has to be boolean
    }

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

    public void restart()
    {
	count = 0;
	firstclick = 0;
	amtout = 0;          //no output
	pointat = BASE;      //move pointer back to start
	i = -1;            //reset i and j
	j = -1;
	repaint();

    }

//*************************************************************
	
    public void next()
    {
	pointat +=OFFSET;
    }

    public void istart()
    {
	pointat = BASE;
    }

    public void jstart()
    {
	pointat = BASE+OFFSET;
    }

    public void output()
    {
	output[0][amtout] = i;
	output[1][amtout] = j;
	amtout++;
    }


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

    public void nextstep()
    {
	int spot = count%14;

// This is for one whole I loop, only checking which loop in last step

	switch(spot)
	{
	   case 0:
		if (amtout>0) 
			restart();
		msg="Initially, I and J have no values.";
		msg2="I will be set to 1.";
		break;

	   case 1:
		next();
		if (count == 1) i = MINI;
		msg="Begin inner loop.";
		msg2="J will be given a value of 6.";
		break;

	   case 2:
		j=MINJ;
		next();
                msg="Print out current values of I and J.";
		msg2="";
                break;
	 	
	   case 5: case 8:
		next();
		msg="Print out current values of I and J.";
		msg2="";
		break;

	   case 3: 
		next();
		output();
		msg="The first continue.  Add 2 to J.";
		msg2="Go back and check J-loop condition.";
		break;

	   case 4: case 7:
		jstart();
		j += 2;
		msg="J isn't bigger than 10,";
	        msg2="so go through loop again.";
		break;

	   case 6:
		next();
		output();
		msg="Second continue.  Add 2 to J.";
		msg2="Go back and check J-loop condition.";
		break;

	   case 9:
		next();
		output();
		msg="Third time through loop.  Add 2 to J.";
		msg2="Go back and check J-loop condition.";
		break;

	   case 10:
		jstart();
		j += 2;
		msg="J is now bigger than 10, so don't go into loop!";
		msg2="";
		break;

	   case 11:
		next(); next(); next();
		msg="We hit the outer continue.  Increment I by 1.";
		msg2="Go back and check I-loop condition.";
		break;

	   case 12:
		istart();
		i++;
		if (i<=MAXI) {
		   msg="I does not exceed limit 5, so continue.";
		   count +=2;
		}
		else
		   msg="I is greater than the limit 5, done!";
		msg2="";
		break;

	   case 13:
		next(); next(); next(); next(); next();
		msg="Program is done, click again to restart.";
		msg2="";
		break;

	default:
		pointat =BASE - OFFSET;
		msg="How the @#$*@ did you get here?";
		msg2="";
		break;
	}

    }

//*************************************************************
    public void paint(Graphics g)
    {
	g.setFont (theFont);
	for (int l=0; l<NUMLINES; l++) {
	    g.drawString (program[l], ALIGN/2, BASE+l*OFFSET);
	}

	g.drawImage(pointer, 230, pointat-OFFSET, this);

	if (i == -1) { 
	  g.drawString ("I is ", ALIGN+5,YMAX-50-3*OFFSET);
	  g.setColor(Color.blue);
	  g.drawString ("undefined", ALIGN+35,YMAX-50-3*OFFSET);
	  g.setColor(Color.black); }
	else {
	   g.drawString ("I = ", ALIGN+5, YMAX-50-3*OFFSET);
	   g.setColor(Color.blue);
	   g.drawString ("" + i, ALIGN+35, YMAX-50-3*OFFSET); 
	   g.setColor(Color.black); }
	if (j == -1) {
	   g.drawString ("J is ", ALIGN+5,YMAX-50-2*OFFSET);
	   g.setColor(Color.blue);
	   g.drawString ("undefined", ALIGN+35,YMAX-50-2*OFFSET);
	   g.setColor(Color.black); } 
	else {
           g.drawString ("J = ", ALIGN+5, YMAX-50-2*OFFSET);
	   g.setColor(Color.blue);
	   g.drawString("" + j, ALIGN+35, YMAX-50-2*OFFSET);
	   g.setColor(Color.black); }
	
        g.drawString(msg, ALIGN/2, YMAX-50);
	if (msg2 != "") 
	   g.drawString(msg2, ALIGN/2, YMAX-50+OFFSET);

	g.drawString ("OUTPUT", XMAX-2*ALIGN, BASE-2*OFFSET);
	for (int l=0; l<amtout; l++) {
	   g.setColor(Color.blue);
	   g.drawString (output[0][l] + "  " + output[1][l],
				XMAX-ALIGN/2,BASE+(l-1)*(OFFSET-2));
	   g.setColor(Color.black); }
   }
}
