import java.awt.*;

public class pointOnLine extends pointOnShape
{
     private double lambda;
     private double minLambda, maxLambda;
     private line l;

     public pointOnLine(double X, double Y, shape S)
     {
	  super(X, Y, S);
	  
	  if (!(s instanceof line))
	       throw(new IllegalArgumentException(
		    "shape passed to pointOnLine must be a line"));

	  minLambda = -1e100;
	  maxLambda = 1e100;
	  if (s instanceof ray)
	       maxLambda = 1.0;
	  else if (s instanceof segment)
	  {
	       minLambda = 0.0;
	       maxLambda = 1.0;
	  }
	  l = (line)s;
	  setLambda();
     }

     public boolean exists()
     {
	  setLambda();
	  return(super.exists());
     }

     protected void setLambda()
     {
	  lambda = (x - l.q.x) / (l.p.x - l.q.x);
	  lambda = Math.min(Math.max(lambda, minLambda), maxLambda);
     }

     public void SetPoint(double X, double Y)
     {
	  point p = s.coordOnShape(X, Y);
	  
	  x = p.x; y = p.y;
	  setLambda();
     }

     public void setX(double X) 
     { 
	  point p = s.coordOnShape(X, y); 
	  x = p.x; y = p.y;
	  setLambda();
     }

     public void setY(double Y)
     { 
	  point p = s.coordOnShape(x, Y); 
	  x = p.x; y = p.y;
	  setLambda();
     }

     public void draw(GeometryWindow G)
     {
	  if (!exists() || hidden)
	  {
	       G.setColor(color);
	       x = lambda * l.p.x + (1 - lambda) * l.q.x;
	       y = lambda * l.p.y + (1 - lambda) * l.q.y;
	       G.drawPoint(x, y);
	  }
     }
     
     public boolean translate(double dx, double dy)
     {
	  translated = true;

	  point p = s.coordOnShape(x + dx, y + dy);
	  x = p.x;
	  y = p.y;
	  setLambda();

	  return(true);
     }

     public boolean mouseDown(double X, double Y)
     {
	  if (hidden)
	       return(false);

	  if (gMath.distance(x, y, X, Y) < clickRange)
	  {
	       dragging = true;
	       
	       point p = s.coordOnShape(X, Y);
	       x = p.x; y = p.y;
	       setLambda();
	       return(true);
	  }
	  return(false);
     }

     public boolean mouseDrag(double X, double Y)
     {
	  if (dragging == true)
	  {
	       point p = s.coordOnShape(X, Y);
	       x = p.x; y = p.y;
	       setLambda();
	       return(true);
	  }
	  return(false);
     }

     public boolean mouseUp(double X, double Y)
     {
	  dragging = false;
	  return(false);
     }
};
