/* turtle.java -- turtle graphics subset
 *
 * Author: Eric Laroche
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 */

import java.awt.*;

/** turtle -- turtle graphics subset.
 * @author Eric Laroche
 * @version @(#) $Id: turtle.java,v 1.1 1997/03/27 15:40:42 laroche Exp $
 */
class turtle
{
	/** version string */
	private static final String version =
		"@(#) $Id: turtle.java,v 1.1 1997/03/27 15:40:42 laroche Exp $";

	/* directions, must start with 0, be consecutive, left turning */
	/** east direction */
	private static final int east = 0;
	/** north direction */
	private static final int north = 1;
	/** west direction */
	private static final int west = 2;
	/** south direction */
	private static final int south = 3;
	/** number of directions */
	private static final int directions = 4;

	/** graphics context to work on */
	private Graphics g = null;
	/** component size */
	private Dimension d = null;
	/** current turtle location.
	 * note that (0, 0) is the lower left corner.
	 */
	private Point location = null;
	/** current turtle direction */
	private int direction = east;
	/** current pen state */
	private boolean pendown = true;

	/** turtle -- no default constructor available
	 */
	private turtle( )
	{
	}

	/** turtle -- get a new turtle.
	 * Initial position is at center, direction right, pen down.
	 */
	public turtle( Graphics g, Dimension d )
	{
		this.g = g;
		this.d = d;
		/* initial turtle position is at center */
		location = new Point( this.d.width / 2, this.d.height / 2 );
		direction = east;
		pendown = true;
	}

	/** penup -- lift the pen
	 */
	public boolean penup( )
	{
		boolean oldpendown = pendown;
		pendown = false;
		return oldpendown;
	}

	/** pendown -- lower the pen
	 */
	public boolean pendown( )
	{
		boolean oldpendown = pendown;
		pendown = true;
		return oldpendown;
	}

	/** turnleft -- turn the turtle direction left
	 */
	public void turnleft( )
	{
		turnleft( true );
	}

	/** turn -- turn the turtle direction
	 */
	public void turnleft( boolean left )
	{
		if ( left )
			direction++;
		else
			direction--;
		while ( direction >= directions )
			direction -= directions;
		while ( direction < 0 )
			direction += directions;
	}

	/** turnright -- turn the turtle direction right
	 */
	public void turnright( )
	{
		turnright( true );
	}

	/** turnright -- turn the turtle direction right
	 */
	public void turnright( boolean right )
	{
		boolean left = ! right;
		turnleft( left );
	}

	/** advance -- move the turtle
	 */
	public void advance( int step )
	{
		Point oldlocation = new Point( location.x, location.y );
		switch ( direction )
		{
		case east :
			location.x += step;
			break;
		case north :
			location.y += step;
			break;
		case west :
			location.x -= step;
			break;
		case south :
			location.y -= step;
			break;
		default :
			throw new IndexOutOfBoundsException( );
		}

		if ( pendown )
			g.drawLine( oldlocation.x, graphicsy( oldlocation.y ),
				location.x, graphicsy( location.y ) );
	}

	/** setlocation -- set absolute turtle location
	 */
	public Point setlocation( Point newlocation )
	{
		Point oldlocation = new Point( location.x, location.y );
		location.x = newlocation.x;
		location.y = newlocation.y;
		return oldlocation;
	}

	/** graphicsy -- convert int turtle y coordinate to Graphics y
	 */
	private int graphicsy( int turtley )
	{
		return d.height - 1 - turtley;
	}
}
