using UnityEngine;
using System.Collections;

public enum Direction {
	right	= 0,
	down	= 1,
	left	= 2,
	up		= 3
}

public enum Action {
	none 	= 0,
	move	= 1,
	hit		= 2
}

public enum AnimationPhase {
	none 	= 0,
	move	= 1,
	hit		= 2
}

public struct Coordinate {
	public int x;
	public int y;
	public Coordinate (int aX, int aY) {
		x = aX;
		y = aY;
	}
}

public class Unit : MonoBehaviour {
		
	public Direction direction;
	protected Direction prevDirection;
	
	public Action action = Action.none;
	
	public Coordinate position;	
	protected Vector3 shift;
	protected Coordinate previos;
	
	public int life = 10;
	public int damage = 4;
	
	protected Sprite[] sprite = new Sprite[4];
	protected Sprite currentSprite;
	
	protected Direction[] path;
	protected int pathPosition;
	
	protected AnimationPhase animationPhase = AnimationPhase.none;
			
	protected Unit(){	
		direction = (Direction)Random.Range(0, 4);
	}
		
	protected Sprite CreateSprite(Coordinate tileUV){		
		return Tile.CreateChar(transform, tileUV, Vector3.zero);
	}
	
	protected void CreateUnitSprites(
		Coordinate right,
		Coordinate down,
		Coordinate left,
		Coordinate up){
		sprite[0] = CreateSprite(right);
		sprite[1] = CreateSprite(down);
		sprite[2] = CreateSprite(left);
		sprite[3] = CreateSprite(up);
		for(int i = 0; i < 4; i++){
			sprite[i].visible = false;
		}
		sprite[0].visible = true;
		currentSprite = sprite[0];
	}
	
	void Start () {
		name = "wolf";
		CreateUnitSprites(
			new Coordinate(4, 1),
			new Coordinate(7, 1),
			new Coordinate(6, 1),
			new Coordinate(5, 1));
		previos = position;
	}
	
	public virtual void AttackUnit(Unit enemy) {
		enemy.life -= damage;
		TextEffect.ShowMessage("-" + damage.ToString(), new Vector3(enemy.position.x * Tile.TILE_SIZE, enemy.position.y * Tile.TILE_SIZE + Tile.TILE_SIZE * 0.5f, -0.5f), 0.8f);
		shift = new Vector3(enemy.position.x - position.x,  enemy.position.y - position.y);
		animationPhase = AnimationPhase.hit;
//		Debug.Log(name + " hit " + enemy.name + " to " + damage.ToString() + " pt");
	}
	
	public virtual void MovedTo(int x, int y) {
		position.x = x;
		position.y = y;
		shift = new Vector3(previos.x - position.x,  previos.y - position.y);
		previos = position;
		animationPhase = AnimationPhase.move;
//		Debug.Log(name + "moved");
	}
	
	protected void AnimateSprite(){
		if (direction != prevDirection) {
			sprite[(int)prevDirection].visible = false;
			sprite[(int)direction].visible = true;
			currentSprite = sprite[(int)direction];
			prevDirection = direction;	
		}
	}
	
	protected bool MoveNextPathPoint(){
		if (path != null){
			if (pathPosition < path.Length) {
				direction = path[pathPosition];
				action = Action.move;
				pathPosition ++;
				return true;
			} else {
				path = null;
				pathPosition = 0;
			}
		}
		return false;
	}
	
	protected virtual void MoveUnit() {
		AnimateSprite();
		switch(animationPhase) {
		default:
		case AnimationPhase.none:
			transform.localPosition = new Vector3(position.x, position.y + 4f / 16f) * Tile.TILE_SIZE;
			break;
		case AnimationPhase.move:
			transform.localPosition =( new Vector3(position.x, position.y + 4f / 16f) + shift * Level.delta16) * Tile.TILE_SIZE;
			break;
		case AnimationPhase.hit:
			float delta =  0.25f - Mathf.Abs(Level.delta8 - 0.5f) * 0.5f;
			transform.localPosition =( new Vector3(position.x, position.y + 4f / 16f) + shift * delta) * Tile.TILE_SIZE;
			break;
		}
	}
	
	public virtual void StartTurn() {
	}
	
	public virtual void EndTurn() {
		shift = Vector3.zero;
		//animationPhase = AnimationPhase.none;
		if (Mathf.Abs(Hero.instance.position.x - position.x) + Mathf.Abs(Hero.instance.position.y - position.y) < 5){
			path = Level.instance.FindPath(position, Hero.instance.position);
			MoveNextPathPoint();
		}
		/*if (Mathf.Abs(Hero.instance.position.x - position.x) + Mathf.Abs(Hero.instance.position.y - position.y) < 6){
			path = Level.instance.FindPath(position, Hero.instance.position);
			if (path != null) {
				direction = path[0];
				pathPosition = 0;
				animationPhase = AnimationPhase.move;
				action = Action.move;
			}
		}*/
		if (life < 0){
			Die();
		}
	}
	
	public virtual void Die() {
		Destroy(gameObject);
		//Debug.Log(name + "Die");
	}
	
	void Update () {
		MoveUnit();
	}
}
