
import java.awt.*;

class circle extends shape
{
     point center, p = null;
     double radius;
     segment sForRadius = null;
     boolean centerInSegment = false;  // is one of the segment's 
     double dragX, dragY;              // end points the center?
     

     public circle(point Center, point P)
     {
	  center = Center;
	  p = P;
     }

     public circle(point Center, double Radius)
     {
	  center = Center;
	  radius = Radius;
     }
     
     public circle(point Center, segment SForRadius)
     {
	  center = Center;
	  sForRadius = SForRadius;

	  if ((center == sForRadius.p) || (center == sForRadius.q))
	       centerInSegment = true;
     }

     public boolean exists()
     {
	  if (!center.exists())
	       return(false);
	  else if (p != null)
	       if (!p.exists())
		    return(false);
	  else if (sForRadius != null)
	       if (!sForRadius.exists())
		    return(false);
	  
	  return(true);
     }

     public void resetTranslated()
     {
	  translated = false;
	  
	  center.resetTranslated();
	  
	  if (p != null)
	       p.resetTranslated();
	  else if (sForRadius != null)
	       sForRadius.resetTranslated();
     }

     public boolean translate(double dx, double dy)
     {
	  if (translated)
	       return(true);

	  translated = true;

	  center.translate(dx, dy);
	  if (p != null)
	       p.translate(dx, dy);
	  else if (sForRadius != null)
	       sForRadius.translate(dx, dy);
	  return(true);	 
     }

     public double radius()
     {
	  if (p != null)
	       return(Math.sqrt( (center.x - p.x) * (center.x - p.x) +
				 (center.y - p.y) * (center.y - p.y) ) );
	  else if (sForRadius != null)
	       return(sForRadius.length());
	  else
	       return(radius);
     }

     public point coordOnShape(double X, double Y)
     {
	  double vx = X - center.x;
	  double vy = Y - center.y;

	  double length = Math.sqrt(vx * vx + vy * vy);
	  double rad = radius();
	  if (length != 0)
	  {
	       vx = vx * rad / length; 
	       vy = vy * rad / length;
	  }
	  else
	  {
	       vx = rad; 
	       vy = 0.0;
	  }

	  return(new point(center.x + vx, center.y + vy));
     }
     
     public pointOnShape pointOnShape(double X, double Y)
     {
	  return(new pointOnCircle(X, Y, this));
     }

     public point intersect(shape s, int whichPoint)
     {
	  if (s instanceof circle)
	  {
	       return(gMath.intersect(this, (circle)s, whichPoint));
	  }
	  else if (s instanceof line)
	  {
	       return(gMath.intersect(this, (line)s, whichPoint));
	  }
	  else
	  {
	       return(null);
	  }
     }

     public void draw(GeometryWindow G)
     {
	  if (!exists() || hidden)
	       return;

	  G.drawCircle(center.x, center.y, radius());
     }

     public boolean mouseDown(double X, double Y)
     {
	  if (hidden)
	       return(false);
	  
	  double r = radius();
	  double newRad = Math.sqrt((X - center.x)*(X - center.x) + 
	         (Y - center.y)*(Y - center.y)) - r;

	  if ( Math.abs(newRad) <= clickRange)
	  {
	       double dx = (X - center.x) * newRad;
	       double dy = (Y - center.y) * newRad;

	       dragging = true;

	       resetTranslated();

	       if (p != null)
		    p.translate(dx, dy);

// if the center is in the segment then we just translate the
// segment, if not, then we tranlate the center;	       
	       if ((sForRadius != null) && (centerInSegment == true))
		    sForRadius.translate(dx, dy);
	       else
		    center.translate(dx, dy);
		    
	       dragX = X;
	       dragY = Y;
	       return(true);
	  }
	  return(false);
     }	  

     public boolean mouseDrag(double X, double Y)
     {
	  if (dragging)
	  {
	       double dx = X - dragX;
	       double dy = Y - dragY;

	       dragging = true;
	       
	       resetTranslated();

	       if (p != null)
		    p.translate(dx, dy);

// if the center is in the segment then we just translate the
// segment, if not, then we tranlate the center;	       
	       if ((sForRadius != null) && (centerInSegment == true))
		    sForRadius.translate(dx, dy);
	       else
		    center.translate(dx, dy);
		    
	       dragX = X;
	       dragY = Y;
	       return(true);
	  }
	  return(false);
     }

     public boolean mouseUp(double X, double Y)
     {
	  dragging = false;
	  return(false);
     }
};
