using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class PlayerManager : MonoBehaviour {

	public float WRONG_TIME = 2f;				// How much time the immmunity after being hit last
	public float WRONG_FLASHING_SPEED = 0.2f; 	// How fast the player flashes when is immune to damage

	public SpriteRenderer spriteRenderer;
	public GameObject particlesBirth;
	public GameObject particlesEvocation;
	public Object particlesSpawning;

	public GameObject particlesDeath;
	public Vector3 haloIncrease = new Vector3 (0.5f,0.5f,0.5f);
	private Vector3 startingHalo = new Vector3 (0,0,0);

	private int alreadyReadSymbolIndex;
 	private float lastTimePickedUp; 

	public List<MagicToolEnum> pickedUpSymbols;
	public int idPlayer = 1;
	public SpriteRenderer halo;

	public SpriteRenderer head;
	private float headTimer = 0;

	//private bool pickUp = false;
	
	// Use this for initialization
	void Start () {
		alreadyReadSymbolIndex = -1;
		GetComponent<PlayerMovement> ().SetIdPlayer(idPlayer);
		lastTimePickedUp = Time.time;
		head.enabled = false;
	}
	
	// Update is called once per frame
	void Update () {
		headTimer -= Time.deltaTime;
		if (headTimer <= 0 && head.enabled)
			head.enabled = false;
	}
		
	void AddInStack(MagicToolEnum magicToolType){
		pickedUpSymbols.Add (magicToolType);
	}
		
		void OnTriggerEnter2D(Collider2D other){
			switch (other.gameObject.tag) {
			case "MagicTool":
				// si da all'avversario un secondo per capire cosa hai preso prima di poterne prendere un'altro
				if (Time.time - lastTimePickedUp > 1){
					lastTimePickedUp = Time.time;
					if (GameFlow.getInstance ().Actual_State == GameMode.Curse) {
						PickUpObject (other.gameObject);
					} else if (GameFlow.getInstance ().Actual_State == GameMode.UnCurse) {
						CheckSymbolInOrder (other.gameObject.GetComponent<MagicTool> ().GetType ());
						GameFlow.getInstance ().Repositioning (other.gameObject.GetComponent<MagicTool> ());
					}

					SoundEffects.instance.PlaySound(SoundEffects.instance.pickUp);
				}
			break;
			case "Ghost":
			Debug.Log ("Player ");
				if(other.gameObject.GetComponent<Ghost>().TargetPlayer == this){
					GameFlow.getInstance().ThisPlayerWinRound(idPlayer==1?2:1, true);
					Debug.Log ("Player " + idPlayer + " è stato colpito dal ghost");
				}
				break;
			}
		}

//	void OnTriggerStay2D(Collider2D other){
//		if (pickUp && other.gameObject.tag == "MagicTool") {
//			if (GameFlow.getInstance ().Actual_State == GameMode.Curse) {
//				PickUpObject (other.gameObject);
//			} else if (GameFlow.getInstance ().Actual_State == GameMode.UnCurse) {
//				CheckSymbolInOrder (other.gameObject.GetComponent<MagicTool> ().GetType ());
//				GameFlow.getInstance ().Repositioning (other.gameObject.GetComponent<MagicTool> ());
//			}
//		}
//	}

	void PickUpObject(GameObject go){
		MagicTool magicTool = go.GetComponent<MagicTool>();
		AddInStack(magicTool.GetType());

		// cambia testa
		Sprite headSprite = null;
		switch (magicTool.GetType()) {
		case MagicToolEnum.Symbol1:
			headSprite = magicTool.Symbol1;
			break;
		case MagicToolEnum.Symbol2:
			headSprite = magicTool.Symbol2;
			break;
		case MagicToolEnum.Symbol3:
			headSprite = magicTool.Symbol3;
			break;
		case MagicToolEnum.Symbol4:
			headSprite = magicTool.Symbol4;
			break;
		}
		head.sprite = headSprite;
		head.enabled = true;
		headTimer = 2;

		magicTool.PickedUp();
	}

		public bool CheckSymbolInOrder(MagicToolEnum type){
			// il simbolo preso corrisponde con quello nello stack
			PlayerManager opponent = idPlayer == 1 ? GameFlow.getInstance ().player2 : GameFlow.getInstance ().player1;
			if (alreadyReadSymbolIndex == -1)
				alreadyReadSymbolIndex = opponent.pickedUpSymbols.Count - 1;

			if (opponent.pickedUpSymbols.Count > 0) {
				if (type == opponent.pickedUpSymbols [alreadyReadSymbolIndex]) {
					alreadyReadSymbolIndex--;
					if (alreadyReadSymbolIndex < 0) {
						// the symbols are finished, the player wins
						GameFlow.getInstance ().ThisPlayerWinRound (idPlayer, false);
					}
					increseHalo (new Vector3 (1, 1, 1));
					Debug.Log ("Player " + idPlayer + " ha preso simbolo giusto");
					return true;
				} else {
					// il simbolo preso non corrisponde, resetto l'indice
					alreadyReadSymbolIndex = opponent.pickedUpSymbols.Count - 1;
					StartCoroutine (ImmunityRoutine ());
					resetHalo ();
					Debug.Log ("Player " + idPlayer + " ha preso simbolo sbagliato");
					return false;
				}
			}

		return true;
		}

	public void Evocation(){
		GameObject particleSystem = Instantiate(particlesEvocation, transform.position, particlesEvocation.transform.rotation) as GameObject;
		ParticleSystem[] particleSystems = particleSystem.GetComponentsInChildren<ParticleSystem> ();
		if (idPlayer == 2)
			foreach(ParticleSystem ps in particleSystems)
				ps.startColor = Color.red;
		else
			foreach(ParticleSystem ps in particleSystems)
				ps.startColor = Color.blue;
	}

	public void Spawning(){
		GameObject particleSystem = Instantiate(particlesBirth, transform.position, particlesBirth.transform.rotation) as GameObject;
		ParticleSystem[] particleSystems = particleSystem.GetComponentsInChildren<ParticleSystem> ();
		if (idPlayer == 2)
			foreach(ParticleSystem ps in particleSystems)
				ps.startColor = Color.red;
		else
			foreach(ParticleSystem ps in particleSystems)
				ps.startColor = Color.blue;

		alreadyReadSymbolIndex = -1;
		pickedUpSymbols.Clear ();

		resetHalo ();
	}

	private IEnumerator ImmunityRoutine(){
		// use shuffle animation
		float time = 0;
		
		// make the sprite flashing rapidly in sequence for some seconds
		while (time < WRONG_TIME) {
			spriteRenderer.material.color = new Color(spriteRenderer.material.color.r, spriteRenderer.material.color.g, spriteRenderer.material.color.b, 0.6f);
			yield return new WaitForSeconds (WRONG_FLASHING_SPEED);
			spriteRenderer.material.color = new Color(spriteRenderer.material.color.r, spriteRenderer.material.color.g, spriteRenderer.material.color.b, 1f);
			yield return new WaitForSeconds (WRONG_FLASHING_SPEED);
			time = time + (WRONG_FLASHING_SPEED * 2);
		}
	}

	private void increseHalo(Vector3 increase){
		Vector3 currentScale = halo.transform.localScale;
		halo.transform.localScale = new Vector3 (currentScale.x+increase.x,currentScale.y+increase.y,currentScale.z+increase.z);
	}

	private void resetHalo(){
		halo.transform.localScale = startingHalo;
	}
}
