using UnityEngine;
using System.Collections;

public class UnitWalk {
	private const float SPEED = 5.0f;
	
	private Grid grid;
	private Unit unit;
	private GridPos target;
	private Vector3 worldTarget;
	
	private ArrayList battles;
	
	
	public UnitWalk(Grid g, Unit u, GridPos t) {
		grid = g;
		unit = u;
		target = t;
		worldTarget = target.getWorldPosition();
		
		battles = new ArrayList();
		
		findObstacles();
	}
	
	public Unit getUnit() {
		return unit;
	}
	
	// go thru all tiles the unit will walk,
	// and check for obstacles and battles
	private void findObstacles() {
		GridPos startPos = unit.getPosition();
		int dirX = 0;
		int dirY = 0;
		int steps = 0;
		
		if (startPos.getX() != target.getX()) {
			if (target.getX() > startPos.getX()) {
				dirX = 1;
				steps = target.getX() - startPos.getX();
			}
			else {
				dirX = -1;
				steps = startPos.getX() - target.getX();
			}
		}
		else {
			if (target.getY() > startPos.getY()) {
				dirY = 1;
				steps = target.getY() - startPos.getY();
			}
			else {
				dirY = -1;
				steps = startPos.getY() - target.getY();
			}
		}
		
		int moves = 0;
		for (int i = 1; i <= steps; ++i) {
			GridPos pos = new GridPos(startPos.getX() + i * dirX, startPos.getY() + i * dirY);
			Tile tile = grid.getTile(pos);
			
			if (tile.hasUnit() || !unit.canWalkOnTile(tile)) break;
			
			++moves;
			
			battles = grid.findBattles(unit, tile.getPosition());
			if (battles.Count != 0) break;
		}
		
		// update target
		target = new GridPos(startPos.getX() + moves * dirX, startPos.getY() + moves * dirY);
		worldTarget = target.getWorldPosition();
		unit.walkedThisTurn(moves);
		
		if (battles.Count > 0) unit.endMoveThisTurn();
	}
	
	public ArrayList getBattles() {
		return battles;
	}
	
	public void step(float dt) {
		grid.removeUnit(unit);
		
		Vector3 pos = unit.getWorldPosition();
		Vector3 dir = worldTarget - pos;
		if (dir.magnitude <= SPEED * dt) {
			unit.setPosition(target);
		}
		else {
			dir.Normalize();
			pos += dir * SPEED * dt;
			unit.setPosition(new GridPos(pos));
			unit.setWorldPosition(pos);
		}
		
		grid.addUnit(unit);
	}
	
	public bool isComplete() {
		return Vector3.Distance(unit.getWorldPosition(), worldTarget) < 1.0e-5f;
	}
}
