using UnityEngine;
using System.Collections;


public class ZeroGravCC : MonoBehaviour {

	float moveSpeed = 6; // move speed
	float turnSpeed = 90; // turning speed (degrees/second)
	float lerpSpeed = 10; // smoothing speed
	float gravity = 10; // gravity acceleration
	bool isGrounded;
	float deltaGround = 0.2f; // character is grounded up to this distance
	float jumpSpeed = 10; // vertical jump initial speed
	float jumpRange = 10; // range to detect target wall
	
	private Vector3 surfaceNormal; // current surface normal
	private Vector3 myNormal; // character normal
	private float distGround; // distance from character position to ground
	private bool jumping = false; // flag "I'm jumping to wall"
	private float vertSpeed = 0; // vertical jump current speed 
	private Rigidbody rb;
//	private ThirdPersonCharacter thirdPersonScript;

	void Start(){
		myNormal = transform.up; // normal starts as character up direction 
		rb.freezeRotation = true; // disable physics rotation
		// distance from transform.position to ground
		distGround = transform.position.y - 0f;  
		rb = gameObject.GetComponent<Rigidbody>();
//		thirdPersonScript = gameObject.GetComponent<ThirdPersonCharacter>();
	}
	
	void FixedUpdate(){
		// apply constant weight force according to character normal:
		rb.AddForce(-gravity*rb.mass*myNormal);
	}
	
	void Update(){
		// jump code - jump to wall or simple jump
		if (jumping) return;  // abort Update while jumping to a wall
		Ray ray;
		RaycastHit hit;
		if (Input.GetButtonDown("Jump")){ // jump pressed:
			if (Physics.Raycast(transform.position, -myNormal, out hit, jumpRange)){ // wall ahead?
//				JumpToWall(hit.point, hit.normal); // yes: jump to the wall
			}
			else if (isGrounded){ // no: if grounded, jump up
				rb.velocity += jumpSpeed * myNormal;
			}                
		}
		
		// movement code - turn left/right with Horizontal axis:
		transform.Rotate(0, Input.GetAxis("Horizontal")*turnSpeed*Time.deltaTime, 0);
		// update surface normal and isGrounded:
		if (Physics.Raycast(transform.position, -myNormal, out hit, Mathf.Infinity)){ // use it to update myNormal and isGrounded
			isGrounded = hit.distance <= distGround + deltaGround;
			surfaceNormal = hit.normal;
//			thirdPersonScript.newNormal = surfaceNormal;
		}
		else {
			isGrounded = false;
			// assume usual ground normal to avoid "falling forever"
			surfaceNormal = Vector3.up; 
		}
		myNormal = Vector3.Lerp(myNormal, surfaceNormal, lerpSpeed*Time.deltaTime);
		// find forward direction with new myNormal:
		var myForward = Vector3.Cross(transform.right, myNormal);
		// align character to the new myNormal while keeping the forward direction:
		var targetRot = Quaternion.LookRotation(myForward, myNormal);
		transform.rotation = Quaternion.Lerp(transform.rotation, targetRot, lerpSpeed*Time.deltaTime);
		// move the character forth/back with Vertical axis:
		transform.Translate(0, 0, Input.GetAxis("Vertical")*moveSpeed*Time.deltaTime); 
	}
	
//	public void JumpToWall(Vector3 point, Vector3 normal){
//		// jump to wall 
//		jumping = true; // signal it's jumping to wall
//		rb.isKinematic = true; // disable physics while jumping
//		var orgPos = transform.position;
//		var orgRot = transform.rotation;
//		var dstPos = point + normal * (distGround + 0.5); // will jump to 0.5 above wall
//		var myForward = Vector3.Cross(transform.right, normal);
//		var dstRot = Quaternion.LookRotation(myForward, normal);
//		for (float t = 0.0; t < 1.0; ){
//			t += Time.deltaTime;
//			transform.position = Vector3.Lerp(orgPos, dstPos, t);
//			transform.rotation = Quaternion.Slerp(orgRot, dstRot, t);
//			yield; // return here next frame
//		}
//		myNormal = normal; // update myNormal
//		rigidbody.isKinematic = false; // enable physics
//		jumping = false; // jumping to wall finished
//	}
}