
import java.applet.*;
import java.awt.*;

public class Geometry1 extends Applet
{
     GeometryWindow gWin;
     point[] p;
     shape[] s;
     int nShapes = 0, nPoints = 0;
     boolean draggingPoint = false;
     boolean draggingShape = false;
     int dragIndex;

     public void init()
     {
	  gWin = new GeometryWindow();
	  setLayout(new BorderLayout());
	  add("Center", gWin);

	  p = new point[100];
	  s = new shape[100];

	  p[nPoints++] = new point(.2, .1);
	  p[nPoints++] = new point(-.4, -.3);
	  p[1].setColor(Color.red);
	  p[nPoints++] = new point(.5, -.1);
	  s[nShapes++] = new line(p[1], p[2]);
	  s[nShapes++] = new segment(p[0], p[2]);
	  s[1].setColor(Color.green);
	  s[nShapes++] = new ray(p[0], p[1]);
	  s[2].setColor(Color.blue);
	  s[nShapes++] = new circle(p[0], p[1]);
	  s[3].hidden = true;
	  s[nShapes++] = new circle(p[2], (segment)s[1]);
	  p[nPoints++] = s[1].pointOnShape(.3, 0);
	  p[nPoints++] = s[2].pointOnShape(-.2, -.2);
	  p[nPoints++] = s[3].pointOnShape(.6, .4);
	  s[nShapes++] = new segment(p[0], p[5]);
	  p[nPoints++] = new intersectionPoint(s[3], s[4], 1);
	  p[nPoints++] = new intersectionPoint(s[3], s[4], -1);
	  s[nShapes++] = new segment(p[6], p[7]);
	  s[nShapes++] = new circle(p[7], (segment)s[6]);
	  p[nPoints++] = new intersectionPoint(s[4], s[0], 1);
	  p[nPoints-1].setColor(Color.yellow);
	  p[nPoints++] = new intersectionPoint(s[4], s[0], -1);
	  p[nPoints-1].setColor(Color.magenta);
	  p[nPoints++] = new intersectionPoint(s[0], s[5]);
	  p[nPoints-1].setColor(Color.green);
      s[nShapes++] = new segment(p[nPoints-2], p[0]);
     }

     public void paint(Graphics g)
     {
	  DrawScene();
     }

     public boolean mouseDown(Event e, int x, int y)
     {
	  double X = gWin.xCoordinate(x);
	  double Y = gWin.yCoordinate(y);
	  boolean redraw = false;
	  
	  draggingPoint = false;
	  draggingShape = false;

	  // We check the points first, so that we will always
	  // be able to move them no matter what is on screen.
	  // we check them in reverse order so that the one drawn
	  // last is selected first
	  for (int i = nPoints - 1; i >= 0; i--)
	       if (redraw = p[i].mouseDown(X, Y))
	       {
		    draggingPoint = true;
		    dragIndex = i;
		    break; 
	       }

	  // if redraw is set then we've found the correct object
	  // we don't need to check further objects
	  if (!redraw)
	  {
	       for (int i = nShapes - 1; i >= 0; i--)
		    if (redraw = s[i].mouseDown(X, Y))
		    {
			 draggingShape = true;
			 dragIndex = i;
			 break;
		    }
	  }

	  if (redraw)
	       DrawScene();

	  return(true);
     }

     public boolean mouseDrag(Event e, int x, int y)
     {
	  double X = gWin.xCoordinate(x);
	  double Y = gWin.yCoordinate(y);
	  boolean redraw = false;

	  if (draggingPoint)
	       redraw = p[dragIndex].mouseDrag(X, Y);

	  if (draggingShape)
	       redraw = s[dragIndex].mouseDrag(X, Y);

	  if (redraw)
	       DrawScene();

	  return(true);
     }

     public boolean mouseUp(Event e, int x, int y)
     {
	  double X = gWin.xCoordinate(x);
	  double Y = gWin.yCoordinate(y);
	  boolean redraw = false;

	  for (int i = 0; i < nPoints; i++)
	       redraw = p[i].mouseUp(X, Y);
	  
	  for (int i = 0; i < nShapes; i++)
	       redraw = s[i].mouseUp(X, Y);

	  if (redraw)
	       DrawScene();

	  return(true);
     }

     public void DrawScene()
     {
 	  gWin.eraseWindow();

	  for (int i = 0; i < nShapes; i++)
	       s[i].draw(gWin);
	  
	  for (int i = 0; i < nPoints; i++)
	       p[i].draw(gWin);

	  gWin.setColor(Color.black);
	  gWin.print("The length of the green segment is " + 
		     gMath.length((segment)s[1]), -1.0, -.8);
	  gWin.print("The angle is " + 
		     180.0 * gMath.angle(p[0], p[1], p[2]) / Math.PI, 
		     -1.0, -.7);

	  gWin.displayScene();
     }
};

