using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using UnityEngine.EventSystems;
using System.Collections.Generic;

public class PlayerController : MonoBehaviour {
	private NavMeshAgent navAgent;
	private Animator animator;
	int collisionLayers;
	bool isRunning = false;
	Inventory inventory;
	UIManager uiManager;
	GameStateManager gameStateManager;

	public Texture2D climbCursorTexture;


	public GameObject gameManager;
	public GameObject creditsLabel;

	public Text subtitlesLabel;
	private InventoryObject objectToPickup = null;

	public AudioSource leftFoot;
	public AudioSource rightFoot;
	public AudioSource mouthAudioSource;

	public AudioClip cannotCombineVO;
	public AudioClip pickupVO;
	public AudioClip comibnedVO;
	public AudioClip lookVO;


	public GameObject pearTree;
	public GameObject bookTrunk;
	public GameObject openedBook;

	public Sprite combinedCansSprite;
	public Sprite binoculusSprite;

	public Camera treeCamera;
	public GameObject treeCameraUI;

	public List<AudioClip> footsteps;
	
	// Use this for initialization
	void Start () {
		navAgent = GetComponent<NavMeshAgent>();
		animator = GetComponent<Animator>();
		collisionLayers = (1 << LayerMask.NameToLayer("Ground")) | (1 << LayerMask.NameToLayer("TouchableObjects"));
		inventory = gameManager.GetComponent<Inventory>();
		uiManager = gameManager.GetComponent<UIManager>();
		gameStateManager = gameManager.GetComponent<GameStateManager> ();
	}
	
	// Update is called once per frame
	void Update () {

		if (isRunning && navAgent.remainingDistance == 0)
		{
			StopRunning();
		}

		if (Input.GetMouseButtonDown(0)) {
			RaycastHit hit;

			objectToPickup = null;

			if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit,  Mathf.Infinity, collisionLayers)) {

				if (!EventSystem.current.IsPointerOverGameObject()) { // If is not on UI walk
						NavigateTo (hit.point);
				} else {
					// Check if it's an inventory object
					InventoryObject invObbj = hit.collider.gameObject.GetComponent<InventoryObject>();

					if (invObbj != null) {

						if (!invObbj.isCollectable) {
							StopRunning();
							LookAt(invObbj);
							return;
						}

						// If object is close pick it up
						if (Vector3.Distance(transform.position, invObbj.transform.position) <= 1)
							PickupObject(invObbj);
						else {
							objectToPickup = invObbj;

							NavigateTo(hit.point);
						}

					}



				}
			}
		}

	}

	public void CombineItems(InventoryObject item1, InventoryObject item2) 
	{
		
		if (item1.combinesWith == item2.objectType) {
			mouthAudioSource.clip = comibnedVO;
			mouthAudioSource.Play();

			objectsCombined(item1, item2);

		} else {
			mouthAudioSource.clip = cannotCombineVO;
			mouthAudioSource.Play();
		}
	}

	void NavigateTo(Vector3 point) {
//		if (gameStateManager.getCurrentState () == GameStateManager.GameState.PLAYING) {
			navAgent.destination = point;
			animator.SetBool("Running", true);
			isRunning = true;
//		}
	}

	void StopRunning()
	{
		navAgent.destination = transform.position;
		isRunning = false;
		animator.SetBool("Running", false);

		if (objectToPickup != null) {
			PickupObject(objectToPickup);
			objectToPickup = null;
		}
	}


	void LookAt(InventoryObject obj)
	{
		if (obj.InfoText.Length > 0) {
			subtitlesLabel.text = obj.InfoText;


			mouthAudioSource.clip = lookVO;
			mouthAudioSource.Play();

			CancelInvoke("ClearSubtitlesText"); // Cancel previous invokes
			Invoke("ClearSubtitlesText", 3);
		}
	}

	void ClearSubtitlesText() {
		subtitlesLabel.text = "";
	}


	void PickupObject(InventoryObject obj)
	{		
		animator.SetTrigger("Pickup");
		GameObject.Destroy(obj.gameObject);

		Invoke("StandUp", 0.5f);

		inventory.addToInventory(obj);
		gameManager.GetComponent<UIManager> ().showInventory ();
	}

	void StandUp() {
		animator.SetTrigger("Standup");
	}


	// Called by animation triggers
	public void Footstep(int foot)
	{
		if (foot == 0) {
			leftFoot.clip = footsteps[Random.Range(0, footsteps.Count)];
			leftFoot.Play();
		} else {
			rightFoot.clip = footsteps[Random.Range(0, footsteps.Count)];
			rightFoot.Play();
		}
	}


	// Object combining
	void objectsCombined(InventoryObject obj1, InventoryObject obj2)
	{
		// Pear into soil
		if (obj1.objectType == ObjectsEnum.inventoryObjectsEnum.pear || obj2.objectType == ObjectsEnum.inventoryObjectsEnum.soil) {
			pearTree.GetComponent<Animator>().SetTrigger("Grow");
			inventory.removeFromInvetory(ObjectsEnum.inventoryObjectsEnum.pear);
			uiManager.hideInventory();

			pearTree.transform.Find("treeSound").transform.GetComponent<AudioSource>().Play();

			InventoryObject pearInvObj = pearTree.transform.Find("Plane").GetComponent<InventoryObject>();
			pearInvObj.Name = "A Pear Tree";
			pearInvObj.InfoText = "The pear doesn't fall too far from the tree...";
			pearInvObj.objectType = ObjectsEnum.inventoryObjectsEnum.trunk;
			pearInvObj.combinesWith = ObjectsEnum.inventoryObjectsEnum.binocular;
		}

		// Book on trunk
		if (obj1.objectType == ObjectsEnum.inventoryObjectsEnum.stupidBook || obj2.objectType == ObjectsEnum.inventoryObjectsEnum.stupidBook) {
			inventory.removeFromInvetory(ObjectsEnum.inventoryObjectsEnum.stupidBook);
			uiManager.hideInventory();
			openedBook.active = true;
			bookTrunk.GetComponent<InventoryObject>().Name = "Opened Stupid Book";
			bookTrunk.GetComponent<InventoryObject>().InfoText = "Now he have something to do in his spare time.";
		}

		if (obj1.objectType == ObjectsEnum.inventoryObjectsEnum.jarredCrocodile || obj2.objectType == ObjectsEnum.inventoryObjectsEnum.jarredCrocodile) {
			GameOver();
		}


		if (obj1.objectType == ObjectsEnum.inventoryObjectsEnum.binocular || obj2.objectType == ObjectsEnum.inventoryObjectsEnum.binocular) {
			ClimbTree();
		}

	}

	public void CombineInventory(ObjectsEnum.inventoryObjectsEnum item1, ObjectsEnum.inventoryObjectsEnum item2)
	{

		// Bear cans with rope check
		if ((item1 == ObjectsEnum.inventoryObjectsEnum.rope && item2 == ObjectsEnum.inventoryObjectsEnum.can) || (item2 == ObjectsEnum.inventoryObjectsEnum.rope && item1 == ObjectsEnum.inventoryObjectsEnum.can))
		{
			Debug.Log("Roped can");
			inventory.removeFromInvetory(ObjectsEnum.inventoryObjectsEnum.rope);

			InventoryItem newCan = inventory.GetInventoryItemForItem(ObjectsEnum.inventoryObjectsEnum.can);
			newCan.UpdateIcon(combinedCansSprite, "Roped Cans");
			inventory.ChangeItem(ObjectsEnum.inventoryObjectsEnum.can, ObjectsEnum.inventoryObjectsEnum.ropedcans);
		}
		// Roped cans with lenses
		else if ((item1 == ObjectsEnum.inventoryObjectsEnum.lens && item2 == ObjectsEnum.inventoryObjectsEnum.ropedcans) || (item2 == ObjectsEnum.inventoryObjectsEnum.ropedcans && item1 == ObjectsEnum.inventoryObjectsEnum.lens)) {
			Debug.Log("Binoculus");
			inventory.removeFromInvetory(ObjectsEnum.inventoryObjectsEnum.lens);

			InventoryItem newCan = inventory.GetInventoryItemForItem(ObjectsEnum.inventoryObjectsEnum.ropedcans);
			newCan.UpdateIcon(binoculusSprite, "Binoculars");
			inventory.GetInventoryObjectForItem(ObjectsEnum.inventoryObjectsEnum.ropedcans).Name = "Binoculars";
			inventory.GetInventoryObjectForItem(ObjectsEnum.inventoryObjectsEnum.ropedcans).objectType = ObjectsEnum.inventoryObjectsEnum.binocular;
			inventory.GetInventoryObjectForItem(ObjectsEnum.inventoryObjectsEnum.ropedcans).combinesWith = ObjectsEnum.inventoryObjectsEnum.trunk;
			inventory.ChangeItem(ObjectsEnum.inventoryObjectsEnum.ropedcans, ObjectsEnum.inventoryObjectsEnum.binocular);
		} else {
			mouthAudioSource.clip = cannotCombineVO;
			mouthAudioSource.Play();
		}
		
	}


	void ClimbTree()
	{
		gameStateManager.currentState = GameStateManager.GameState.BINOCULUS;

		uiManager.hideInventory();
		treeCamera.gameObject.SetActive(true);
		treeCameraUI.SetActive(true);
	}

	void GameOver() {
		Debug.Log("Game OVER!!!");

		creditsLabel.SetActive(true);
	}
}
