using UnityEngine;
using System.Collections;

using System.Collections.Generic;

public class RitualManager : MonoBehaviour {

	public static RitualManager instance;

	public LanceTween lanceTweenInstance;

	public Ritual sacrificeRitual;
	public Ritual fertRitual;
	public Ritual divineRitual;
	public Ritual fireRitual;
	public Ritual rainRitual;

	public Ritual currentRitual = null;

	public delegate void EndRitualAction();
	public event EndRitualAction OnEndRitual;

	public delegate void RitualResult();
	public event RitualResult OnGoodRitual;
	public event RitualResult OnBadRitual;


	void Awake()
	{
		instance = this;
	}

	void Start()
	{
		lanceTweenInstance = LanceTween.instance;
	}


	List<Adept> selectedAdepts = new List<Adept>();

	public void AddSelectedAdept(Adept a){
		selectedAdepts.Add (a);
	}

	public void TriggerSacrifice()
	{
		Debug.Log ("CHOSEN RITUAL SACRIFICE");
		TriggerRitual(sacrificeRitual);
	}
	public void TriggerFertility(){
		Debug.Log ("CHOSEN RITUAL FERTILITY");
		TriggerRitual(fertRitual);
	}
	public void TriggerDivine(){
		Debug.Log ("CHOSEN RITUAL DIVINE");
		TriggerRitual(divineRitual);
	}
	public void TriggerFire(){
		Debug.Log ("CHOSEN RITUAL FIRE");
		TriggerRitual(fireRitual);
	}
	public void TriggerRain(){
		Debug.Log ("CHOSEN RITUAL RAIN");
		TriggerRitual(rainRitual);
	}

	public void TriggerRitual(Ritual ritual){
		Debug.Log ("TRIGGER RITUAL");
		if (GameManager.instance.currentState == GameManager.GameState.WaitingForRitual) {
			Debug.Log ("STATE: " + GameManager.instance.currentState);
			if (ritual != null) {
				Debug.Log ("RITUAL NON NULL");

				selectedAdepts.Clear ();

				this.currentRitual = ritual;

				MusicController.instance.PlayTribal ();

				Debug.Log ("START A RITUAL");

				foreach (var adept in FindObjectsOfType<Adept>())
					adept.StopRandomSpeed ();

				if (ritual.difficulty > 1) {
					Debug.Log ("Classic RITUAL");
					Ellipse.instance.speed = 0.01f;

					foreach (var adept in FindObjectsOfType<Adept>())
						adept.StartDancing ();

					MinigameManager.instance.SpawnSequence (ritual.difficulty);
					GameManager.instance.EnterRitual ();
				} else {
					Debug.Log ("Sacrifice RITUAL");
					Ellipse.instance.speed = 0f;
					Ellipse.instance.StopSkewNoise ();
					//Ellipse.instance.s

					MinigameManager.instance.SendFakeSequence ();
					var adepts = FindObjectsOfType<Adept> ();
					foreach (var adept in adepts)
						adept.Animate ("Scared");
					
					GameManager.instance.EnterRitual_Sacrifice ();
				} 
			} else {
				Debug.LogError ("RITUAL IS NULL!");
			}
		}
	} 

	void CompleteShared (){
		MinigameManager.instance.StopTimer ();

		// Pause the adepts
		foreach (var adept in FindObjectsOfType<Adept>())
			adept.StopDancing ();
		Ellipse.instance.speed = 0f;

		MusicController.instance.PlayMurmur ();

		// PAUSE THE BAR
		GameManager.instance.PauseWowBar();

		GameManager.instance.currentState = GameManager.GameState.FinishingRitual;
	}
	public void CompleteRitual_Dance(){
		CompleteShared ();
		Invoke ("TriggerCompleteRitualEffects", 1f);
	}

	void TriggerCompleteRitualEffects(){
		// We now get the effects
		//if(GameManager.instance.currentState == GameManager.GameState.InRitual) {
		bool hasWon = currentRitual.CheckResult (selectedAdepts.ToArray ());

		foreach (var adept in FindObjectsOfType<Adept>())
			adept.maskSr.color = Color.white;

		if (hasWon) {
			if (OnGoodRitual != null)
				OnGoodRitual ();
		} else {
			if (OnBadRitual != null)
				OnBadRitual ();
		}
		
		if (hasWon)
			StartCoroutine (GoodEffectCO ());
		else
			FinalizeRitual (hasWon);
		//}
	}
	IEnumerator GoodEffectCO(){
		Debug.Log ("PLAYING EFFECT RITUAL");

		yield return currentRitual.StartCoroutine (currentRitual.RitualEffectCO ());
		FinalizeRitual (true);
	}

	public void CompleteRitual_TimeOut(){
		currentRitual.TriggerLosing ();

		CompleteShared ();
		FinalizeRitual (won:false);
	}

	void FinalizeRitual(bool won = false){
		Debug.Log ("FINALIZING RITUAL!");

		GameManager.instance.ExitRitual ();

		if (won) {
			foreach (var adept in FindObjectsOfType<Adept>())
				adept.Animate ("Awe");
			SfxController.instance.PlaySound ("effect_ooooh");
		} else { 
			foreach (var adept in FindObjectsOfType<Adept>())
				adept.Animate ("Fire");
			SfxController.instance.PlaySound ("effect_hmm");
		}

		// Resume the game after a little while
		Invoke ("ResumeGame", 2f);
	}
	void ResumeGame(){
		// Resume the bar after a little while
		GameManager.instance.ResumeWowBar();

		Ellipse.instance.speed = 0.005f;
		Ellipse.instance.StartSkewNoise ();

		foreach (var adept in FindObjectsOfType<Adept>())
			adept.Animate ("Walk");

		foreach (var adept in FindObjectsOfType<Adept>())
			adept.StartRandomSpeed ();
		
		if (OnEndRitual != null)
			OnEndRitual ();
	}

}
