using UnityEngine;
using System.Collections;
using EZCameraShake;

[AddComponentMenu("EZ Camera Shake/Camera Shaker")]
public class PlayerControl : MonoBehaviour {
	[HideInInspector]
	public bool facingRight = true;			// For determining which way the player is currently facing.
	[HideInInspector]
	public bool levitate = false;				// Condition for whether the player should jump.


	public float moveForce = 365f;			// Amount of force added to move the player left and right.
	public float maxSpeed = 5f;				// The fastest the player can travel in the x axis.
	public AudioClip levitationClip;	    // Array of clips for when the player levitates.
	public float levitationForce = 30f;	// Amount of force added when the player jumps.
	public AudioClip summoning;			    // Array of clips for when the player taunts.

	public AudioClip walking;			    // Array of clips for when the player taunts.

	private Transform groundCheck;			// A position marking where to check if the player is grounded.
	private bool grounded = true;			// Whether or not the player is grounded.
	private Animator anim;					// Reference to the player's animator component.

	public GameObject friendlySummon;
	public Transform summonPrefab;
	private Transform PlayerFollow;			// A position marking where to check if the player is grounded.

	public float initScale;

	public float shakeMag = 0.96f;
	public float shakeRough = 10.43f;

	public GameObject platform;
	public GameObject target;
	public GameObject BossTarget;
	private bool BossFollow = false;
	private Transform initPlat;
	private Transform initBoss;
	private bool movePlatform = false;
	float distCovered = 0;

	public bool alive = true;

	void Awake()
	{
		initPlat = platform.transform;
		initBoss = GameObject.FindGameObjectWithTag ("Enemy").transform;
		// Setting up references.
		groundCheck = transform.Find("groundCheck");
		PlayerFollow = transform.Find("PlayerFollow");
		anim = GetComponent<Animator>();
	}

	void Update()
	{
		if (alive) {
			// The player is grounded if a linecast to the groundcheck position hits anything on the ground layer.
			grounded = Physics2D.Linecast (transform.position, groundCheck.position, 1 << LayerMask.NameToLayer ("Ground"));  


			if (friendlySummon != null) {
				float diff = friendlySummon.transform.position.x - PlayerFollow.transform.position.x;
				if (Mathf.Abs (diff) < 0.5f) {
					Vector3 summonScale = friendlySummon.transform.localScale;
					summonScale.x = transform.localScale.x * (initScale / 0.45f);
					friendlySummon.transform.localScale = summonScale;

				}
			}
		}else {
			if (transform.position.y > -2.5f) {
				GetComponent<Rigidbody2D> ().gravityScale = 10f;
			}
			else {
				
			}
		}

		if (movePlatform) {
			distCovered += 1f;
			float journeyLength = 30f;
			float fracJourney = distCovered / journeyLength;
			platform.transform.position = Vector3.Lerp(initPlat.position, target.transform.position, fracJourney);
			BossFollow = true;
		}

		if (BossFollow) {
			GameObject.FindGameObjectWithTag ("Enemy").GetComponent<BossScript> ().follow = true;
		}
	}

	void FixedUpdate ()
	{
		if (alive) {
			//<!--   MUST FIX!!!!!!!!!!! -->VVVVVVVVVVVV
			if (Input.GetKey (KeyCode.UpArrow))
				levitate = true;
			;
			//<!--   MUST FIX!!!!!!!!!!! -->^^^^^^^^^^^^^


			// Cache the horizontal input.
			float h = Input.GetAxis ("Horizontal");

			// The Speed animator parameter is set to the absolute value of the horizontal input.
			anim.SetFloat ("Speed", Mathf.Abs (h));
			

			// If the player is changing direction (h has a different sign to velocity.x) or hasn't reached maxSpeed yet...
		if (h * GetComponent<Rigidbody2D> ().velocity.x < maxSpeed){
			// ... add a force to the player.
			GetComponent<Rigidbody2D> ().AddForce (Vector2.right * h * moveForce);}

			// If the player's horizontal velocity is greater than the maxSpeed...
			if (Mathf.Abs (GetComponent<Rigidbody2D> ().velocity.x) > maxSpeed)
			// ... set the player's velocity to the maxSpeed in the x axis.
			GetComponent<Rigidbody2D> ().velocity = new Vector2 (Mathf.Sign (GetComponent<Rigidbody2D> ().velocity.x) * maxSpeed, GetComponent<Rigidbody2D> ().velocity.y);

			// If the playeris moving...
			if ((Mathf.Abs (GetComponent<Rigidbody2D> ().velocity.x) > 1f) && (transform.position.y < -2.8)
			    && !GameObject.Find ("One shot audio"))
				AudioSource.PlayClipAtPoint (walking, transform.position);

			// If the input is moving the player right and the player is facing left...
			if (h > 0 && !facingRight)
			// ... flip the player.
			Flip ();
		// Otherwise if the input is moving the player left and the player is facing right...
		else if (h < 0 && facingRight)
			// ... flip the player.
			Flip ();

			// If the player should jump...
			if (levitate) {
				// Play levitation audio clip.
				if (levitationClip) {
					AudioSource.PlayClipAtPoint (levitationClip, transform.position);
				}
				// Add a vertical force to the player.
				GetComponent<Rigidbody2D> ().AddForce (new Vector2 (0f, levitationForce));

				// Make sure the player can't jump again until the jump conditions from Update are satisfied.
				levitate = false;
			} 

			if (!grounded) {
				anim.SetBool ("Levitate", true);
			} else {
				anim.SetBool ("Levitate", false);
			}
		} 
		else {
			anim.SetFloat ("Speed", 0);
		}
	}

	//void Die()
	//{
	//}

	void Flip ()
	{
		// Switch the way the player is labelled as facing.
		facingRight = !facingRight;
 
		// Multiply the player's x local scale by -1.
		Vector3 theScale = transform.localScale;
		theScale.x *= -1;
		transform.localScale = theScale;

	}

	public void Summon ()
	{   if(friendlySummon) Destroy (friendlySummon);
		if (summonPrefab) {
			Transform instance = Instantiate (summonPrefab, PlayerFollow.position, Quaternion.identity) as Transform;
			GameObject newSummon = instance.gameObject;
			friendlySummon = newSummon;
		} else {
			GameObject.FindGameObjectWithTag("MainCamera").GetComponent<CameraShaker>().ShakeOnce(shakeMag, shakeRough, 1f, 6f);
			movePlatform = true;
		}
		if(!GetComponent<AudioSource>().isPlaying)
		{
			GetComponent<AudioSource>().clip = summoning;
			GetComponent<AudioSource>().Play();
		}
	}

	public void Dispell ()
	{
		Destroy (GameObject.FindGameObjectWithTag ("Enemy"));
	}
}
