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


public class GameController : MonoBehaviour {
	enum state{MENU, GAME, GAMEOVER, SELECT};
	public AudioClip m_win, m_defaultMusic, m_darkMusic;
	public GameObject m_monsterOne, m_monsterTwo, m_monsterThree;
	public GameObject m_R1, m_R2, m_R3, m_R4;
	private AudioSource m_winSrc, m_defaultMusicSrc, m_darkMusicSrc;
	private float m_lightFactor = 1.0f, m_lastText;
	private bool m_spawnEnemy = false;
	private state m_showState = state.MENU;
	private Canvas m_canvas;
	private Text m_text;
	private SpriteRenderer m_startScreen;
	private Canvas m_select, m_gameOver;
	private List<GameObject> m_objs = new List<GameObject> ();
	private List<string> m_encourage = new List<string> () {"Use your best judgement", "You can do it", "I believe in you", "Use bash", "I love you", "Go for it"};
	private List<string> m_hate = new List<string> () {"I don't care about you...", "Do you expect me to care?", "Kill it.", "...", "Pff. that's just a scratch.", "Who cares about wounds? Kill.",
			"Don't you like hurting things?", "Haha, it is going to die."};

	// Use this for initialization
	void Start () {
		m_canvas = GameObject.FindWithTag("overlay").GetComponent<Canvas>();
		m_startScreen = GameObject.FindWithTag ("startscreen").GetComponent<SpriteRenderer> ();
		m_text = GameObject.FindWithTag ("comment").GetComponent<Text> ();
		m_select = GameObject.FindWithTag ("select").GetComponent<Canvas> ();
		m_gameOver = GameObject.FindWithTag ("gameover").GetComponent<Canvas> ();
		m_winSrc = gameObject.AddComponent<AudioSource> ();
		m_winSrc.clip = m_win;
		m_defaultMusicSrc = gameObject.AddComponent<AudioSource> ();
		m_defaultMusicSrc.clip = m_defaultMusic;
		m_darkMusicSrc = gameObject.AddComponent<AudioSource> ();
		m_darkMusicSrc.clip = m_darkMusic;

		m_darkMusicSrc.loop = true;
		m_defaultMusicSrc.loop = true;
		reset ();
	}

	void FixedUpdate() {
		if (m_winSrc.time > 3 || !m_winSrc.isPlaying) {
			m_defaultMusicSrc.volume = Mathf.Min (m_defaultMusicSrc.volume + Time.deltaTime / 7f, m_lightFactor);
			m_darkMusicSrc.volume = Mathf.Min (m_darkMusicSrc.volume + Time.deltaTime / 7f, Mathf.Pow (1.0f - m_lightFactor, 2.0f));
		} else {
			m_defaultMusicSrc.volume = Mathf.Max(Mathf.Min (0.1f, m_lightFactor), m_defaultMusicSrc.volume - Time.deltaTime);
		}
		if (!m_winSrc.isPlaying && m_spawnEnemy) {
			spawnEnemy();
			m_spawnEnemy = false;
		}
		if (m_showState == state.GAME) {
			m_lastText -= Time.deltaTime;
			if (m_lastText < 0) {
				m_lastText = HelperFunctions.getScaledRandom(7, 10);
				if (0.5 > m_lightFactor) {
					m_text.text = m_hate[(int) HelperFunctions.getScaledRandom(0f, m_hate.Count - 0.01f)];
				} else {
					m_text.text = m_encourage[(int) HelperFunctions.getScaledRandom(0f, m_encourage.Count - 0.01f)] + "!";
				}
			}
		}
	}

	public void reset() {
		m_spawnEnemy = false;
		m_lightFactor = 1.0f;
		m_darkMusicSrc.volume = 0.0f;
		m_lastText = -1f;
		m_defaultMusicSrc.Stop ();
		m_darkMusicSrc.Stop ();
		m_defaultMusicSrc.Play ();
		m_darkMusicSrc.Play ();
		m_showState = state.MENU;
		m_text.text = "";
		foreach (GameObject obj in m_objs) {
			GameObject.Destroy(obj);
		}
		m_objs.Clear ();
	}

	public void registerWin(Vector2 victim) {
		m_winSrc.Play ();
		m_lightFactor = Mathf.Max (0, m_lightFactor - 0.1f);
		if (m_lightFactor < 0.31) {
			int bits = (int) HelperFunctions.getScaledRandom(5 - m_lightFactor*10, 10 - m_lightFactor * 10);
			for (int i = 0; i < bits; i++) {
				double bit = HelperFunctions.getScaledRandom(0f, 0.99f);
				Vector2 pos = victim + new Vector2(HelperFunctions.getScaledRandom(-1, 1), HelperFunctions.getScaledRandom(-1,1));
				if (bit < 0.25) {
					Instantiate (m_R1, pos, Quaternion.identity);
				} else  if (bit < 0.5) {
					Instantiate (m_R2, pos, Quaternion.identity);
				} else  if (bit < 0.75) {
					Instantiate (m_R3, pos, Quaternion.identity);
				} else {
					Instantiate (m_R4, pos, Quaternion.identity);
				}
			}
		}
	}

	void startGame(GameObject mon) {
		if (m_showState != state.SELECT) {
			return;
		}
		m_showState = state.GAME;
		GameObject obj = Instantiate (mon, new Vector2 (-9, 4), Quaternion.identity) as GameObject;
		m_objs.Add (obj);
		Player pl = obj.AddComponent<Player> ();
		pl.m_level = 3;
		pl.tag = "Player";

		spawnEnemy ();
	}

	public void startCharlog() {
		startGame (m_monsterOne);
	}

	public void startSquirtop() {
		startGame (m_monsterTwo);
	}

	public void startBulba() {
		startGame (m_monsterThree);
	}

	public void queueEnemy() {
		m_spawnEnemy = true;
	}

	public void spawnEnemy() {
		GameObject mon;
		double choice = Rand.r.NextDouble ();
		if (choice < 0.33) {
			mon = m_monsterOne;
		} else if (choice < 0.66) {
			mon = m_monsterTwo;
		} else {
			mon = m_monsterThree;
		}
		GameObject obj = Instantiate (mon, new Vector2(9,4), Quaternion.identity) as GameObject;
		m_objs.Add (obj);
		Enemy en = obj.AddComponent<Enemy> ();
		en.tag = "Enemy";
		en.m_noobify = m_lightFactor;
		en.m_level = Mathf.Max(1, (int) (GameObject.FindWithTag ("Player").GetComponent<Player> ().m_level + (-1.0 - (2.0 * m_lightFactor)) * HelperFunctions.getScaledRandom (1f, 2.99f)));
		en.resetHealth ();
	}

	public void gameOver() {
		m_showState = state.GAMEOVER;
		foreach (GameObject obj in m_objs) {
			GameObject.Destroy(obj);
		}
		m_objs.Clear ();
		m_lightFactor = 0.0f;
	}

	void Update() {
		if (Input.GetKeyDown(KeyCode.Escape)) {
			reset ();
		}
		if (m_showState == state.MENU) {
			m_canvas.enabled = false;
			m_select.enabled = false;
			m_startScreen.enabled = true;
			m_gameOver.enabled = false;
			if (Input.GetMouseButtonDown(0)) {
				m_showState = state.SELECT;
			}
		} else if (m_showState == state.GAME) {
			m_canvas.enabled = true;
			m_startScreen.enabled = false;
			m_select.enabled = false;
			m_gameOver.enabled = false;

		} else if (m_showState == state.GAMEOVER) {
			m_canvas.enabled = false;
			m_startScreen.enabled = false;
			m_select.enabled = false;
			m_gameOver.enabled = true;
			if (Input.GetMouseButtonDown(0)) {
				reset();
			}
		} else if (m_showState == state.SELECT) {
			m_canvas.enabled = false;
			m_startScreen.enabled = false;
			m_select.enabled = true;
			m_gameOver.enabled = false;
		}
	}
}
