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

public class GameControler : MonoBehaviour
	{

	public TrackManager trackManager;
    public WidgetManager widgetManager;
	public SoundManager soundManager;
    public InstructionDisplay instructionDisplay;
    public ErrorDisplay errorCodesDisplay;
	public SendHighScore sendHighScore;
	public EffectManager effectManager;

    public int timeToWait = 5; //time allowed to hit a button on a do now, for now use same time for all waits for player inputs
	public float timeOnCurrentPlayThrough = 0.0f;
	public int machineHealth = 100;
	public HealthBar healthBar;
	public int healthPenaltyForMissedTrack = -5;
	public int healthPenaltyForButtonMash = -1;
	public int healthIncreaseForGoodTrack = 2;
	public bool healthChanged = false;

	/*
	public GameObject healthBar = null;
	float healthBarX = 0;
	float healthBarY = 0;
	float healthBarZ = 0;
	*/

	public bool gameEnded = false;
	ParticleSystem bubbles = null;
	public GameObject BubbleParent = null;


	public int currentLevel = 1; //TODO: set in editor!!
	//public int secondsBetweenLevels = 3;
	public int trackIncreasePerLevel = 1;
	public int cogLoadPerLevel = 1;

	public int MAX_MACHINE_HEALTH = 100;
	public Dictionary<string, string> errorInstructionToCodes = new Dictionary<string, string>();


	void Start()
	{
        errorInstructionToCodes.Add("When green light is on, set big dial to 4", "256");
		errorInstructionToCodes.Add("Press red button, then set red slider to 4.", "404");
		errorInstructionToCodes.Add("Set big dial to 1 NOW", ":-)");
		errorInstructionToCodes.Add("Flip left-side switch, then flip right-side switch.", ">:(");
		errorInstructionToCodes.Add("Set green slider to 3 NOW", "3-D");
		errorInstructionToCodes.Add("Press blue button, then press red button", "911");
		errorInstructionToCodes.Add("Set blue slider to 5 NOW", "711");
		errorInstructionToCodes.Add("Set green slider to 4 NOW", "411");
        errorInstructionToCodes.Add("Set purple slider to 5 NOW", "HOC");
        errorInstructionToCodes.Add("Set red slider to 5 NOW", "FOO");
        errorInstructionToCodes.Add("Set green slider to 5 NOW", "BAS");
        errorInstructionToCodes.Add("Set red slider to 2 NOW", "TBA");
        errorInstructionToCodes.Add("Set green slider to 2 NOW", "EBA");
        errorInstructionToCodes.Add("Set purple slider to 4 NOW", "KEY");
		errorInstructionToCodes.Add("Flip right-side switch, then flip left-side switch", "POP");
		errorInstructionToCodes.Add("When purple light is ON, press purple button", "TRT");
		errorInstructionToCodes.Add("Press red button, then press yellow button", "OJ");
		errorInstructionToCodes.Add("Press yellow button, then press red button", "PZA");
        errorInstructionToCodes.Add("Set big dial to 4 NOW", "SUB");
        errorInstructionToCodes.Add("Press green button NOW", "WOA");
		errorInstructionToCodes.Add("When red light is ON, press red button", "QED");
        


        Debug.Log("GameControl.Start()");
		/*
		healthBarX = healthBar.transform.position.x;
		healthBarY = healthBar.transform.position.y;
		healthBarZ = healthBar.transform.position.z;
		*/
		bubbles = BubbleParent.GetComponent<ParticleSystem>();
	}

	public void changeLevel()
	{
		//Debug.Log("GameControler Level up to " + Mathf.FloorToInt(timeOnCurrentPlayThrough / secondsBetweenLevels));
        currentLevel++; // Mathf.FloorToInt(timeOnCurrentPlayThrough / secondsBetweenLevels);
	}

	void Update()
	{
		timeOnCurrentPlayThrough += Time.deltaTime;

	}

    public void reportTrackSuccess(bool success, Track someTrack)
    {
        //Debug.Log("Track Success is " + success);
        
        if (!success)
        {
			changeHealth(healthPenaltyForMissedTrack);
        } else {
            this.changeLevel();

            emitBubbles(currentLevel);

            
            // if instructions for this track are still on display, make them go away
            instructionDisplay.clearTextIfMatching(someTrack.getInstruction());
			changeHealth(healthIncreaseForGoodTrack);

		}
    }

	public void emitBubbles(int num)
	{
		// show bubbles!
		bubbles.Emit(num);
	}

    public void reportInvalidWidgetUse()
    {
        //Debug.Log("Invalid Widget Use");
		changeHealth(healthPenaltyForButtonMash);

    }



    public void changeHealth(int change)
    {
        machineHealth += change;
        machineHealth = Math.Min(machineHealth, MAX_MACHINE_HEALTH);        
		healthBar.setHealth(machineHealth);

		float healthPercentage = (float)machineHealth / (float)MAX_MACHINE_HEALTH * 100;
		//Debug.Log ("New health %: " + healthPercentage);
        
        if (change < 0)
            effectManager.shake(0.4f, 0.3f);

		if (healthPercentage > 90)
			soundManager.setCurrentEscalation(0);
		else if (healthPercentage > 80)
			soundManager.setCurrentEscalation(1);
		else if (healthPercentage > 60)
			soundManager.setCurrentEscalation(2);
		else if (healthPercentage > 40)
			soundManager.setCurrentEscalation(3);
		else if (healthPercentage > 20)
			soundManager.setCurrentEscalation(4);

        // Check for death
        if (machineHealth <= 0)
        {
            gameOver();
        }
    }

	/*
	 * Game Over
	 */
	void gameOver()
		{
		if(gameEnded)
			return;
		effectManager.shake( 3 , 1 );
		gameEnded = true;
		Debug.Log ("Game Over");
		StartCoroutine( delayed_highScore() );
		}

	IEnumerator delayed_highScore()
		{
		yield return new WaitForSeconds(3.0f);
		sendHighScore.activateAndSetScore( (int)(timeOnCurrentPlayThrough) );
		}


}
