/*
 * Created on Apr 21, 2003
 *
 * To change this generated comment go to 
 * Window>Preferences>Java>Code Generation>Code Template
 */
package jdraw.figures;

import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.geom.*;
import java.util.ArrayList;
import java.util.List;

import jdraw.framework.*;
import jdraw.std.StdHandle;

	/**
	 * Line implements straight lines
	 *
	 * @author  Christoph Denzler
	 * @version 1.0  21.4.03
	 */
public class Line extends AbstractFigure {
	
	public class LineHandle extends StdHandle {
		Point otherend;
		boolean isLineBeginHandle;

		/**
		 * 
		 */
		public LineHandle(Line owner, boolean isLineBegin) {
			super(owner);
			isLineBeginHandle = isLineBegin;
		}

		protected Point getAnchor(java.awt.Rectangle r) {
			return isLineBeginHandle ? 
							((Line)owner).getEnd():
						  ((Line)owner).getBegin();
		}
		
		/* (non-Javadoc)
		 * @see jdraw.framework.Handle#getBounds()
		 */
		public java.awt.Rectangle getBounds() {
			Point b = isLineBeginHandle ?((Line)owner).getBegin():((Line)owner).getEnd();
			return new java.awt.Rectangle(b.x-WIDTH/2, b.y-HEIGHT/2, WIDTH, HEIGHT);
		}

		/* (non-Javadoc)
		 * @see jdraw.framework.Handle#getCursor()
		 */
		public Cursor getCursor() {
			return Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR);
		}

		/* (non-Javadoc)
		 * @see jdraw.framework.Handle#startInteraction(int, int, java.awt.event.MouseEvent, jdraw.framework.DrawView)
		 */
		public void startInteraction(int x, int y, MouseEvent e, DrawView v) {
			otherend = isLineBeginHandle ? 
									((Line)owner).getEnd():
									((Line)owner).getBegin();
		}

		/* (non-Javadoc)
		 * @see jdraw.framework.Handle#dragInteraction(int, int, java.awt.event.MouseEvent, jdraw.framework.DrawView)
		 */
		public void dragInteraction(int x, int y, MouseEvent e, DrawView v) {
			owner.setBounds(otherend, e.getPoint());
		}

		/* (non-Javadoc)
		 * @see jdraw.framework.Handle#stopInteraction(int, int, java.awt.event.MouseEvent, jdraw.framework.DrawView)
		 */
		public void stopInteraction(int x, int y, MouseEvent e, DrawView v) {
			owner.setBounds(otherend, e.getPoint());
		}

	}

	
	private Line2D line;
	
	/**
	 * Create a new Line from begin to end.
	 * @param begin
	 * @param end
	 */
	public Line(Point begin, Point end) {
		line = new Line2D.Float(begin, end);
	}
	
	/**
	 * Create a new Line of length 0 starting
	 * at Point begin.
	 * @param begin
	 */
	public Line(Point begin) {
		line = new Line2D.Float(begin, begin);
	}

	/**
	 * Sets the bounding box. Note that the diagonal of the
	 * bounding box is the line defined by the two arguments
	 * @see jdraw.framework.Figure#setBounds(Point, Point)
	 */
	public void setBounds(Point origin, Point corner) {
		line.setLine(origin, corner);
		notifyListeners(new FigureEvent(this));
	}

	/**
	 * Draws the line
	 * @see jdraw.framework.Figure#draw(Graphics)
	 */
	public void draw(Graphics g) {
		Color tmp = g.getColor();
		g.drawLine((int)line.getX1(), (int)line.getY1(),
							 (int)line.getX2(), (int)line.getY2());
		g.setColor(tmp);
	}

	/**
	 * Tests whether the mouse coordinates are on the Line
	 * 
	 * @param x x-coordinate of mouse position
	 * @param y y-coordinate of mouse position
	 * @return <tt>true</tt>, if coordinates are contained in the figure, 
	 *         <tt>false</tt> otherwise
	 */
	public boolean contains(int x, int y) {
		return line.ptLineDistSq(x, y) <= 5;
	}

	/* (non-Javadoc)
	 * @see jdraw.framework.Figure#move(int, int)
	 */
	public void move(int dx, int dy) {
		line.setLine(line.getX1()+dx, line.getY1()+dy, line.getX2()+dx, line.getY2()+dy);
		notifyListeners(new FigureEvent(this));
	}

	/* (non-Javadoc)
	 * @see jdraw.framework.Figure#getBounds()
	 */
	public java.awt.Rectangle getBounds() {
		return line.getBounds();
	}
	
	public Point getBegin() {
		return new Point((int)line.getX1(), (int)line.getY1());
	}

	public Point getEnd() {
		return new Point((int)line.getX2(), (int)line.getY2());
	}
	
	public int getLength () {
		return (int)line.getP1().distance(line.getP2());
	}
	/**
	 * Returns a list of 8 handles for this Rectangle
	 * @see jdraw.framework.Figure#getHandles()
	 */	
	public List getHandles() {
		List handles = new ArrayList(2);
		handles.add(new LineHandle(this, true));
		handles.add(new LineHandle(this, false));
		return handles;
	}

	/**
	 * Copies the internals of Rectangle.
	 * 
	 * @see java.lang.Object#clone()
	 */
	public Object clone() {
		return null;
	}

}
