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

public class RefereeBehaviour : MonoBehaviour {

	private static int START_LEVEL = 0; 					//Da quale scena(indice) iniziano i livelli
	private static int SCORE_LIFE = 500;					//Score se si acquisisce o perde una vita
	private static int SCORE_MULTIPLIER = 100;				//Score base
	private static float LEVEL_SPEED_MULTIPLIER = 1.25f;	//Moltiplicatore della velocità di gioco
	private static float CHARACTER_SPEED_MULTIPLIER = 1.05f;//Moltiplicatore della velocità del personaggio
	
	private static int numberOfCharacters = 2;
	private static List<CharacterStats> charactersStats; 	//Statistiche personaggi
	private static List<CharacterBehaviour> characters;		//GameObjects Personaggi
	private static int level = 1;							//Livello attuale
	private static float levelSpeed;						//Velocità del livello
	private static float characterSpeed;					//Velocità dei personaggi
	
	private static bool isLevelOver = false;

	private int count = 0;

	/*
	 *	Getter & Setter
	 */
	public static int Level {
		get {
			return level;
		}
	}

	public static float LevelSpeed {
		get {
			return levelSpeed;
		}
	}

	public static float CharacterSpeed {
		get {
			return characterSpeed;
		}
	}

	public static bool IsLevelOver {
		get {
			return isLevelOver;
		}

		set {
			isLevelOver = value;
		}
	}

	
	// Use this for initialization
	void Start () {
		loadCharacters();
		if (charactersStats == null) {
			createCharactersStats(numberOfCharacters);
			updateSpeed();
		}

		Debug.Log("LEVEL: "+level);
	}
	
	// Update is called once per frame
	void Update () {
//		if (count++ > 1200) {
//			isLevelOver = true;
//			count = 0;
//		}

		if (isLevelOver || (characters != null && isAllDead())) {
			Debug.Log(characters.Count);
			isLevelOver = false;
			changeLevel();
		}
	}

	/*
	 * Ritorna true se sono morti tutti nella scena, altrimenti falso
	 */
	bool isAllDead() {
		int countDead = 0;
		foreach (CharacterBehaviour c in characters) {
			if (c.State == States.KO) {
				countDead++;
			}
		}

		return countDead == characters.Count;
	}


	/*
	 * Crea le statistiche dei personaggi
	 */
	void createCharactersStats (int n) {

		numberOfCharacters = n;
		charactersStats = new List<CharacterStats>();

		for (int i = 0; i<n; i++) {
			CharacterStats c = new CharacterStats();
			charactersStats.Add(c);
		}
	}

	/*
	 * Aggiorna la velocità di gioco in base al livello
	 */
	void updateSpeed () {
		levelSpeed = level * LEVEL_SPEED_MULTIPLIER;
		characterSpeed = level * CHARACTER_SPEED_MULTIPLIER;
	}
	
	/*
	 * Aggiorna gli score dei personaggi
	 */
	void updateScore () {

		if (characters == null)
			return;

		for (int i = 0; i<characters.Count; i++) {

			CharacterBehaviour c = characters[i];
			CharacterStats cStats = charactersStats[i];

			if (c.State == States.KO) {
				cStats.updateScore(-SCORE_LIFE);
				cStats.decreaseLives();
			} else {
				cStats.updateScore(level * SCORE_MULTIPLIER);

				if (c.State == States.LIFE) {
					cStats.increaseLives();
					cStats.updateScore(SCORE_LIFE);
				}
			}
		}
	}

	/*
	 * Ritorna un indice random per selezionare la scena successiva
	 */
	int getSceneNumber() {

		if (level % 5 == 0) {
			return 3;
		}
		return level % 2 == 0?  1 : 2;
//		int sceneNumber;
//
//		do {
//			sceneNumber = Random.Range(START_LEVEL, Application.levelCount);
//		} while (lastSceneNumber == sceneNumber);
//
//		lastSceneNumber = sceneNumber;
//
//		return sceneNumber;
	}

	/*
	 * Controlla se il gioco è finito.
	 * Se è finito, ritorna true
	 */
	bool checkGameOver() {

		int deadCount = 0;
		foreach (CharacterStats c in charactersStats) {
			if (c.isDead()) {
				deadCount++;
			}
		}

		return (deadCount +1 >= charactersStats.Count);
	}

	/*
	 * Ritorna l'indice del personaggio che vince.
	 */ 
	int getWinnerCharacter() {

		foreach (CharacterStats c in charactersStats) {
			if (!c.isDead()) {
				return charactersStats.IndexOf(c);
			}
		}

		int countMax = 0;
		int max = int.MinValue;
		CharacterStats cMax = null;
		foreach (CharacterStats c in charactersStats) {
			int score = c.Score;
			if (max < score) {
				max = score;
				cMax = c;

				if (max == score) {
					countMax++;
				}
			}
		}


		if (countMax > 1) {
			return -1;
		}

		return charactersStats.IndexOf(cMax);
	}


	/*
	 * Carica i personaggi dalla scena
	 */ 
	void loadCharacters() {
		characters = new List<CharacterBehaviour>();
		for (int i = 0; i<numberOfCharacters; i++) {
			CharacterBehaviour c = (CharacterBehaviour)GameObject.Find("Player"+(i+1)).GetComponent(typeof(CharacterBehaviour));
			characters.Add(c);
			Debug.Log(c.Name);
		}
	}

	/*
	 * Nasconde i personaggi che non hanno più vite
	 */
	void hideDeadCharacters() {

		for (int i = 0; i<characters.Count; i++) {
			
			CharacterBehaviour c = characters[i];
			CharacterStats cStats = charactersStats[i];

			if (cStats.isDead()) {
				c.die();
			}
		}
	}

	/*
	 * Passa al livello successivo
	 */
	void changeLevel () {


		updateScore();

		if (checkGameOver()) {

			int index = getWinnerCharacter();
			if (index == -1) {
				print("DRAW");
			} else {
				print("Win "+ characters[index].Name);
			}
			return;
		}

		level++;

		//loadCharacters();

		Application.LoadLevel(getSceneNumber());

		//TODO:Disabilitare chi è morto
	}

	public static int getLivesOfCharacter(int n) {
		if (charactersStats != null) {

			Debug.Log(charactersStats[n].Lives);

			return charactersStats[n].Lives;
		}
		return 3;
	}
}
