package Nodepad;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;


/**
 * Pointer.java<br>
 * A pointer is a diamond at the tail end, and a line drawn from the
 * center of the diamond to the head end.
 *
 * Created: Tue Dec 31 14:07:20 2002
 *
 * @author <a href="mailto:shapiro@cse.buffalo.edu">Stuart C. Shapiro</a>
 */

public class Pointer extends JComponent {
    static final int width = 10; // width of the diamond
    static final int halfwidth = width/2;
    static final int defaultLength = 95; // default vertical length of the line

    protected Pad pad; // The pad this pointer is drawn on.
    /* pad-relative coordinates. */
    private int tailx, taily; // coordinates of the center of the diamond
    protected int headx, heady; // coordinates of the head-end of this pointer

    private int[] polyxpoints = new int[4];
    private int[] polyypoints = new int[4];

    /**
     * Creates a new Pointer whose tail is at position (x,y)
     * relative to its containing pad.
     *
     * @param p the pad this pointer is drawn on.
     * @param x the x position of the tail of this pointer.
     * @param y the y position of the tail of this pointer.
     */
    public Pointer (Pad p, int x, int y){
	this(p,x,y,x,y-defaultLength);
    }

    /**
     * Creates a new Pointer from (tx,ty) to (hx,hy)
     * relative to the pad its drawn on.
     *
     * @param p the pad this pointer is drawn on.
     * @param tx the x position of the tail of this pointer.
     * @param ty the y position of the tail of this pointer.
     * @param hx the x position of the head of this pointer.
     * @param hy the y position of the head of this pointer.
     */
    public Pointer (Pad p, int tx, int ty, int hx, int hy){
	super();
	pad = p;
	tailx = tx;
	taily = ty;
	headx = hx;
	heady = hy;
    }

    /**
     * Draws this pointer as a diamond, centered at <tailx,taily>, and
     * a line drawn from the center of the diamond to <headx,heady>.
     *
     * @param g a <code>Graphics</code> value
     */
    public void paintComponent(Graphics g) {
	setLocation(new Point(Math.min(tailx-halfwidth, headx),
			 Math.min(taily-halfwidth, heady)));
	setSize(new Dimension(Math.max(Math.abs(headx-tailx) + halfwidth, width),
			      Math.max(Math.abs(heady-taily) + halfwidth, width)));
	g.setColor(Color.black);
	/* draw in this component's coordinate system */
	g.drawLine(tailx-getX(), taily-getY(),
		   headx-getX(), heady-getY());
	polyxpoints[0] = tailx-getX();
	polyxpoints[1] = polyxpoints[0] + halfwidth;
	polyxpoints[2] = polyxpoints[0];
	polyxpoints[3] = polyxpoints[0] - halfwidth;
	polyypoints[0] = taily - getY() + halfwidth;
	polyypoints[1] = polyypoints[0] - halfwidth;
	polyypoints[2] = polyypoints[0] - width;
	polyypoints[3] = polyypoints[1];
	g.fillPolygon(polyxpoints, polyypoints, 4);
    }

    /**
     * Moves the tail of this pointer to a new location
     * relative to its containing pad,
     * leaving the pointer line at the same angle and length.
     * 
     * @param x the new x location of the tail of this pointer.
     * @param y the new y location of the tail of this pointer.
     */
    protected void moveTo(int x, int y){
	Rectangle bounds = getBounds();
	{int dx = x-tailx;
	tailx = x;
	headx = headx + dx;}
	{int dy = y-taily;
	taily = y;
	heady = heady + dy;}
	pad.repaint(bounds.union(getBounds()));
    }

    /**
     * Moves the tail of this pointer to a new location
     * relative to its containing pad,
     * leaving the head at the same position
     * 
     * @param x the new x location of the tail of this pointer.
     * @param y the new y location of the tail of this pointer.
     */
    protected void moveTailTo(int x, int y){
	Rectangle bounds = getBounds();
	tailx = x;
	taily = y;
	pad.repaint(bounds.union(getBounds()));
    }
    
}// Pointer
