using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class PlayerControl : MonoBehaviour		// God-class-y. No time to un-God it.
{
	#region Editor-type junk.
	public GameObject masterObject;
	private EnemyGenerator enemyGenerator;
	public Transform mainCamera;
	public GameObject bulletCubeOrange;
	private GameObject playerGun;
	public GameObject revolverSprite;
	public GameObject shotgunSprite;
	public Font customFont;
	public Texture heartTexture;
	public Texture bulletTexture;
	public Texture shellTexture;
	public Texture bullhornTexture;
	public Texture skullTexture;
	public Texture skullEmptyTexture;
	public Texture handcuffsTexture;
	public Texture handcuffsEmptyTexture;
	public Texture keyOverlayTexture;
	public Texture blackDotTexture;
	// Audio.
	public AudioClip footstepLight1;
	public AudioClip footstepLight2;
	public AudioClip footstepLight3;
	public AudioClip footstepLight4;
	public AudioClip revolverSfx;
	public AudioClip revolverClickSfx;
	public AudioClip shotgunSfx1;
	public AudioClip shotgunSfx2;
	public AudioClip shotgunSfx3;
	public AudioClip shotgunClickSfx;
	public AudioClip bulletDropSfx;
	public AudioClip bulletImpactSfx1;
	public AudioClip bulletImpactSfx2;
	public AudioClip bulletImpactSfx3;
	public AudioClip bullhornSfx;
	public AudioClip deathSfx;
	#endregion
	#region Enums
	public enum Direction
	{
		North,
		South,
		East,
		West
	};
	public enum GunType
	{
		Revolver = 0,
		Shotgun = 1
	};
	public enum PlayerInput
	{
		Null,
		Bullhorn,
		Sprint,
		Fire,
		Law,
		Arrest,
		Forward,
		Backward,
		Left,
		Right
	};
	#endregion
	#region Stats/Skills/Weapons
	public int level;// = 1;
	public int turn;// = 0;
	public GunType gunType;// = 0;
	public int currentHealth;// = 6;
	public int maxHealth;// = 6;
	public int currentActionPoints;// = 1;
	public int maxActionPoints;// = 1;
	public int currentAmmo;// = 6;
	public int maxAmmo;// = 6;
	public int damage;// = 3;
	public int currentBullhorns;// = 2;
	public int maxBullhorns;// = 6;
	public int voiceStat;// = 0;
	public int totalKills;// = 0;
	public int totalArrests;// = 0;
	#endregion
	#region Position and Gameplay data.
	public Direction playerFacing;
	public int xIndex;
	public int yIndex;
	private int lastTotalKills = 0;
	private int lastTotalArrests = 0;
	private int killsPerBullhorn = 3;
	private bool isKillsFilled = false;
	private int arrestsPerHealthRefill = 3;
	private bool isArrestsFilled = false;
	private int bullhornChainAmmo = 2;
	private bool isPlayerDead = false;
	private PlayerInput lastValidInput;
	private float deathFadeTime = 4.0f;
	private float alphaFadeValue = 0.0f;
	private bool isTheLaw = false;
	public bool isPenetratingShot = false;
	public string lastLogMessage = "";
	private bool canTakeAxisInput = true;		// For axis controls requiring input locking.
	public bool gameWon = false;
	#endregion
	void Start ()
	{
		lastValidInput = PlayerInput.Null;
		loadPlayerData();
		switch (gunType)		// Need to split this crap into another class.
		{
			case GunType.Revolver:
				playerGun = revolverSprite;
				break;
			case GunType.Shotgun:
				playerGun = shotgunSprite;
				break;
		}
		playerFacing = Direction.South;
		xIndex = 0;
		yIndex = 1;
		enemyGenerator = masterObject.GetComponent<EnemyGenerator>();
	}
	void Update ()
	{
		// Dead players can't do shit in roguelikes.
		if (isPlayerDead)
		{
			return;
		}
		// Reset axis inputs.
		if (Input.GetAxis("ForwardBackwardAxis") == 0.0f	&&
			Input.GetAxis("LeftRightAxis")		 == 0.0f)
		{
			canTakeAxisInput = true;
		}
		// Player inputs.
		if ((Input.GetButtonDown("Forward")		||
			 Input.GetAxis("ForwardBackwardAxis") > 0.0f)	&&
			currentActionPoints > 0							&&
			canTakeAxisInput)
		{
			canTakeAxisInput = false;
			switch (playerFacing)
			{
				case Direction.North:
					if (yIndex - 1 >= 0	&&
						DungeonGenerator.mazeRoom[xIndex, yIndex - 1] == (int)DungeonGenerator.TileType.Floor	&&
						enemyGenerator.isTileClearOfUnits(xIndex, yIndex - 1))
					{
						setTilePosition(xIndex, yIndex - 1);
					}
					break;
				case Direction.South:
					if (yIndex + 1 < DungeonGenerator.maxDimension	&&
						DungeonGenerator.mazeRoom[xIndex, yIndex + 1] == (int)DungeonGenerator.TileType.Floor	&&
						enemyGenerator.isTileClearOfUnits(xIndex, yIndex + 1))
					{
						setTilePosition(xIndex, yIndex + 1);
					}
					break;
				case Direction.East:
					if (xIndex - 1 >= 0	&&
						DungeonGenerator.mazeRoom[xIndex - 1, yIndex] == (int)DungeonGenerator.TileType.Floor	&&
						enemyGenerator.isTileClearOfUnits(xIndex - 1, yIndex))
					{
						setTilePosition(xIndex - 1, yIndex);
					}
					break;
				case Direction.West:
					if (xIndex + 1 < DungeonGenerator.maxDimension	&&
						DungeonGenerator.mazeRoom[xIndex + 1, yIndex] == (int)DungeonGenerator.TileType.Floor	&&
						enemyGenerator.isTileClearOfUnits(xIndex + 1, yIndex))
					{
						setTilePosition(xIndex + 1, yIndex);
					}
					break;
			}
			audio.PlayOneShot(getRandomFootstepLightSFX());
			lastValidInput = PlayerInput.Forward;
			checkEndTurn();
			setLastLogMessage("You move forward.");
		}
		if ((Input.GetButtonDown("Backward")	||
			 Input.GetAxis("ForwardBackwardAxis") < 0.0f)	&&
			currentActionPoints > 0							&&
			canTakeAxisInput)
		{
			canTakeAxisInput = false;
			switch (playerFacing)
			{
				case Direction.North:
					if (yIndex + 1 < DungeonGenerator.maxDimension	&&
						DungeonGenerator.mazeRoom[xIndex, yIndex + 1] == (int)DungeonGenerator.TileType.Floor	&&
						enemyGenerator.isTileClearOfUnits(xIndex, yIndex + 1))
					{
						setTilePosition(xIndex, yIndex + 1);
					}
					break;
				case Direction.South:
					if (yIndex - 1 >= 0	&&
						DungeonGenerator.mazeRoom[xIndex, yIndex - 1] == (int)DungeonGenerator.TileType.Floor	&&
						enemyGenerator.isTileClearOfUnits(xIndex, yIndex - 1))
					{
						setTilePosition(xIndex, yIndex - 1);
					}
					break;
				case Direction.East:
					if (xIndex + 1 >= 0	&&
						DungeonGenerator.mazeRoom[xIndex + 1, yIndex] == (int)DungeonGenerator.TileType.Floor	&&
						enemyGenerator.isTileClearOfUnits(xIndex + 1, yIndex))
					{
						setTilePosition(xIndex + 1, yIndex);
					}
					break;
				case Direction.West:
					if (xIndex - 1 < DungeonGenerator.maxDimension	&&
						DungeonGenerator.mazeRoom[xIndex - 1, yIndex] == (int)DungeonGenerator.TileType.Floor	&&
						enemyGenerator.isTileClearOfUnits(xIndex - 1, yIndex))
					{
						setTilePosition(xIndex - 1, yIndex);
					}
					break;
			}
			if (lastValidInput == PlayerInput.Bullhorn)	// Bullhorn -> Backward chains ammo!
			{//Debug.Log("<color=yellow>AMMO CHAIN!</color>");
				if (currentAmmo <= maxAmmo - 1)
				{
					currentAmmo += bullhornChainAmmo;
				}
				else
				{
					currentAmmo = maxAmmo;
				}
				audio.PlayOneShot(bulletDropSfx);
				setLastLogMessage("You move backward and find something shiny!");
			}
			else
			{
				audio.PlayOneShot(getRandomFootstepLightSFX());
				setLastLogMessage("You move backward.");
			}
			lastValidInput = PlayerInput.Backward;
			checkEndTurn();
		}
		if ((Input.GetButtonDown("Right")	||
			 Input.GetAxis("LeftRightAxis") > 0.0f)	&&
			canTakeAxisInput)
		{
			canTakeAxisInput = false;
			switch (playerFacing)
			{
				case Direction.North:
					setFacing(Direction.East);
					break;
				case Direction.South:
					setFacing(Direction.West);
					break;
				case Direction.East:
					setFacing(Direction.South);
					break;
				case Direction.West:
					setFacing(Direction.North);
					break;
			}
			lastValidInput = PlayerInput.Right;
			setLastLogMessage("You turn right.");
			setTilePosition(xIndex, yIndex);
			audio.PlayOneShot(getRandomFootstepLightSFX());
		}
		if ((Input.GetButtonDown("Left")	||
			 Input.GetAxis("LeftRightAxis") < 0.0f)	&&
			canTakeAxisInput)
		{
			canTakeAxisInput = false;
			switch (playerFacing)
			{
				case Direction.North:
					setFacing(Direction.West);
					break;
				case Direction.South:
					setFacing(Direction.East);
					break;
				case Direction.East:
					setFacing(Direction.North);
					break;
				case Direction.West:
					setFacing(Direction.South);
					break;
			}
			lastValidInput = PlayerInput.Left;
			setTilePosition(xIndex, yIndex);
			audio.PlayOneShot(getRandomFootstepLightSFX());
			setLastLogMessage("You turn left.");
		}
		if (Input.GetButtonDown("Fire")		&&		// Fire Weapon.
			currentActionPoints > 0			&&
			canTakeAxisInput)
		{
			if (currentAmmo > 0)
			{
				if (lastValidInput == PlayerInput.Sprint)	// Sprint -> Fire chains into penetrating shot!
				{//Debug.Log("<color=red>PENETRATING SHOT!</color>");
					if (!isPenetratingShot)
					{
						CancelInvoke("toggleisPenetratingShot");
						toggleisPenetratingShot();
					}
					Invoke("toggleisPenetratingShot", 1.0f);
					setLastLogMessage("You fire a Penetrating Shot!");
				}
				else
				{
					setLastLogMessage("You fire!");
				}
				switch (gunType)
				{
					case GunType.Revolver:
						fireRevolverShot();
						break;
					case GunType.Shotgun:
						fireShotgunShot();
						break;
				}
				lastValidInput = PlayerInput.Fire;
				checkEndTurn();
				currentAmmo--;
			}
			else
			{
				switch (gunType)
				{
					case GunType.Revolver:
						audio.PlayOneShot(getRandomRevolverClickSfx());
						break;
					case GunType.Shotgun:
						audio.PlayOneShot(getRandomShotgunClickSfx());
						break;
				}
				setLastLogMessage("\"No ammo left!\"");
			}
		}
		if (Input.GetButtonDown("Surrender")	&&		// Order surrender.
			currentActionPoints > 0				&&
			canTakeAxisInput)
		{
			if (currentBullhorns > 0)
			{
				audio.PlayOneShot(bullhornSfx);
				currentBullhorns--;
				lastValidInput = PlayerInput.Bullhorn;
				int enemiesBullhorned = enemyGenerator.bullhornEnemies(voiceStat);
				checkEndTurn();
				setLastLogMessage("\"SURRENDER!\" - " + enemiesBullhorned + " enemies surrendering!");
			}
			else
			{
				setLastLogMessage("\"No Bullhorns left!\"");
			}
		}
		if (Input.GetButtonDown("Sprint")		&&		// Sprint.
			currentActionPoints > 0				&&
			canTakeAxisInput)
		{
			if (currentHealth > 1)
			{
				lastValidInput = PlayerInput.Sprint;
				currentHealth--;
				currentActionPoints += 2;		// Ugh - done because checkEndTurn() automatically deducts an action point!
				checkEndTurn();
				setLastLogMessage("You get ready to sprint!");
			}
			else
			{
				setLastLogMessage("\"Can't sprint any more!\"");
			}
		}
		/*if (Input.GetKeyDown("r")	&&					// Reload Weapon.
			currentActionPoints > 0)
		{
			checkEndTurn();
			currentAmmo = maxAmmo;
			setTilePosition(xIndex, yIndex);
			setLastLogMessage("You reload your weapon.");
		}*/
		if (Input.GetButtonDown("Law")		&&				// THE LAW (controls/gameplay help).
			canTakeAxisInput)
		{
			isTheLaw = !isTheLaw;
			lastValidInput = PlayerInput.Law;
		}
		if (Input.GetButtonDown("Arrest")	&&				// Arrest.
			currentActionPoints > 0	&&
			canTakeAxisInput)
		{
			bool hasArrestedPerp = false;
			switch (playerFacing)
			{
				case Direction.North:
					if (yIndex - 1 >= 0	&&
						DungeonGenerator.mazeRoom[xIndex, yIndex - 1] == (int)DungeonGenerator.TileType.Floor	&&
						!enemyGenerator.isTileClearOfUnits(xIndex, yIndex - 1))
					{
						hasArrestedPerp = enemyGenerator.canTouchEnemy(xIndex, yIndex - 1);
					}
					break;
				case Direction.South:
					if (yIndex + 1 < DungeonGenerator.maxDimension	&&
						DungeonGenerator.mazeRoom[xIndex, yIndex + 1] == (int)DungeonGenerator.TileType.Floor	&&
						!enemyGenerator.isTileClearOfUnits(xIndex, yIndex + 1))
					{
						hasArrestedPerp = enemyGenerator.canTouchEnemy(xIndex, yIndex + 1);
					}
					break;
				case Direction.East:
					if (xIndex - 1 >= 0	&&
						DungeonGenerator.mazeRoom[xIndex - 1, yIndex] == (int)DungeonGenerator.TileType.Floor	&&
						!enemyGenerator.isTileClearOfUnits(xIndex - 1, yIndex))
					{
						hasArrestedPerp = enemyGenerator.canTouchEnemy(xIndex - 1, yIndex);
					}
					break;
				case Direction.West:
					if (xIndex + 1 < DungeonGenerator.maxDimension	&&
						DungeonGenerator.mazeRoom[xIndex + 1, yIndex] == (int)DungeonGenerator.TileType.Floor	&&
						!enemyGenerator.isTileClearOfUnits(xIndex + 1, yIndex))
					{
						hasArrestedPerp = enemyGenerator.canTouchEnemy(xIndex + 1, yIndex);
					}
					break;
			}
			checkEndTurn();
			setLastLogMessage("You reach forward.");
			if (hasArrestedPerp)
			{
				totalArrests++;
				setLastLogMessage("Arrest executed for " + totalArrests % arrestsPerHealthRefill + " / " + arrestsPerHealthRefill + " arrests!");
				if (totalArrests % arrestsPerHealthRefill == 0)
				{
					refillHealth();
				}
			}
			/*else if (lastValidInput == PlayerInput.Sprint)
			{//Debug.Log("<color=yellow>AOE KNOCKBACK</color>");
				
			}*/
			else if (PlayerPrefs.GetInt("deaths", 0) >= 10)
			{
				audio.PlayOneShot(getRandomRevolverClickSfx());
				switch (gunType)		// Need to split this crap off into another class.
				{
					case GunType.Revolver:
						gunType = GunType.Shotgun;
						playerGun = shotgunSprite;
						revolverSprite.transform.position = new Vector3(-9999.9f, -9999.9f, -9999.9f);
						setLastLogMessage("The LAW will be heeded (you pull out a [Shotgun]!)");
						break;
					case GunType.Shotgun:
						gunType = GunType.Revolver;
						playerGun = revolverSprite;
						shotgunSprite.transform.position = new Vector3(-9999.9f, -9999.9f, -9999.9f);
						setLastLogMessage("The LAW will be heeded (you pull out a [Revolver]!)");
						break;
				}
				updateGun();
			}
			lastValidInput = PlayerInput.Arrest;
		}
	}
	public void toggleisPenetratingShot ()
	{
		isPenetratingShot = !isPenetratingShot;
	}
	private void checkEndTurn ()
	{
		resetIsKillsFilled();
		resetisArrestsFilled();
		enemyGenerator.enemyTurn(currentActionPoints);
		currentActionPoints--;
		if (currentActionPoints <= 0)
		{
			currentActionPoints = maxActionPoints;
		}
		turn++;
	}
	private float getRandomFireCone (bool useNegativeRange)
	{//useNegativeRange = false;	// HACK: Added revolver sprite so disable this for now!
		float cone = Random.Range(2, 5) * 0.01f;
		if (useNegativeRange	&&
			Random.Range(0, 2) > 0)
		{
			cone *= -1.0f;
		}
		return cone;
	}
	public void fireRevolverShot ()
	{
		audio.PlayOneShot(getRandomRevolverSfx());
		(GameObject.Find("Main Camera").GetComponent<CameraBehavior>()).startRevolverFireCameraShake();
		GameObject projectile = (GameObject)Instantiate(bulletCubeOrange, new Vector3(xIndex * 0.32f + getRandomFireCone(true), -1.0f * getRandomFireCone(false), yIndex * 0.32f + getRandomFireCone(true)), Quaternion.identity);
		projectile.rigidbody.AddForce(mainCamera.transform.forward * Random.Range(400, 500));
		Destroy(projectile, 1.0f);
	}
	public void fireShotgunShot ()
	{
		audio.PlayOneShot(getRandomShotgunSfx());
		(GameObject.Find("Main Camera").GetComponent<CameraBehavior>()).startShotgunFireCameraShake();
		Invoke("fireSingleShot", 0.0f);
		Invoke("fireSingleShot", 0.001f);
		Invoke("fireSingleShot", 0.002f);
		//Invoke("fireSingleConeShot", 0.001f);
		//Invoke("fireSingleConeShot", 0.002f);
	}
	public void fireSingleShot ()
	{
		GameObject projectile = (GameObject)Instantiate(bulletCubeOrange, new Vector3(xIndex * 0.32f + getRandomFireCone(true), -1.0f * getRandomFireCone(false), yIndex * 0.32f + getRandomFireCone(true)), Quaternion.identity);
		projectile.rigidbody.AddForce(mainCamera.transform.forward * Random.Range(500, 600));
		Destroy(projectile, 1.0f);
	}
	/*public void fireSingleConeShot ()	// Doesn't do jack shit yet!
	{
		GameObject projectile = (GameObject)Instantiate(bulletCubeOrange, new Vector3(xIndex * 0.32f + getRandomFireCone(true), -1.0f * getRandomFireCone(false), yIndex * 0.32f + getRandomFireCone(true)), Quaternion.identity);
		projectile.rigidbody.AddForce(mainCamera.transform.forward * Random.Range(500, 600));
		Destroy(projectile, 1.0f);
	}*/
	public void setTilePosition (int xIndex, int yIndex)
	{
		this.xIndex = xIndex;
		this.yIndex = yIndex;
		mainCamera.position = new Vector3(this.xIndex * DungeonGenerator.tileSize, 0.0f, this.yIndex * DungeonGenerator.tileSize);
		updateGun();
		(GameObject.Find("_MinimapCamera").GetComponent<MinimapCamera>()).setMinimapCamera(playerFacing, xIndex, yIndex);
		DungeonGenerator dg = masterObject.GetComponent<DungeonGenerator>();
		if (dg.elevatorXIndex == xIndex	&&
			dg.elevatorYIndex == yIndex)
		{
			if (level >= dg.lastLevel)
			{
				if (!enemyGenerator.hasTechnoWitch())
				{//Debug.Log("GAME WON!");
					PlayerPrefs.SetInt("victories", PlayerPrefs.GetInt("victories", 0) + 1);
					ApplicationControl.persistSaveData();
					Invoke("loadMainMenu", 3.0f);		// Show a stat screen first?
					gameWon = true;
				}
				else
				{//Debug.Log("GAME NOT WON YET!");
					setLastLogMessage("You must slay the Techno Witch!");
				}
				return;
			}
			else
			{
				level++;
				turn++;
				setLastLogMessage("You've reached the elevator!");
				enemyGenerator.killAllEnemies();	// Clean up.
				savePlayerData();
				Application.LoadLevel("main");
			}
		}
	}
	public void savePlayerData ()
	{
		PlayerPrefs.SetString("lastLogMessage", lastLogMessage);
		PlayerPrefs.SetInt("level", level);
		PlayerPrefs.SetInt("turn", turn);
		PlayerPrefs.SetInt("gunType", (int)gunType);
		PlayerPrefs.SetInt("currentHealth", currentHealth);
		PlayerPrefs.SetInt("maxHealth", maxHealth);
		PlayerPrefs.SetInt("currentActionPoints", currentActionPoints);
		PlayerPrefs.SetInt("maxActionPoints", maxActionPoints);
		PlayerPrefs.SetInt("currentAmmo", currentAmmo);
		PlayerPrefs.SetInt("maxAmmo", maxAmmo);
		PlayerPrefs.SetInt("damage", damage);
		PlayerPrefs.SetInt("currentBullhorns", currentBullhorns);
		PlayerPrefs.SetInt("maxBullhorns", maxBullhorns);
		PlayerPrefs.SetInt("voiceStat", voiceStat);
		PlayerPrefs.SetInt("totalKills", totalKills);
		PlayerPrefs.SetInt("totalArrests", totalArrests);
	}
	public void loadPlayerData ()
	{
		//lastLogMessage = PlayerPrefs.GetString("lastLogMessage", getLastLogMessage("You enter [Overrun Penal Colony]."));
		lastLogMessage = PlayerPrefs.GetString("lastLogMessage", getLastLogMessage("Press L to toggle THE [L]AW."));
		level = PlayerPrefs.GetInt("level", 1);
		turn = PlayerPrefs.GetInt("turn", 0);
		gunType = (GunType)PlayerPrefs.GetInt("gunType", 0);
		currentHealth = PlayerPrefs.GetInt("currentHealth", 6);
		maxHealth = PlayerPrefs.GetInt("maxHealth", 6);
		currentActionPoints = PlayerPrefs.GetInt("currentActionPoints", 1);
		maxActionPoints = PlayerPrefs.GetInt("maxActionPoints", 1);
		currentAmmo = PlayerPrefs.GetInt("currentAmmo", 6);
		maxAmmo = PlayerPrefs.GetInt("maxAmmo", 6);
		damage = PlayerPrefs.GetInt("damage", 1);
		currentBullhorns = PlayerPrefs.GetInt("currentBullhorns", 2);
		maxBullhorns = PlayerPrefs.GetInt("maxBullhorns", 6);
		voiceStat = PlayerPrefs.GetInt("voiceStat", 0);
		totalKills = PlayerPrefs.GetInt("totalKills", 0);
		totalArrests = PlayerPrefs.GetInt("totalArrests", 0);
	}
	public void updateGun ()
	{
		float xOffset = 0.0f;
		float yOffset = 0.0f;
		switch (playerFacing)
		{
			case Direction.North:
				playerGun.transform.rotation = Quaternion.Euler(new Vector3(0.0f, 270.0f, 0.0f));
				xOffset = -0.04f;
				yOffset = -0.06f;
				break;
			case Direction.South:
				playerGun.transform.rotation = Quaternion.Euler(new Vector3(0.0f, 90.0f, 0.0f));
				xOffset = 0.04f;
				yOffset = 0.06f;
				break;
			case Direction.East:
				playerGun.transform.rotation = Quaternion.Euler(new Vector3(0.0f, 0.0f, 0.0f));
				xOffset = -0.06f;
				yOffset = 0.04f;
				break;
			case Direction.West:
				playerGun.transform.rotation = Quaternion.Euler(new Vector3(0.0f, 180.0f, 0.0f));
				xOffset = 0.06f;
				yOffset = -0.04f;
				break;
		}
		playerGun.transform.position  = new Vector3(xIndex * DungeonGenerator.tileSize + xOffset, -0.07f, yIndex * DungeonGenerator.tileSize + yOffset);
	}
	private AudioClip getRandomFootstepLightSFX ()
	{
		switch (Random.Range(0, 4))
		{
			case 0:	return footstepLight1;
			case 1:	return footstepLight2;
			case 2:	return footstepLight3;
			case 3:	return footstepLight4;
		}
		return null;	// Eh... never gets returned, but still.
	}
	private AudioClip getRandomRevolverSfx ()
	{
		return revolverSfx;
	}
	private AudioClip getRandomShotgunSfx ()
	{
		switch (Random.Range(0, 3))
		{
			case 0:	return shotgunSfx1;
			case 1:	return shotgunSfx2;
			case 2:	return shotgunSfx3;
		}
		return null;
	}
	public AudioClip getRandomBulletImpactSfx ()
	{
		switch (Random.Range(0, 3))
		{
			case 0:	return bulletImpactSfx1;
			case 1:	return bulletImpactSfx2;
			case 2:	return bulletImpactSfx3;
		}
		return null;
	}
	private AudioClip getRandomRevolverClickSfx ()
	{
		return revolverClickSfx;
	}
	private AudioClip getRandomShotgunClickSfx ()
	{
		return shotgunClickSfx;
	}
	public void setFacing (Direction facing)
	{
		playerFacing = facing;
		switch (playerFacing)
		{
			case Direction.North:
				mainCamera.rotation = Quaternion.Euler(new Vector3(0.0f, 180.0f, 0.0f));
				break;
			case Direction.South:
				mainCamera.rotation = Quaternion.Euler(new Vector3(0.0f, 0.0f, 0.0f));
				break;
			case Direction.East:
				mainCamera.rotation = Quaternion.Euler(new Vector3(0.0f, 270.0f, 0.0f));
				break;
			case Direction.West:
				mainCamera.rotation = Quaternion.Euler(new Vector3(0.0f, 90.0f, 0.0f));
				break;
		}
		updateGun();
		(GameObject.Find("_MinimapCamera").GetComponent<MinimapCamera>()).setMinimapCamera(playerFacing, xIndex, yIndex);
	}
	public void takeDamage (int damage, ProjectileBehavior.DamageType damageType, bool stealItem)
	{
		(GameObject.Find("Main Camera").GetComponent<CameraBehavior>()).startDamageCameraShake();
		currentHealth -= damage;
		if (stealItem)
		{//Debug.Log("<color=red>ITEM STOLEN!</color>");
			// Steal ammo or a bullhorn!
			switch (Random.Range(0, 2))
			{
				case 0://Debug.Log("<color=yellow>AMMO STOLEN!</color>");
					if (currentAmmo > 0)
					{
						currentAmmo--;
					}
					break;
				case 1://Debug.Log("<color=cyan>BULLHORN STOLEN!</color>");
					if (currentBullhorns > 0)
					{
						currentBullhorns--;
					}
					break;
			}
		}
		if (currentHealth <= 0)
		{
			isPlayerDead = true;
			currentHealth = 0;
			audio.PlayOneShot(deathSfx);
			PlayerPrefs.SetInt("deaths", PlayerPrefs.GetInt("deaths", 0) + 1);
			ApplicationControl.persistSaveData();
			Invoke("loadMainMenu", deathFadeTime);
		}
	}
	public void loadMainMenu ()	// Shouldn't really be here!
	{
		Application.LoadLevel("mainMenu");
	}
	public void refillHealth ()
	{
		currentHealth = maxHealth;
	}
	public void refillAmmo ()
	{
		currentAmmo = maxAmmo;
	}
	public void refillBullhorns ()
	{
		currentBullhorns = maxBullhorns;
	}
	public void grantKill (string unitName)
	{
		totalKills++;
		setLastLogMessage("You kill [" + unitName + "] for " + totalKills % killsPerBullhorn + " / " + killsPerBullhorn + " kills!");
		if (totalKills % killsPerBullhorn == 0	&&
			currentBullhorns < maxBullhorns)
		{
			currentBullhorns++;
		}
	}
	public void OnGUI ()	// Fucking hell.
	{
		// Victory text.
		if (gameWon)
		{
			// Victory message.
			GUIStyle victoryGuiStyle = new GUIStyle();
			victoryGuiStyle.font = customFont;
			victoryGuiStyle.fontSize = 128;
			victoryGuiStyle.normal.textColor = Color.green;
			GUI.Label(new Rect(Screen.width / 2.0f - 256.0f, Screen.height / 2.0f - 64.0f, 128.0f, 64.0f), "VICTORY!", victoryGuiStyle);
			// Fade to black.
			alphaFadeValue += Mathf.Clamp01(Time.deltaTime / deathFadeTime);
			GUI.color = new Color(0.0f, 0.0f, 0.0f, alphaFadeValue);
			GUI.DrawTexture(new Rect(0.0f, 0.0f, Screen.width, Screen.height), blackDotTexture, ScaleMode.StretchToFill, true, 0.0f);
			//(GameObject.Find("Main Camera").GetComponent<CameraBehavior>()).startDeathCameraShake();
		}
		if (!isPlayerDead)
		{
			// Matrix for handling the GUI in different resolutions.
			GUI.matrix = Matrix4x4.TRS(new Vector3(0.0f, 0.0f, 0.0f), Quaternion.identity, new Vector3(1.0f, 1.0f, 1.0f));
			// Event Log text.
			GUIStyle eventLogGuiStyle = new GUIStyle();
			eventLogGuiStyle.font = customFont;
			eventLogGuiStyle.fontSize = 32;
			eventLogGuiStyle.normal.textColor = Color.cyan;
			Texture ammoTexture = null;
			switch (gunType)
			{
				case GunType.Revolver:
					ammoTexture = bulletTexture;
					break;
				case GunType.Shotgun:
					ammoTexture = shellTexture;
					break;
			}
			if (currentHealth > 0)	// Normal message.
			{
				GUI.Label(new Rect(48.0f, Screen.height - 64.0f/*128.0f*/, 128.0f, 64.0f), lastLogMessage, eventLogGuiStyle);
			}
			else					// Death message.
			{
				eventLogGuiStyle.normal.textColor = Color.red;
				GUI.Label(new Rect(128.0f, 16.0f, 128.0f, 64.0f), "Turn " + turn + ": " + "You died!", eventLogGuiStyle);
			}
			// Heart icons for health.
			for (int i = 1; i <= currentHealth; i++)
			{
				GUI.DrawTexture(new Rect(32.0f * i, 32.0f, 64.0f, 64.0f), heartTexture, ScaleMode.StretchToFill, true, 0.0f);
			}
			// Bullet icons for ammo.
			for (int i = 1; i <= currentAmmo; i++)
			{
				GUI.DrawTexture(new Rect(32.0f * i, 80.0f, 64.0f, 64.0f), ammoTexture, ScaleMode.StretchToFill, true, 0.0f);
			}
			// Bullhorn icons.
			for (int i = 1; i <= currentBullhorns; i++)
			{
				GUI.DrawTexture(new Rect(32.0f * i, 136.0f, 64.0f, 64.0f), bullhornTexture, ScaleMode.StretchToFill, true, 0.0f);
			}
			// Skull kill icons.
			if (!isKillsFilled					&&
				totalKills > 0					&&
				totalKills != lastTotalKills	&&
				totalKills % killsPerBullhorn == 0)
			{
				isKillsFilled = true;
				lastTotalKills = totalKills;
				Invoke("resetIsKillsFilled", 2.0f);
			}
			if (isKillsFilled)
			{
				for (int i = 0; i < killsPerBullhorn; i++)
				{
					GUI.DrawTexture(new Rect(i * 32.0f + 256.0f, 136.0f, 64.0f, 64.0f), skullTexture, ScaleMode.StretchToFill, true, 0.0f);
				}
			}
			else
			{
				for (int i = 0; i < killsPerBullhorn; i++)
				{
					GUI.DrawTexture(new Rect(i * 32.0f + 256.0f, 136.0f, 64.0f, 64.0f), skullEmptyTexture, ScaleMode.StretchToFill, true, 0.0f);
				}
			}
			for (int i = 1; i <= totalKills % killsPerBullhorn; i++)
			{
				GUI.DrawTexture(new Rect(32.0f * i + 224.0f, 136.0f, 64.0f, 64.0f), skullTexture, ScaleMode.StretchToFill, true, 0.0f);
			}
			// Handcuffs fill icons.
			if (!isArrestsFilled						&&
				totalArrests > 0					&&
				totalArrests != lastTotalArrests	&&
				totalArrests % arrestsPerHealthRefill == 0)
			{
				isArrestsFilled = true;
				lastTotalArrests = totalArrests;
				Invoke("resetisArrestsFilled", 2.0f);
			}
			if (isArrestsFilled)
			{
				for (int i = 0; i < arrestsPerHealthRefill; i++)
				{
					GUI.DrawTexture(new Rect(i * 32.0f + 256.0f, 32.0f, 64.0f, 64.0f), handcuffsTexture, ScaleMode.StretchToFill, true, 0.0f);
				}
			}
			else
			{
				for (int i = 0; i < arrestsPerHealthRefill; i++)
				{
					GUI.DrawTexture(new Rect(i * 32.0f + 256.0f, 32.0f, 64.0f, 64.0f), handcuffsEmptyTexture, ScaleMode.StretchToFill, true, 0.0f);
				}
			}
			for (int i = 1; i <= totalArrests % arrestsPerHealthRefill; i++)
			{
				GUI.DrawTexture(new Rect(32.0f * i + 224.0f, 32.0f, 64.0f, 64.0f), handcuffsTexture, ScaleMode.StretchToFill, true, 0.0f);
			}
			// NOTE: Fuck it, do the limit/transparency thing. Leave this crap here for now - too many commits and I don't wanna dredge this shit up later.
			// Skull icons.
			/*float verticalSetAdjust = -4.0f;
			for (int i = 1; i <= totalKills; i++)
			{
				if (i % arrestsPerHealthRefill == 0)
				{
					GUI.DrawTexture(new Rect(32.0f * i, Screen.height - 106.0f + verticalSetAdjust, 64.0f, 64.0f), skullTexture, ScaleMode.StretchToFill, true, 0.0f);
				}
				else
				{
					GUI.DrawTexture(new Rect(32.0f * i, Screen.height - 106.0f, 64.0f, 64.0f), skullTexture, ScaleMode.StretchToFill, true, 0.0f);
				}
			}
			// Handcuffs icons.
			for (int i = 1; i <= totalArrests; i++)
			{
				if (i % arrestsPerHealthRefill == 0)
				{
					GUI.DrawTexture(new Rect(32.0f * i, Screen.height - 64.0f + verticalSetAdjust, 64.0f, 64.0f), handcuffsTexture, ScaleMode.StretchToFill, true, 0.0f);
				}
				else
				{
					GUI.DrawTexture(new Rect(32.0f * i, Screen.height - 64.0f, 64.0f, 64.0f), handcuffsTexture, ScaleMode.StretchToFill, true, 0.0f);
				}
			}*/
			if (isTheLaw)
			{
				GUI.DrawTexture(new Rect(0.0f, Screen.height - 512.0f, 512.0f, 512.0f), keyOverlayTexture, ScaleMode.StretchToFill, true, 0.0f);
			}
		}
		// Death text.
		else
		{
			// Death message.
			GUIStyle deathGuiStyle = new GUIStyle();
			deathGuiStyle.font = customFont;
			deathGuiStyle.fontSize = 128;
			deathGuiStyle.normal.textColor = Color.red;
			GUI.Label(new Rect(Screen.width / 2.0f - 256.0f, Screen.height / 2.0f - 64.0f, 128.0f, 64.0f), "YOU DIED", deathGuiStyle);
			// Fade to black.
			alphaFadeValue += Mathf.Clamp01(Time.deltaTime / deathFadeTime);
			GUI.color = new Color(0.0f, 0.0f, 0.0f, alphaFadeValue);
			GUI.DrawTexture(new Rect(0.0f, 0.0f, Screen.width, Screen.height), blackDotTexture, ScaleMode.StretchToFill, true, 0.0f);
			(GameObject.Find("Main Camera").GetComponent<CameraBehavior>()).startDeathCameraShake();
		}
	}
	private void resetIsKillsFilled ()
	{
		isKillsFilled = false;
	}
	private void resetisArrestsFilled ()
	{
		isArrestsFilled = false;
	}
	public void setLastLogMessage (string message)
	{
		lastLogMessage = getLastLogMessage(message);
	}
	public string getLastLogMessage (string message)
	{
		return "L-T " + level + "-" + turn + ": " + message;
	}
	public void setGunType (GunType gunType)
	{
		this.gunType = gunType;
		switch (this.gunType)
		{
			case GunType.Revolver:
				damage = 1;
				break;
			case GunType.Shotgun:
				damage = 2;
				break;
		}
	}
}