 using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[RequireComponent (typeof (Controller2D))]
public class Player : MonoBehaviour {


	public float maxJumpHeight = 4; 	//how high we want the character to jump. E.g. 4 units. Assigning values to jumpHeight and timeToJumpApex to determine gravity and jumpVelocity
	public float minJumpheight = 1; 
	public float timeToJumpApex = .4f; 	//how long it takes until the player reaches the highest point of the jump
	float accelerationTimeAirborne = .2f; 	//change of direction while airborne (probably want to have the Playerobject's change of direction slower while airborne compared to when grounded)
	float accelerationTimeGrounded = .1f; 	//change of direction while grounded
	float moveSpeed = 6; 

	float gravity = -20;		//not very intuitive, hard to imagine what this really means. Not going to assign anything directly to these variables (e.g. not setting gravity = -20;). Rather have the jumpHeight and timeToJumpApex
	float maxJumpVelocity;		//same as above note. Not intuitive 
	float minJumpVelocity;
	Vector3 velocity; 
	float velocityXsmoothing;  	//the smooth function (for smoothing the Playerobject's movement)

	//private Transform player; 	//TESTING TP

	Controller2D controller; 

	// Use this for initialization
	void Start () {
		controller = GetComponent<Controller2D> ();

		gravity = -(2 * maxJumpHeight) / Mathf.Pow (timeToJumpApex, 2); 	//for explanation, see time 5.57 in the youtube tutorial.		Known: jumpHeight, timeToJumpApex. Solve for: gravity, jumpVelocity
		maxJumpVelocity = Mathf.Abs(gravity * timeToJumpApex); 
		minJumpVelocity = Mathf.Sqrt (2 * Mathf.Abs (gravity) * minJumpheight);
		print ("Gravity: " + gravity + "Jump Velocity: " + maxJumpVelocity); 
	}


//	void Awake() {		//TESTING TP
//		player = GameObject.FindGameObjectWithTag("Player").transform; 
//	}

	// Update is called once per frame
	void Update () {

		//jump input controlling max and min jump height
		if (Input.GetKeyUp (KeyCode.Space)) {
			if (velocity.y > minJumpVelocity) {
				velocity.y = minJumpVelocity; 
			}
		}

		//solving jump input again for the W button			///////////////OLE! CAN I SOMEHOW INCLUDE THIS IN THE STUFF ABOVE????!??????????!!!!!!!!!!?????????????????!!!!!!!!!!!!!!!!???????????!!!!!!!!!!!!!!!!!!!!
		if (Input.GetKeyUp (KeyCode.W)) {
			if (velocity.y > minJumpVelocity) {
				velocity.y = minJumpVelocity; 
			}
		}
			

		if (controller.collisions.above || controller.collisions.below) {		//fixing problem of accumulating gravity (if this code did not exist in the script, the rays would grow bigger and bigger and if object falls off the edge it would fall incredibly fast
			velocity.y = 0;
		}

		Vector2 input = new Vector2 (Input.GetAxisRaw ("Horizontal"), Input.GetAxisRaw ("Vertical")); 

		if (Input.GetKeyDown (KeyCode.W) && controller.collisions.below) {		//jumping.		(if the W is pressed and there is a collision below the player...)
			velocity.y = maxJumpVelocity; 
		}

		if (Input.GetKeyDown (KeyCode.Space) && controller.collisions.below) {		// OLE!! CAN I SOMEHOW INCLUDE THIS ASWELL IN THE STUFF ABOVE??!! !!!!!!!!!!!!!!!!!!!!!!!!!!???????!?!?!?!?!?!?!??!?!?!?!?!??!?!?!!!!!!!
				velocity.y = maxJumpVelocity; 
		}

		float targetVelocityX = input.x * moveSpeed; 			//instead of velocity.x = input.x * moveSpeed;, this way x-movement gets smoother so the changes in direction are not so abrubt
		velocity.x = Mathf.SmoothDamp(velocity.x, targetVelocityX, ref velocityXsmoothing, (controller.collisions.below)?accelerationTimeGrounded:accelerationTimeAirborne); 		//instead of only velocity.x = input.x * moveSpeed;
		//each frame we're going to apply the gravity to our velocity
		velocity.y += gravity * Time.deltaTime; 
		controller.Move (velocity * Time.deltaTime); //so our controller will acctually move the player


		//TESTING TP
		//if (Input.GetMouseButtonDown (0))
		//	player.position = Camera.main.ScreenToWorldPoint (Input.mousePosition); 
	}
}

