/** USE EXISTING JAVA CLASSES **/

import java.awt.*;
import java.applet.Applet;

/** EXTEND THE JAVA APPLET CLASS AND IMPLEMENT THE RUNNABLE INTERFACE **/

public class MidtermChallenge extends Applet implements Runnable

//public class MidtermChallenge extends Applet 
   {final int maxnumlines = 10;                       // Define max number of lines,
    final int maxsize = maxnumlines + 5;              // max array size, 
    Point startpoint[] = new Point[maxsize];          // the array of start points,
    Point endpoint[] = new Point[maxsize];            // the array of end points, 
    Point anchorpoint, connectpoint;                  // the current anchor point and
    int entrynum = 0;                                 // connection point, and the 
						      // current array entry number,
    int frameNumber = -1;                // Define and/or initialize some
    int delay;                           // AnimatorApplet1 class variables.
    Thread animatorThread;
    boolean frozen = true;
    Font font=new Font("TimesRoman",Font.BOLD,36);
    String framestr = "";
    
    boolean eraser = false;
    int linesleft = maxnumlines;
 
 /** INITIALIZE THE APPLET **/

    public void init()
      {setBackground(Color.blue);
       String str;
        int fps = 10;                      // Define the default fps (frames per second).
        str = getParameter("fps");         // Possibly, get HTML string specifying the
        try                                // fps.
         {if (str != null)
           {fps = Integer.parseInt(str);}  // If possible, convert HTML fps to an
          }                                // integer.
        catch (Exception e) {}             // In case the try caused something strange.
        delay = (fps > 0) ? (1000/fps): 100; // Convert fps to the milisecond delay
        }                                    // time between frame						      
											      					      // starting with 0 (instead of 1).
  
       
     /** HANDLE THE MOUSEDOWN EVENT **/    
    
     public boolean mouseDown(Event e, int x, int y)
	{if (entrynum < maxsize)                 
	  {anchorpoint = new Point(x,y);              // Initialize both points to
	   connectpoint = anchorpoint;                // the current mouse position.  
	   return true;}                              // Note that this will give us a
	 else                                         // way to prevent painting a single
	  {return false;}                             // point (see the mouseUp method).
	 }
	 
     /** HANDLE THE MOUSEDRAG EVENT **/    
    
     public boolean mouseDrag(Event e, int x, int y)
	{if (entrynum < maxsize)                      // A mouseDrag event occurs only
	  {connectpoint = new Point(x,y);             // when the mouse is moved. So,
	   repaint();                                 // we must have connectpoint != 
	   return true;}                              // anchorpoint, which ensures that
	 else                                         // a temporary (purple) line will 
	  {return false;}                             // be painted (see the paint method).
	 }	 
	 	 
	
     /** HANDLE THE MOUSEUP EVENT **/    
    
     public boolean mouseUp(Event e, int x, int y)
	{if (entrynum < maxsize && connectpoint != anchorpoint) // Don't add a single point.
	  {addline(); 
	   if (!eraser)                                          // Add new points to the arrays.
	    {repaint();}
	   else
	    {//switch to animation
	    frozen = false;
	    start();
	     }                                          // Repaint everything, including 
	   return true;
	   }                                        // the new line (all blue).
	 else                                         
	  {return false;}      
	 }
	 
	 
     /** THE ADDLINE METHOD **/   
     
     void addline()
	{startpoint[entrynum] = anchorpoint;          // Record the startpoint and endpoint
	 endpoint[entrynum] = connectpoint;           // of the new line.
	 entrynum++;                                  // Add 1 to the current entry number.
	 anchorpoint = null;                          // Nullifying these points prevents the
	 connectpoint = null;                         // line from being painted twice (see                                  
	 }                                            // the paint method).

	      
   /** GENERATE AND/OR START THE ANIMATION THREAD **/

    public void start()
       {if (frozen) { }                    // The animation is supposed to stay frozen.
        else                               // Otherwise, generate and/or start the
         {if (animatorThread == null)      // animation thread. Apparently, if run
           {animatorThread = new Thread(this);}  // breaks after catching an exception,
          animatorThread.start();                // the animatorThread though not null
          }                                      // will still need to be restarted.
        }

    /** CREATE AND DISPLAY FRAMES OF THE ANIMATION THREAD **/

    public void run()
       {
        Thread.currentThread().setPriority(Thread.MIN_PRIORITY); // Set the priority low.
        long startTime = System.currentTimeMillis();             // Remember start time.
        while (Thread.currentThread() == animatorThread)         // The animation loop.
           {frameNumber++;                               // Advance the frame number.
            framestr = "Frame " + frameNumber;           // Create the frame string.
            repaint();                                   // Display the frame.
            try                                          // Sleep for the delay period.
             {startTime += delay;
              Thread.sleep(Math.max(0,
                                    startTime-System.currentTimeMillis()));
              }
            catch (InterruptedException e) {break;}     // In case the try caused
            }                                           // something strange, exit
        }                                               // the while loop.


		      	      
    /** CREATE THE CURRENT FRAME **/

    public void paint(Graphics g)
       {if (entrynum < maxsize)
	g.setColor(Color.yellow);
	for (int i = 0; i < entrynum; i++)                   // Note that nothing happens here, 
	  {if (i < maxnumlines)                              // until a mouseDown event occurs.  
	    {g.drawLine(startpoint[i].x, startpoint[i].y,    // Repaint all lines from 0 to
			    endpoint[i].x, endpoint[i].y);}  // maxnumlines-1.    
	   //else                                               
	    //{g.setColor(Color.red);                          // Also, if entrynum > maxnumlines, 
	    // g.drawString("Sorry, line quota exceeded !!",   // then print this instead of any
		//	    endpoint[i].x, endpoint[i].y);}  // extra line.
	   }
	if (connectpoint != anchorpoint)                     // Paint a temporary purple line 
	 {g.setColor(Color.red);                         // in response to a mouseDrag event.
	  g.drawLine(anchorpoint.x, anchorpoint.y, 
		      connectpoint.x, connectpoint.y);}
	if (entrynum == maxsize-1)
	  {eraser = true;}	      
	else if (entrynum == maxsize)    
	
	   {g.setFont(font);
        g.setColor(Color.yellow);
        g.drawString(framestr,120,110);
        }
	  
	}
	
	
    }		 
