package examples.moveongrid;

import java.awt.geom.*;
import fang.TrackerAdapter;

/**Moves a sprite smoothly over
 * a set of cells in a given
 * period of time. 
 * @author Jam Jenkins
 */
public class GridTracker
			extends TrackerAdapter
{
	/**the number of vertical cells*/
	private int rows;

	/**the number of horizontal cells*/
	private int columns;

	/**the time remaining to move*/
	private double timeLeft=0;

	/**the total time given to move*/
	private double totalTime=1;

	/**the total distance required to move*/
	private Point2D.Double totalDistance;

	/**how far to move at this frame*/
	private Point2D.Double translate;

	/**makes a grid tracker to work on
	 * a square screen split up into the
	 * given number of rows and columns.
	 * @param rows the number of horizontal
	 * divisions in the screen
	 * @param columns the number of vertical
	 * divisions in the screen
	 */
	public GridTracker(int rows, int columns)
	{
		this.rows=rows;
		this.columns=columns;
		totalDistance=new Point2D.Double();
		translate=new Point2D.Double();
	}

	/**sets the time given to move from
	 * one cell to another
	 * @param totalTime the time in seconds
	 */
	public void setMoveTime(double totalTime)
	{
		this.totalTime=totalTime;
	}

	/**moves a given number of cells up/down
	 * and left/right.  The parameters represent
	 * the distance to move, not the target cell.
	 * If a move is currently underway, this
	 * method call returns immediately with no
	 * action taken and the call is ignored.
	 * @param r the number of cells to move
	 * vertically.  Positive means move to the
	 * right and negative means move to the left.
	 * @param c the number of cells to move
	 * horizontally.  Positive means move down
	 * and negative means move up.
	 */
	public void move(int r, int c)
	{
		if(timeLeft>0)
			return;
		totalDistance.x=c/(double)columns;
		totalDistance.y=r/(double)rows;
		timeLeft=totalTime;
	}

	/**gets the translation amount
	 * @return the amount to move at this frame
	 */
	public Point2D.Double getTranslation()
	{
		return translate;
	}

	/**updates the amount to translate
	 * given the amount of time that has
	 * passed.
	 * @param time the time since the last
	 * advanced time in seconds
	 */
	public void advanceTime(double time)
	{
		if(timeLeft>0)
		{
			double timePassed=Math.min(timeLeft, time);
			translate.x=totalDistance.x*timePassed/totalTime;
			translate.y=totalDistance.y*timePassed/totalTime;
			timeLeft-=timePassed;
		}
		else
		{
			translate.x=0;
			translate.y=0;
		}
	}
}

