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

class Point {
  protected int x, y;

  public Point(int a, int b) { setPoint(a, b); }

  public void setPoint(int a, int b)
  {
    x = a;
    y = b;
  }

  public boolean Equal(Point p)
  {
    if ((x == p.x) && (y == p.y))
      return true;
    
    else 
      return false;
  }
} 


class NewCanvas extends Canvas {
final int MAXSPOTS = 6;
final int MAXLINES = 6*5/2;
  Point starts[] = new Point[MAXLINES];
  Point ends[] = new Point[MAXLINES];
  Point anchor; // start of current line
  Point currentpoint; // end of current line
  Point mystarts[] = new Point[MAXLINES];
  Point myends[] = new Point[MAXLINES];
  Point MSTstarts[] = new Point[16];
  Point MSTends[] = new Point[16];
  int currline = 0;; // number of lines
  int option, spots;
  int xspots[] = new int[16];
  int yspots[] = new int[16];
  double edges[] = new double[15];
  double MST[] = new double[15];
  int distance = 0;
  int yourdis = 0;
  double d2[] = new double[16];
  int currspots = 0;
  boolean visited [] = new boolean[16];
  int current[] = new int[16];
  double D[][] =new double[20][20];

  String s1 = new String( "The minimum spanning tree problem is to find an optimal connection ");   
   String s2 = new String( "for  a set of nodes. Each node must be visited at least once  ");
   String s3 = new String( "and the route must be connected and no cycles are allowed. ");
   String s4 = new String( "Click on a node to visit the node and drag the mouse to the next node");
   String s5 = new String("you want to connectContinue till all nodes have been visited.");
   String s6 = new String("An optimized route will be computed to compare with your route.");
   String s7 = new String( "Let us see how you perform ");

 
   public boolean mouseDown(Event e, int x, int y)  {
     Point d = new Point(x, y);
     Point rd = error_checking(d);

      if (rd != null)
         anchor = new Point(rd.x, rd.y);
      else {
             anchor = null;
	     System.out.println("Please click on the existed points");
	   }

      return true;
    }
  
   public boolean mouseUp(Event e, int x, int y) {
      Point u = new Point(x, y);
      Point ru = error_checking(u);
       if ((ru != null) && (anchor != null) && (currline < MAXLINES)) {
 	  addline(ru.x, ru.y);
          currspots++;
       }       
       else System.out.println("Please click on the existed point");

       if (currspots >= (MAXSPOTS-1))  setView(4);
       else setView(3);

       return true;
     }

     void addline(int x,int y) {
 	  starts[currline]=anchor;
 	  ends[currline]=new Point(x,y);
 	  currline++;
 	  repaint();
     }	
      


   public Point error_checking(Point p) {
       int rx, ry;
       Point R;

       for (int i = 0; i < MAXSPOTS; i++) {
          rx = Math.abs(p.x - xspots[i]);
          ry = Math.abs(p.y - yspots[i]);  
          if ( (rx < 10) && (ry < 10) )  {
	     R = new Point(xspots[i], yspots[i]);
  	     return R;
          }
       }

       return null;
    }



         
    public void paint(Graphics g) {
       if (option == 1) {        //help information

         g.setColor(Color.white);
         g.drawString(s1, 5, 25);
         g.drawString(s2, 5, 40);
         g.drawString(s3, 5, 55);
         g.drawString(s4, 5, 70);
         g.drawString(s5, 5, 85);
         g.drawString(s6, 5, 100);
         g.drawString(s7, 5, 115);
        }
   
       if (option == 2) {      //generate random points

          for (int i = 0; i < MAXSPOTS; i++) {
            xspots[i] = (int)(Math.random() * 450);
            yspots[i] = (int)(Math.random() * 450);
            g.setColor(Color.red);
            g.fillOval(xspots[i], yspots[i], 10, 10); 
          }
          currspots = 0;
	  currline = 0;
	  yourdis = 0;
	  distance = 0;
        }

      
        if (option == 3) {    //choose a route

          for (int i = 0; i < MAXSPOTS; i++) {
             g.setColor(Color.red);
             g.fillOval(xspots[i], yspots[i], 10, 10);
          }
          for (int i=0;i<currline;i++) {
            g.setColor(Color.yellow);
 	    g.drawLine(starts[i].x,starts[i].y,ends[i].x,ends[i].y);
            d2[i] = (double)(Math.pow( (starts[i].x - ends[i].x), 2) +
                  	     Math.pow( (starts[i].y - ends[i].y), 2) );
         }	
        }
	  
        if (option == 4) {      //game over: result display
           for (int i = 0; i < MAXSPOTS; i++) {
             g.setColor(Color.red);
             g.fillOval(xspots[i], yspots[i], 10, 10);
           }
           for (int i=0;i<currline;i++) {
             g.setColor(Color.yellow);
 	    g.drawLine(starts[i].x,starts[i].y,ends[i].x,ends[i].y);
           }
      
        int n = currline -1;
	d2[n] = (double)(Math.pow( (starts[n].x - ends[n].x), 2) +
                  	 Math.pow( (starts[n].y - ends[n].y), 2) );
	for (int i = 0; i < currline; i++)
	   yourdis += (int)Math.sqrt(d2[i]);


           mygraph();

           g.setColor(Color.white);
           g.drawString("My distance is:  ", 25, 25);
           g.drawString(String.valueOf(distance), 150, 25);
           g.drawString("Your distance is: ", 25, 60);
           g.drawString(String.valueOf(yourdis), 150, 60);
           g.drawString("The difference is: ", 25, 95);
           g.drawString(String.valueOf(yourdis - distance), 150, 95);
           
           g.setColor(Color.red);     //draw the route computer chose

           for (int i = 0; i <(MAXSPOTS-1); i++)
              g.drawLine(MSTstarts[i].x, MSTstarts[i].y, MSTends[i].x, MSTends[i].y);
        }
    }
  

   void mygraph() 
     {
       double d,minimum;
       int numberinst=0;
       int k = 0, n = 0; 
       //distance = 0;
      for(int i=0;i<MAXSPOTS;i++)
	for(int j=0;j<MAXSPOTS;j++)
	  D[i][j]=0;

      current[0] = 0;
      visited[0] = true; 
      numberinst = 1;

      for (int i = 1; i<MAXSPOTS; i++)
        visited[i] = false;

      for (int i = 0; i < MAXSPOTS; i++)  
	{
	  for (int j = 0; j < MAXSPOTS; j++)  
	    {
	      if (j != i) 
 		{
		d = (double) (Math.pow( (xspots[i] - xspots[j]), 2) +
		      Math.pow( (yspots[i] - yspots[j]), 2) );
		D[i][j] = Math.sqrt(d);	
	      }
	  }
      }
      int kk=0, selstart=16, selend=16, i;

      double minimumm;
      while (kk < MAXSPOTS-1) 
       {
	 minimumm= 9999.0;

	 for(int l=0;l<numberinst;l++)
	   {
	     i = current[l];
	     for(int j=0;j<MAXSPOTS;j++)
	       {
		 if (visited[j] != true)
		   { 
		     if (minimumm > D[i][j]) 
		       {
			 minimumm = D[i][j];
			 selend = j;
			 selstart=i;
		       }
		   }
	       }
	   }
	 visited[selend] = true;
	 MSTstarts[kk] = new Point(xspots[selstart], yspots[selstart]);
	 MSTends[kk] = new Point(xspots[selend], yspots[selend]);
	 distance += (int)D[selstart][selend];
	 current[numberinst++] = selend;
	 kk++;
       }
    }


  public void setView(int choice) {
      option = choice;
      repaint();
   }
}

public class Game2 extends Applet {
   private Panel p;
   private NewCanvas c;
   private Button help, newgame;
  int click = 0;

   public void init() {
     p = new Panel();
     c = new NewCanvas();
          
     c.resize(500, 500);
     c.setBackground(Color.pink);

     help = new Button("Help");
     newgame = new Button("New Game");

     p.add("West", help);
     p.add("East", newgame);
 
     add("North", p);
     add("South", c);
    }
 
    public boolean handleEvent(Event e) {
       if (e.id ==Event.WINDOW_DESTROY &&e.target==this)
           System.exit(0);

       return super.handleEvent(e);
     }
   
   public boolean action(Event e, Object o)
   { 
     if (e.target instanceof Button) {
        if (e.target == help) 
           c.setView(1);
        if (e.target == newgame) {
           c.setView(2);
        }
        repaint();

        return true;
     }  
     return true; 
   }
}




             
   

