using UnityEngine;
using System.Collections;

public class ScoreManager : MonoBehaviour {
	private static ScoreManager instance; 

	public bool __Trick = false;
	public bool __Fail = false;

	public float score = 0;

	public int trick_multiplier = 1;
	public float trick_timeMultiplier = 0;

	public bool trick_active = false;
	public float trick_timeScore = 0;
	public float trick_totalScore = 0;
	public string trick_name = "";
	public Color trick_successColor;
	public Color trick_failColor;

	public float trick_duration = 0;

	public float trick_displayCooldown = 0;
	public float trick_maxDisplayCooldown = 1.5f;

	public float pulse_cooldown = 0;
	public float pulse_maxCooldown = 0.5f;

	public float pulse_maxSize;
	public float pulse_currentSize;

	public Rect trickDisplayRect;
	public GUIStyle trickDisplayStyle;
	private int _trickDisplayStyle_originalFontSize;

	public Rect scoreRect;
	public GUIStyle scoreStyle;

	public AudioClip successSound;
	public AudioClip failSound;

	// Use this for initialization
	void Awake () {
		instance = this;
	}

	void Start()
	{
		_trickDisplayStyle_originalFontSize = trickDisplayStyle.fontSize;
	}
	
	// Update is called once per frame
	void Update () 
	{
		scoreRect.width = Screen.width;
		
		int clearanceFromBottomOfScreen = Mathf.CeilToInt(trickDisplayStyle.fontSize + pulse_maxSize);
		
		trickDisplayRect.y = Screen.height - clearanceFromBottomOfScreen;
		trickDisplayRect.width = Screen.width;


		if (__Trick) {
			NewTrick(trick_name,trick_timeScore);
			__Trick = false;
		}
		if (__Fail) {
			FailTrick();
			__Fail = false;
		}

		pulse_cooldown = Mathf.Max(0,pulse_cooldown - Time.deltaTime);
		pulse_currentSize = (pulse_maxSize * ((pulse_cooldown / pulse_maxCooldown)));
		trickDisplayStyle.fontSize = Mathf.RoundToInt (_trickDisplayStyle_originalFontSize + pulse_currentSize);

		if (trick_active) {

			trick_duration += Time.deltaTime;
			trick_totalScore += trick_timeMultiplier * Time.deltaTime * trick_timeScore;
		} 
		else 
		{
			// Check to see if the trick has timed-out.
			// If so, reset everything and apply scores.
			trick_displayCooldown = Mathf.Max (0,trick_displayCooldown - Time.deltaTime);
			if (trick_displayCooldown <= 0) {
				_EndTrick ();
			}
		}
	}
	private void _FailTrick()
	{
		trick_totalScore *= trick_multiplier; 

		// Reset Trick Duration
		trick_duration = 0;

		trick_multiplier = 0;
		trick_timeMultiplier = 0;
		trickDisplayStyle.normal.textColor = instance.trick_failColor;
		trick_active = false;

		AudioSource.PlayClipAtPoint (failSound, Player.position);
	}
	private void _EndTrick()
	{
		// Score
		score += trick_totalScore * trick_multiplier;

		// Reset Multiplier
		if (trick_displayCooldown > 0) {
			trick_multiplier ++;
		} else {
			trick_multiplier = 1;
		}
		trick_active = false;

		// Unset Trick Values
		trick_timeScore = 0;
		trick_totalScore = 0;

		// Reset Trick Duration
		trick_duration = 0;
	}

	public static void NewTrick(string s, float baseScore, float timeScore = 0, float timeMultiplier = 0)
	{
		if (!instance)
			return;
		instance._EndTrick ();
		instance.trick_name = s;
		instance.trick_totalScore = baseScore;
		instance.trick_timeScore = timeScore;
		instance.trick_timeMultiplier = timeMultiplier;
		instance.trick_active = true;
		instance.trickDisplayStyle.normal.textColor = instance.trick_successColor;

		RefreshPulse ();
		RefreshTrickDisplay ();
		AudioSource.PlayClipAtPoint (instance.successSound, Player.position);
	}

	// Refresh Display Duration of Trick.
	public static void RefreshTrickDisplay()
	{
		instance.trick_displayCooldown = instance.trick_maxDisplayCooldown;
	}

	// Refresh Pulse of Trick.
	public static void RefreshPulse()
	{
		instance.trick_displayCooldown = instance.trick_maxDisplayCooldown;
		instance.pulse_cooldown = instance.pulse_maxCooldown;
	}

	// For special tricks that use their own internal metrics for scoring. Manually set trick score.
	public static void SetTrickScore(float score)
	{
		instance.trick_totalScore = score;
	}

	public static void SetTrickName(string name)
	{
		instance.trick_name = name;
	}

	// For Timed Tricks. End the trick.
	public static void EndTrick()
	{
		instance.trick_active = false;
		instance.trick_timeMultiplier = 0;
		RefreshPulse ();
		RefreshTrickDisplay ();
	}

	// For any trick. Kill it.
	public static void FailTrick()
	{
		instance._FailTrick ();
		RefreshPulse ();
		RefreshTrickDisplay ();
	}

	void OnGUI() {
		if (score > 0)
			GUI.Label(scoreRect,"Score: " + score.ToString("F0"),scoreStyle);

		if (trick_displayCooldown > 0) {
			GUI.Label (trickDisplayRect,
					trick_name + "\n" +
				trick_totalScore.ToString ("F0") + "x" + trick_multiplier.ToString ("F0"),
		          	trickDisplayStyle);
		}
	}
}
