
import java.awt.*;

public class ray extends line
{
     public ray(point P, point Q)
     {
	  super(P, Q);
     }

     public ray(double x1, double y1, double x2, double y2)
     {
	  super(x1, y1, x2, y2);
     }

     public ray(point P, double m)
     {
	  super(P, m);
     }

     public point coordOnShape(double X, double Y)
     {
	  point P = super.coordOnShape(X, Y);

	  double tx = q.x - p.x;
	  double ty = q.y - p.y;

	  double pTanDist = p.x * tx + p.y * ty;
	  double qTanDist = q.x * tx + q.y * ty;

	  double tanDist = P.x*tx + P.y*ty;
	  if (tanDist < pTanDist)
	       return(new point(p.x, p.y));
	  else
	       return(P);
     }

     public void draw(GeometryWindow G)
     {
	  if (!exists() || hidden)
	       return;

	  point P = null;
	  double tx = q.x - p.x;
	  double ty = q.y - p.y;
	  double length = Math.sqrt(tx*tx + ty*ty);
	  tx /= length;
	  ty /= length;

	  double pDist = p.x * tx + p.y * ty;
	  double x, y;
	  
	  G.setColor(color);

	  double m = slope();
	  if (Math.abs(m) > 1e3)
	  {
	       if (p.x * tx + G.yll * ty > pDist)
		    G.drawSegment(p.x, p.y, p.x, G.yll);
	       else
		    G.drawSegment(p.x, p.y, p.x, G.yur);
	       return;
	  }
	  else if (Math.abs(m) < 1e-3)
	  {
	       if (G.xll * tx + p.y * ty > pDist)
		    G.drawSegment(p.x, p.y, G.xll, p.y);
	       else
		    G.drawSegment(p.x, p.y, G.xur, p.y);
	       return;
	  }
	  
	  x = G.xll; y = m*(x - p.x) + p.y;
	  if ( (y > G.yll) && (y < G.yur) )
	       if ( x * tx + y * ty > pDist )
		    P = new point(x, y);

	  if (P == null)
	  {
	       x = G.xur; y = m*(x - p.x) + p.y;
	       if ( (y > G.yll) && (y < G.yur) )
		    if ( x * tx + y * ty > pDist )
			 P = new point(x, y);
	  }

	  if (P == null)
	  {
	       y = G.yll; x = (y - p.y) / m + p.x;
	       if ( (x > G.xll) && (x < G.xur) )
		    if ( x * tx + y * ty > pDist )
			 P = new point(x, y);
	  }

	  if (P == null)
	  {
	       y = G.yur; x = (y - p.y) / m + p.x;
	       if ( (x > G.xll) && (x < G.xur) )
		    if ( x * tx + y * ty > pDist )
			 P = new point(x, y);
	  }

	  if (P != null)
	  {
	       G.setColor(color);
	       G.drawSegment(p.x, p.y, P.x, P.y);
	  }
     }

     public boolean MouseDown(double X, double Y)
     {
	  if (hidden)
	       return(false);
	  double m = slope();
	  double tx = q.x - p.x;
	  double ty = q.y - p.y;
	  double nx = -(q.y - p.y);
	  double ny = q.x - p.x;
	  double pDist = p.x * tx + p.y * ty;

	  double baseDist = p.x * nx + p.y * ny;
	  double pointDist = X * nx + Y * ny;

//	  double pTanDist = p.x * tx + p.y * ty;
//	  double qTanDist = q.x * tx + q.y * ty;
	  double tanDist = X * tx + Y * ty;

	  if ( (Math.abs(pointDist - baseDist) < clickRange) &&
	       (tanDist > pDist) )
	  {
	       dragging = true;
	       
	       double dx = (pointDist - baseDist) * nx;
	       double dy = (pointDist - baseDist) * ny;

	       p.translate(dx, dy);
	       q.translate(dx, dy);
	       
	       dragX = X;
	       dragY = Y;
	       return(true);
	  }
	  return(false);	  
     }
};





