using UnityEngine;
using System.Collections;

public enum ObjectiveDirection
{
	N = 0,
	W = 1,
	S = 2,
	E = 3
}

public enum SubjectiveDirection
{
	Forward = 0,
	Left = 1,
	TurnBack = 2,
	Right = 3,
	None = -1,
}

public class Traveller {
	
	// current position on the map
	public Vec2Int currentPlayerPosition;

	public bool Alive = true;

	public ObjectiveDirection FacingDirection = ObjectiveDirection.N;

	public GameManager ParentGameManager;

	public void DropInLabirynth()
	{
		Alive = true;
		FacingDirection = (ObjectiveDirection)UnityEngine.Random.Range (0, 4);

		System.Random rand = new System.Random();
		currentPlayerPosition = new Vec2Int(
			rand.Next() % Map.Instance.MSIZEX, 
			rand.Next() % Map.Instance.MSIZEY);
		
		while ((Mathf.Abs(currentPlayerPosition.x - Map.Instance.exitPosition.x)
		        + Mathf.Abs(currentPlayerPosition.y - Map.Instance.exitPosition.y) < 5)
		       && Map.Instance.getFieldOfMap(currentPlayerPosition.x, currentPlayerPosition.y).fieldType != Field.FieldType.Empty)
		{
			currentPlayerPosition = new Vec2Int(
				rand.Next() % Map.Instance.MSIZEX,
				rand.Next() % Map.Instance.MSIZEY);
		}

		// make sure he's not facing a wall
//		Vec2Int nextPlayerPosition = GetSubjectiveMoveNextPosition(FacingDirection);
//		while (!Map.Instance.possibleToMove(currentPlayerPosition.x,currentPlayerPosition.y,nextPlayerPosition.x,nextPlayerPosition.y))
//		{
//			int dir = (int)FacingDirection;
//			FacingDirection = (ObjectiveDirection)(dir++);
//			nextPlayerPosition = GetSubjectiveMoveNextPosition(FacingDirection);
//		}

		Debug.Log ("Traveller's dropped in at: " + currentPlayerPosition.x + ", " + currentPlayerPosition.y + ", facing " + FacingDirection);
	}
	
	public Vec2Int GetSubjectiveMoveNextPosition(ObjectiveDirection direction)
	{
		Vec2Int nextPlayerPosition = new Vec2Int (currentPlayerPosition.x, currentPlayerPosition.y);
		switch (direction) 
		{
		case ObjectiveDirection.N:
			nextPlayerPosition.y -= 1;
			break;
		case ObjectiveDirection.W:
			nextPlayerPosition.x -= 1;
			break;
		case ObjectiveDirection.S:
			nextPlayerPosition.y += 1;
			break;
		case ObjectiveDirection.E:
			nextPlayerPosition.x += 1;
			break;
		}
		return nextPlayerPosition;
	}

	public bool IsSubjectiveMovePossible(SubjectiveDirection direction)
	{
		ObjectiveDirection newDirection = FacingDirection;
		switch (direction) 
		{
		case SubjectiveDirection.Forward:
			break;
		case SubjectiveDirection.Left:
			newDirection += 1;
			break;
		case SubjectiveDirection.TurnBack:
			newDirection += 2;
			break;
		case SubjectiveDirection.Right:
			newDirection += 3;
			break;
		}
		newDirection = (ObjectiveDirection)((int)newDirection % 4);
		return IsMovePossible (newDirection);
	}

	public void SubjectiveMove(SubjectiveDirection direction)
	{	
		switch (direction)
		{
		case SubjectiveDirection.Forward:
			break;
		case SubjectiveDirection.Left:
			FacingDirection += 1;
			break;
		case SubjectiveDirection.TurnBack:
			FacingDirection += 2;
			break;
		case SubjectiveDirection.Right:
			FacingDirection += 3;
			break;
		}
		FacingDirection = (ObjectiveDirection)((int)FacingDirection % 4);
		Move(FacingDirection);
	}

	public bool IsMovePossible(ObjectiveDirection direction)
	{
		Vec2Int nextPlayerPosition = GetSubjectiveMoveNextPosition(direction);
		return (Map.Instance.possibleToMove (currentPlayerPosition.x, currentPlayerPosition.y, nextPlayerPosition.x, nextPlayerPosition.y));
		
	}
	
	public void Move(ObjectiveDirection direction)
	{
		currentPlayerPosition = GetSubjectiveMoveNextPosition (direction);
		HandleArrival();

	}
	
	public void HandleArrival()
	{
		Debug.Log ("Traveller's new position: " + currentPlayerPosition.x + ", " + currentPlayerPosition.y);
		ParentGameManager.HandleArrival (currentPlayerPosition.x, currentPlayerPosition.y);
	}

	public void Die()
	{
	}
}
