using UnityEngine;
using System.Collections;
using XInputDotNetPure; // Required in C#

public class PlayerAttack : MonoBehaviour
{
	public enum CurrentAttackType
	{
		Punch,
		Kick,
		Special
	};

	public Transform playerObject;
	public int playerIndex;
	public int playerGameID;

	[HideInInspector]
	public tk2dUIProgressBar enduranceBar;

	[HideInInspector]
	public tk2dUIProgressBar healthBar;

	public int maxEndurence = 100;
	private int enduranceAmount = 0;
	public int enduranceIncrement = 10;

	public int maxHealth = 100;
	private int healthAmount = 0;

	public int kickEnduranceCost = 10;
	public int punchEnduranceCost = 20;
	public int specialEnduranceCost = 100;

	public int kickDamage = 25;
	public int punchDamage = 10;
	public int specialDamage = 50;

	public Color [] colours;

	[HideInInspector]
	public GameObject deathObject;

	[HideInInspector]
	public GameObject fistObject;

	[HideInInspector]
	public GameObject kickObject;

	[HideInInspector]
	public GameObject specialObject;

	public Attack forwardAttack;
	public Attack backwardAttack;
	public Attack leftAttack;
	public Attack rightAttack;

	public tk2dSprite forwardSprite;
	public tk2dSprite backwardSprite;
	public tk2dSprite leftSprite;
	public tk2dSprite rightSprite;

	public tk2dSprite forwardSpriteOutline;
	public tk2dSprite backwardSpriteOutline;
	public tk2dSprite leftSpriteOutline;
	public tk2dSprite rightSpriteOutline;

	public CurrentAttackType currentAttack;
	private CurrentAttackType lastAttack;
	public string [] attackTypeSpriteNames;

	private GamePadState state;
	private GamePadState prevState;

	private Color ownColour;

	private double lastAttackTime;
	private double lastIncrement;

	void Start () 
	{
		enduranceAmount = maxEndurence;
		healthAmount = maxHealth;

		ownColour = colours[playerGameID];
		playerObject.GetComponent<tk2dSprite>().color = ownColour;
	}

	public void TakeDamage(int damageAmount)
	{
		healthAmount -= damageAmount;

		if (healthAmount < 0)
		{
			int randomNumber = Random.Range(0, 100);

			if (randomNumber < 35)
			    AudioManager.audioManager.PlayAnnoucements(AudioManager.Announcements.Anihilated);
			else if (randomNumber < 65)
			    AudioManager.audioManager.PlayAnnoucements(AudioManager.Announcements.Defeated);
			else if (randomNumber < 85)
				AudioManager.audioManager.PlayAnnoucements(AudioManager.Announcements.Knockout);
			else
				AudioManager.audioManager.PlayAnnoucements(AudioManager.Announcements.KO);

			GameManager.playersAmount--;
			healthAmount = 0;
			deathObject.SetActive(true);
			gameObject.SetActive(false);
		}
		else
		{
			if (Random.Range (0, 100) < 85)
				AudioManager.audioManager.PlayHit();
			else
				AudioManager.audioManager.PlayAnimal();
		}
	}

	public void Hit(int enduranceAmount)
	{
		enduranceAmount -= enduranceAmount;
		
		if (enduranceAmount < 0)
		{
			enduranceAmount = 0;
		}
	}

	bool HitNormal()
	{
		if (state.Triggers.Right >= 0.9f)
		{
			if (enduranceAmount - specialEnduranceCost >= 0)
			{
				AudioManager.audioManager.PlayPunch();
				enduranceAmount -= specialEnduranceCost;
				return true;
			}
		}

		if (currentAttack == CurrentAttackType.Kick)
		{
			if (enduranceAmount - kickEnduranceCost >= 0)
			{
				AudioManager.audioManager.PlayKick();
				enduranceAmount -= kickEnduranceCost;
				return true;
			}
		}
		else if (currentAttack == CurrentAttackType.Punch)
		{
			if (enduranceAmount - punchEnduranceCost >= 0)
			{
				AudioManager.audioManager.PlayPunch();
				enduranceAmount -= punchEnduranceCost;
				return true;
			}
		}

		return false;
	}

	void ChangeAttackColour()
	{
		Color kickCol = ownColour;
		Color punchCol = ownColour;
		Color specialCol = new Color(1, 0, 0);

		switch (currentAttack)
		{
			case CurrentAttackType.Kick:
				backwardSprite.color = kickCol;
				forwardSprite.color = kickCol;
				leftSprite.color = kickCol;
				rightSprite.color = kickCol;
			break;

			case CurrentAttackType.Punch:
				backwardSprite.color = punchCol;
				forwardSprite.color = punchCol;
				leftSprite.color = punchCol;
				rightSprite.color = punchCol;
			break;

			case CurrentAttackType.Special:
				backwardSprite.color = specialCol;
				forwardSprite.color = specialCol;
				leftSprite.color = specialCol;
				rightSprite.color = specialCol;
			break;
		}
	}

	void SetAttackDamage(int dmg)
	{
		forwardAttack.currentDamage = dmg;
		backwardAttack.currentDamage = dmg;
		leftAttack.currentDamage = dmg;
		rightAttack.currentDamage = dmg;
	}
	
	void Update () 
	{
		if (GameManager.currentState == GameManager.GameStates.Game)
		{
			prevState = state;
			state = GamePad.GetState((PlayerIndex)playerIndex);

			if (prevState.Buttons.RightShoulder == ButtonState.Released && 
			    state.Buttons.RightShoulder == ButtonState.Pressed)
			{
				currentAttack = CurrentAttackType.Kick;
				lastAttack = CurrentAttackType.Kick;

				SetAttackDamage(kickDamage);

				fistObject.SetActive(false);
				kickObject.SetActive(true);
				specialObject.SetActive(false);
			}

			if (prevState.Buttons.LeftShoulder == ButtonState.Released && 
			    state.Buttons.LeftShoulder == ButtonState.Pressed)
			{
				currentAttack = CurrentAttackType.Punch;
				lastAttack = CurrentAttackType.Punch;

				SetAttackDamage(punchDamage);

				fistObject.SetActive(true);
				kickObject.SetActive(false);
				specialObject.SetActive(false);
			}

			if (state.Triggers.Right >= 0.9f)
			{
				currentAttack = CurrentAttackType.Special;

				SetAttackDamage(specialDamage);

				fistObject.SetActive(false);
				kickObject.SetActive(false);
				specialObject.SetActive(true);
			}
			else
			{
				currentAttack = lastAttack;

				fistObject.SetActive(false);
				kickObject.SetActive(false);
				specialObject.SetActive(false);

				if (currentAttack == CurrentAttackType.Kick)
				{	
					SetAttackDamage(kickDamage);
					fistObject.SetActive(true);
				}
				else
				{
					SetAttackDamage(punchDamage);
					kickObject.SetActive(true);
				}
			}

			healthBar.Value = (float)healthAmount / (float)maxHealth;
			enduranceBar.Value = (float)enduranceAmount / (float)maxEndurence;

			if (Time.time - lastIncrement > 0.1f)
			{
				lastIncrement = Time.time;

				if (enduranceAmount + enduranceIncrement > maxEndurence)
				{
					enduranceAmount = maxEndurence;
				}
				else
				{
					enduranceAmount += enduranceIncrement;
				}
			}

			if (Time.time - lastAttackTime > 0.25f)
			{
				lastAttackTime = Time.time;

				if ((state.ThumbSticks.Right.X > 0.001f || state.ThumbSticks.Right.X < -0.001f) ||
				    (state.ThumbSticks.Right.Y > 0.001f || state.ThumbSticks.Right.Y < -0.001f))
				{
					if (state.ThumbSticks.Right.X > -0.4f &&
					    state.ThumbSticks.Right.X < 0.4f)
					{
						if (state.ThumbSticks.Right.Y < 0)
						{
							if (!backwardAttack.isAttack())
							{
								if (HitNormal())
								{
									ChangeAttackColour();

									backwardSprite.SetSprite(attackTypeSpriteNames[(int)currentAttack]);
									backwardSpriteOutline.SetSprite(attackTypeSpriteNames[(int)currentAttack] + "Outline");
									backwardAttack.Activate(false, true);
								}
							}
						}
						else
						{
							if (!forwardAttack.isAttack())
							{
								if (HitNormal())
								{
									ChangeAttackColour();

									forwardSprite.SetSprite(attackTypeSpriteNames[(int)currentAttack]);
									forwardSpriteOutline.SetSprite(attackTypeSpriteNames[(int)currentAttack] + "Outline");
									forwardAttack.Activate(false, true);
								}
							}
						}
					}
					else
					{
						if (state.ThumbSticks.Right.X < 0)
						{
							if (!leftAttack.isAttack())
							{
								if (HitNormal())
								{
									ChangeAttackColour();

									leftSprite.SetSprite(attackTypeSpriteNames[(int)currentAttack]);
									leftSpriteOutline.SetSprite(attackTypeSpriteNames[(int)currentAttack] + "Outline");
									leftAttack.Activate(false, true);
								}
							}
						}
						else
						{
							if (!rightAttack.isAttack())
							{
								if (HitNormal())
								{
									ChangeAttackColour();

									rightSprite.SetSprite(attackTypeSpriteNames[(int)currentAttack]);
									rightSpriteOutline.SetSprite(attackTypeSpriteNames[(int)currentAttack] + "Outline");
									rightAttack.Activate(false, true);
								}
							}
						}
					}
		        }
			}
		}
    }
}
