package examples.dragNDrop;

import fang.*;

import java.awt.Shape;
import java.awt.geom.*;

/**
 * Sprite extension with built-in dragging
 * capabilities.  setMouse() must be called
 * before it can be used.
 * 
 * @author Neal Ehardt
 */
public class Draggable extends Sprite
{
	/** offset from the center of the sprite to the mouse */
	private Point2D.Double offset;
	/** the mouse that the sprite can be dragged by */
	private Mouse mouse;
	/** tells whether or not the sprite is being dragged */
	private boolean dragging;
	/** default constructor */
	Draggable()
	{
		super();
		dragging = false;
	}
	/** constructor with a shape for the sprite to take on */
	Draggable(Shape shape)
	{
		super(shape);
		dragging = false;
	}
	/**
	 * Get the mouse being used for drag calculations.
	 * @return FANG mouse
	 */
	public Mouse getMouse()
	{
		return mouse;
	}
	/**
	 * Tell which mouse to read.
	 * @param mouse to be read
	 */
	public void setMouse(Mouse mouse)
	{
		this.mouse = mouse;
		dragging = false;
	}
	/**
	 * updates the sprite's position based on its offset
	 * from the mouse.
	 */
	private void updatePosition()
	{
		Point2D.Double mousePos = mouse.getLocation();
		setLocation( mousePos.x + offset.x,
		             mousePos.y + offset.y );
	}

	/**
	 * Called every advanceFrame.  Checks on the mouse
	 * to update the drag status and update the sprite's
	 * position.
	 */
	public void update()
	{
		super.update();
		//if there's no mouse, nothing can be done
		if(mouse == null)
			return;
		if(mouse.buttonPressed())
		{ //mouse is currently being held
			Point2D.Double clickPos = mouse.getClickLocation();
			//test for fresh click inside the sprite
			if(clickPos != null && intersects(clickPos))
			{
				dragging = true;
				//set new offset based on mouse and sprite positions
				Point2D.Double location = getLocation();
				offset = new Point2D.Double(
				             location.x - clickPos.x,
				             location.y - clickPos.y );
			}
			if(dragging)
				updatePosition();
		}
		else //mouse is currently released
		{
			//if dragging is still true, the piece was just released
			if(dragging)
			{
				//change the position one last time
				updatePosition();

				dragging = false;
			}
		}
	}
}

