using UnityEngine;
//using UnityEngine.SceneManagement;
using System;
using System.Collections;
using System.Collections.Generic;

/* GameManager: manages all game mechanics, singleton, always available in scene */
public class GameManager : MonoBehaviour {

	public enum GameState { InRitual, WaitingForRitual, GameOverWow, GameOverNoAdepts, Intro,
		InRitual_Sacrifice, FinishingRitual};

	public delegate void ChangeStateAction();

	public event ChangeStateAction OnStartPlaying;
	public event ChangeStateAction OnRitualBegin;
	public event ChangeStateAction OnRitualBegin_Sacrifice;
	public event ChangeStateAction OnRitualEnd;
	public event ChangeStateAction OnGameOverWow;
	public event ChangeStateAction OnGameOverAdepts;

	// Game state
	public GameState currentState = GameState.Intro;

	// Population
	public int startingAdepts = 6;
	List<Adept> population;

	// Time
	[HideInInspector]
	public float elapsedTime;
	float startTime;

	// WowBar
	[HideInInspector]
	public float wowBarValue; 

	public float wowBarStartValue = 1f;

	float wowBarSpeed;
	public float wowSpeedExponent = 1.1f;
	public float wowTimeBeforeExplosion = 100f;


	bool wowBarPaused = false;
	public void PauseWowBar(){
		wowBarPaused = true;
	}
	public void ResumeWowBar(){
		wowBarPaused = false;
	}

	// Static Stuff

	// Auto-Instantiatiation

	static GameManager _instance;

	static public GameManager instance {
		// using lazy instantiation here... 
		get{
			return _instance;
		}
	}

	void Awake(){
		this.currentState = GameState.Intro;
		_instance = this;
	}

	void Start () {
		// During the INTRO we spawmn initial adepts
		startTime = Time.time;
		for(int i = 0; i < startingAdepts; i++){
			AdeptFactory.instance.CreateAdept();
		}
		wowBarValue = 1f;
		// Adding Basic GameOver handlers
		OnGameOverWow += OnGameOverWowHandler;
		OnGameOverAdepts += OnGameOverAdeptsHandler;
	}
	
	void Update () {
		elapsedTime = Time.time - startTime;

		// update wow bar value over time
		// TODO: maybe pause the elaped time TOO???
		if (!wowBarPaused){
			wowBarSpeed = Mathf.Pow(elapsedTime, wowSpeedExponent) / wowTimeBeforeExplosion;
			ModifyWow(-1 * wowBarSpeed * Time.deltaTime);
			//wowBarValue -= wowBarSpeed * Time.deltaTime; 		//s = s0 + v*t
		}

	}

	// Public Stuff

	// StateChange
	public void StartPlaying(){
		currentState = GameState.WaitingForRitual;
		if(OnStartPlaying != null) OnStartPlaying();
	}

	public void EnterRitual(){
		currentState = GameState.InRitual;
		if(OnRitualBegin != null) OnRitualBegin();
	}
	public void EnterRitual_Sacrifice(){
		currentState = GameState.InRitual_Sacrifice;
		if(OnRitualBegin_Sacrifice != null) OnRitualBegin_Sacrifice();
	}


	public void ExitRitual(){
		currentState = GameState.WaitingForRitual;
		if(OnRitualEnd != null) OnRitualEnd();
	}

	public void GameOverWow(){
		currentState = GameState.GameOverWow;
		if(OnGameOverWow != null) OnGameOverWow();
	}

	public void GameOverNoAdepts(){
		currentState = GameState.GameOverNoAdepts;
		if(OnGameOverAdepts != null) OnGameOverAdepts();
	}

	// Population
	public void CheckAdepts(){
		if(AdeptFactory.instance.GetAliveAdepts() <= 0){
			OnGameOverAdepts();
		}
	}

	// WowBar
	public void ModifyWow(float wow){
		wowBarValue = Mathf.Clamp((wowBarValue + wow), 0, 1);
		if(wowBarValue <= 0 && !currentState.Equals(GameState.GameOverWow)){
			GameOverWow();
		}
	}

	// Events Handler

	void OnGameOverWowHandler(){
		// TODO
		//Debug.Log("TODO: Handle GameOver for low WOW, exiting");
		Application.LoadLevel("GameOver");
	}

	void OnGameOverAdeptsHandler(){
		// TODO
		//Debug.Log("TODO: Handle GameOver for low adepts, exiting");
		Application.LoadLevel("GameOver");
	}
}
