package Rectangles;

import Rectangles.Rectangles;
import Rectangles.MoveResult;
import Rectangles.IFCConstants;
import Rectangles.Robot;

public class Hunter implements IFCConstants {
	public static final int MAX_TRAIL_LENGTH = 7;

	public static Trail[][] traceAllRobots( Rectangles rectangles, int playerIndex ) 
		throws Exception {
		Trail trails[][] = new Trail[rectangles.numPlayers()][rectangles.numRobots()];

		for( int player = 0; player < trails.length; player++ ) {
			if( player == playerIndex ) {
				continue;
			}
			
			for( int robot = 0; robot < trails[player].length; robot++ ) {
				trails[player][robot] = traceback( rectangles, player, robot );
			}
		}

		return( trails );
	}

	public static Trail traceback( Rectangles rectangles, int player, int robot ) 
		throws Exception {
		MoveResult[] moveResults = rectangles.history();
		Robot[][] robots = rectangles.allRobots();
		Trail trail = new Trail( player, robots[player][robot].xpos(), 
			robots[player][robot].ypos() 
		);

		for( int i = moveResults.length - 1; i >= ( moveResults.length - 
			MAX_TRAIL_LENGTH - 1 ) && i > -1; i-- ) {
			char[][] robotMoves = moveResults[i].moves();
			
			// if the top segment's length > 1, attempt to continue it;
			// else if the top segment's length is 1, extend is by 1 block 
			// in the direction of the previous move.
			if( ( ( Segment )trail.peek() ).length() > 0 ) {
				if( robotMoves[player][robot] != ( ( Segment )trail.peek() ).direction() ) {
					// trail changes direction; start a new segment
					trail.push( new Segment( ( ( Segment )trail.peek() ).start() ) );
					continue;
				}
			}
			else {
				// set a direction for the segment
				( ( Segment )trail.peek() ).changeDirection( robotMoves[player][robot] );
			}

			Point trailStart = ( ( Segment )trail.peek() ).start();

			// extend the trail in the previously defined direction
			switch( robotMoves[player][robot] ) {
				case _CEAST:
					trailStart.setXpos( trailStart.xpos() - 1 );
					break;
				case _CWEST:
					trailStart.setXpos( trailStart.xpos() + 1 );
					break;
				case _CNORTH:
					trailStart.setXpos( trailStart.ypos() + 1 );
					break;
				case _CSOUTH:
					trailStart.setXpos( trailStart.ypos() - 1 );
					break;
				default:
					continue;
			};
		}

		return( trail );
	}
}
