using System.Collections;
using UnityEngine;
using matnesis.TeaTime;
using UnityEngine.SceneManagement;

[RequireComponent(typeof(PlayerMovement)), RequireComponent(typeof(Rigidbody))]
public class PlayerActor : MonoBehaviour 
{

	// Jumping settings
	public float jumpForce = 350;
	public float jumpForceFall = 100;
	public int maxJumpCap = 1;
	public float resetJumpTimer = 0.1f;

	// Ground checker settings
	public Transform groundChecker;
	public float groundDetectionRadius = 0.2f;
	public LayerMask whatIsGround;

	private PlayerMovement move;
	private Rigidbody rBody;
	private Vector3 originalPosition;

	public int jumpsWasted = 0;
	private bool jumping;
	private TeaTime resetJumps;
	private Animator anim;
	public bool facingRight = true;
	private bool noDamage;

	// Use this for initialization
	void Start () 
	{
		if(groundChecker == null) { transform.FindChild ("GroundChecker"); }
		move = GetComponent<PlayerMovement> ();
		rBody = GetComponent<Rigidbody> ();
		anim = GetComponent<Animator> ();

		resetJumps = this.tt().Add(resetJumpTimer, () => 
			{
				if(IsGrounded())
				{
					jumpsWasted = 0;	
				}
			}).Add((ttHandler t) => 
				{ 
					if(jumpsWasted == 0) 
					{
						t.self.Stop();
					} 
				}).Repeat().Immutable();
		originalPosition = transform.position;
	}

	void Update ()
	{
		jumping = Input.GetButtonDown (Buttons.Jump);

		if(IsGrounded())
		{
			anim.SetFloat ("Move", Mathf.Abs(move.horizontalValue));
		}
		else
		{
			anim.SetFloat ("Move", 1);
		}
		anim.SetBool ("Grounded", IsGrounded());

		if(anim.GetCurrentAnimatorStateInfo(0).IsName("Walk") && !IsGrounded())
		{
			anim.speed = 3;
		}
		else
		{
			anim.speed = 1;
		}
		/*if(transform.position.y < -10)
		{
			transform.position = originalPosition;
			Camera.main.GetComponent<SideScroll> ().StartTransitionToPlayer ();
		}*/
	}

	// Update is called once per frame
	void FixedUpdate () 
	{
		if(facingRight && move.horizontalValue < 0)
		{
			Flip ();
		}
		else if(!facingRight && move.horizontalValue > 0)
		{
			Flip ();
		}
			

		// Jumping
		if(jumping)
		{
			if (jumpsWasted < maxJumpCap) 
			{
				//anim.SetTrigger ("Jump");

				rBody.AddForce (Vector3.up * jumpForce);
				//rBody.velocity = new Vector3 (rBody.velocity.x, jumpForce, rBody.velocity.z);
				jumpsWasted += 1;

				resetJumps.Play ().Forward ();
			}
		}

		/*if(!IsGrounded())
		{
			rBody.velocity = new Vector3 (rBody.velocity.x, jumpForceFall * Time.fixedDeltaTime, rBody.velocity.z);
		}*/

		rBody.velocity = new Vector3 (move.horizontalValue, rBody.velocity.y, rBody.velocity.z);
	}

	bool IsGrounded ()
	{
		Collider[] collisionObj = Physics.OverlapSphere (groundChecker.position, groundDetectionRadius, whatIsGround);
		if(collisionObj.Length > 0)
		{
			return true;
		}
		//Debug.Log (collisionObj.Length > 0);

		return false;
	}
		
	void OnCollisionEnter (Collision other)
	{
		if(other.gameObject.tag == Tags.Impulse)
		{
			Debug.Log (other.gameObject.name);
			this.tt ("Trampoline").Loop (0.2f, (ttHandler t) => 
				{
					Vector3 scale = other.transform.localScale;
					scale.y = Mathf.Lerp(scale.y, 1.2f, t.t);
					other.transform.localScale = scale;
				}).Loop (0.5f, (ttHandler t) => 
					{
						Vector3 scale = other.transform.localScale;
						scale.y = Mathf.Lerp(scale.y, 0.1f, t.t);
						other.transform.localScale = scale;
					}).Loop (0.2f, (ttHandler t) => 
						{
							Vector3 scale = other.transform.localScale;
							scale.y = Mathf.Lerp(scale.y, 0.3f, t.t);
							other.transform.localScale = scale;
						}).Loop (0.2f, (ttHandler t) => 
							{
								Vector3 scale = other.transform.localScale;
								scale.y = Mathf.Lerp(scale.y, 0.1f, t.t);
								other.transform.localScale = scale;
							});
			rBody.AddForce (Vector3.up * (10));
		}
	}

	void OnTriggerEnter (Collider other)
	{
	    if(other.gameObject.layer == LayerMask.NameToLayer(Layers.Water))
		{
			TakePlayerLife ();
			transform.position = originalPosition;
			Camera.main.GetComponent<SideScroll> ().StartTransitionToPlayer ();
		}
		else if(other.gameObject.tag == Tags.Final)
		{
			this.tt().Add(1, () =>
				{
					Camera.main.GetComponent<CameraShake>().Shake();
					GameObject.Find("World").GetComponent<Rigidbody>().isKinematic = false;
				}).Add(3, () => 
					{
						rBody.isKinematic = true;
					}).Add(3, () =>
						{
							SceneManager.LoadScene(0);
						});
		}
	}

	void Flip ()
	{
		Vector3 newScale = transform.localScale;
		newScale.z *= -1;
		transform.localScale = newScale;
		facingRight = !facingRight;
	}

	public void TakePlayerLife ()
	{
		SkinnedMeshRenderer render = GetComponentInChildren<SkinnedMeshRenderer> ();
		MeshRenderer gunrender = GetComponentInChildren<MeshRenderer> ();
		this.tt("Inmune").Add(() => 
			{
				noDamage = true;
				render.enabled = false;
				gunrender.enabled = false;
			}).Add(0.2f, () => 
				{
					render.enabled = true;
					gunrender.enabled = true;
				}).Add(0.2f, () => 
					{
						render.enabled = false;
						gunrender.enabled = false;
					}).Add(0.2f, () => 
						{
							gunrender.enabled = true;
							render.enabled = true;
						}).Add(0.2f, () => 
							{
								render.enabled = false;
								gunrender.enabled = false;
							}).Add(0.2f, () => 
								{
									render.enabled = true;
									gunrender.enabled = true;
									noDamage = false;
								});

		GameManager.playerLifes--;
		GameManager.UI.ChangeHearts ();
		if(GameManager.playerLifes <= 0)
		{
			GameManager.StartOver ();
			this.tt().Add(1, () =>
				{
					Camera.main.GetComponent<CameraShake>().Shake();
					GameObject.Find("World").GetComponent<Rigidbody>().isKinematic = false;
				}).Add(3, () => 
					{
						rBody.isKinematic = true;
					}).Add(3, () =>
						{
							SceneManager.LoadScene(0);
						});
		}
	}
}
