using UnityEngine;
using System.Collections;

public class KartScript : MonoBehaviour {
	
	
	public GameObject animObj;
	
	public GameObject chassis;
	
	public GameObject wheel_FL;
	public GameObject wheel_FR;
	public GameObject wheel_BL;
	public GameObject wheel_BR;
	
	
	public string leftKey;
	public string rightKey;
	public string upKey;
	public string downKey;
	
	
	private bool grounded = true;
	
	private Vector3 moveVector = Vector3.zero;
	
	private float accelSpeed = 0.5f;
	private float brakeSpeed = 0.5f;
	
	public GameObject camObj;
	public GameObject camTarget;
	
	private Vector3 checkpointPos;
	private Vector3 checkpointDirection;
	
	// Use this for initialization
	void Start () {
		checkpointPos = transform.position;
		checkpointDirection = transform.forward;
	}
	
	
	private int currentCheckpoint = 0;
	private int totalCheckpoints = 0;
	private int currentLap = 0;
	
	public TextMesh lapText;
	
	private bool gameOver = false;
	private bool won = false;
	
	public void Lose(){
		gameOver = true;
	}
	
	public void InitTrack(int checks){
		totalCheckpoints = checks;
		
	}
	
	// Update is called once per frame
	void Update () {
		
		if (!gameOver){
			lapText.text = "Lap " + currentLap + "/2";
		}else{
			if (won){
				lapText.text = "WINNER!";
			}else{
				lapText.text = "LOSER!";
			}
		}
		
		
		//accel
		if (grounded){
			if (Input.GetKey(upKey)){
				moveVector += transform.forward * accelSpeed * Time.deltaTime;
			}else{
				//deccelerate
				moveVector -= (moveVector - Vector3.zero) * 5f * Time.deltaTime;
			}
			
			if (Input.GetKey(downKey)){
				moveVector += -transform.forward * brakeSpeed * Time.deltaTime;
			}
			
		}else{
			moveVector.y -= 0.2f * Time.deltaTime;
		}
		
		//turning
		if (Input.GetKey(leftKey)){
			transform.Rotate(0,-90*Time.deltaTime,0);
			
			if (grounded){
				Vector3 newMove = transform.forward * moveVector.magnitude;
				moveVector = (moveVector + newMove)/2;
			}
		}
		if (Input.GetKey(rightKey)){
			transform.Rotate(0,90*Time.deltaTime,0);
			
			if (grounded){
				Vector3 newMove = transform.forward * moveVector.magnitude;
				moveVector = (moveVector + newMove)/2;
			}
				
		}
		
		if (moveVector.magnitude > 0.28f){
			moveVector = moveVector.normalized * 0.28f;
		}
		Vector3 lastpos = transform.position;
		
		transform.position += moveVector;
		
		Ray groundRay = new Ray(transform.position + transform.up, -transform.up);
		RaycastHit groundHit = new RaycastHit();
		int groundLayer = (1<<0)|(1<<9);
		if (Physics.Raycast(groundRay, out groundHit, 1.01f, groundLayer)){
			grounded = true;
			transform.position = groundHit.point;
			moveVector.y = 0f;
			
			
			Vector3 lookDir = Vector3.Cross(transform.forward, transform.up);
			lookDir = Vector3.Cross(lookDir, groundHit.normal);
			
			if (Vector3.Dot(transform.forward, lookDir) <=0f) lookDir *= -1;
			
			transform.LookAt(transform.position + lookDir, groundHit.normal);
			
			if (groundHit.collider.gameObject.layer == 9){
				if (moveVector.magnitude > 0.15f){
					moveVector = moveVector.normalized * 0.15f;
				}
			}
			
		}else{
			grounded = false;
		}
		
		
		Ray collideRay = new Ray(lastpos, transform.position-lastpos);
		RaycastHit collideHit = new RaycastHit();
		float collideLength = Vector3.Distance(lastpos, transform.position);
		int collideLayer = (1<<8)|(1<<10);
		if (Physics.Raycast(collideRay, out collideHit, collideLength, collideLayer)){
			
			if (collideHit.collider.gameObject.layer == 8){
				//die
				moveVector = Vector3.zero;
				transform.position = checkpointPos;
				grounded = true;
				transform.LookAt(transform.position + checkpointDirection, Vector3.up);
				
				camObj.transform.position = camTarget.transform.position;
				camObj.transform.rotation = camTarget.transform.rotation;
			}else{
				//checkpoint
				
				
				
				CheckpointScript check = collideHit.collider.gameObject.GetComponent<CheckpointScript>();
				bool allowCheck = false;
				
				print(currentCheckpoint + " - " + check.checkpintID + " - " + totalCheckpoints);
				
				
				if (check.checkpintID == 0 && currentCheckpoint == totalCheckpoints){
					allowCheck = true;
					currentLap ++;
					if (currentLap ==3 && !gameOver){
						gameOver = true;
						won = true;
						GameObject.Find("_Judge").GetComponent<KartJudge>().Finish(this);
					}
				}else if (check.checkpintID == 0 && currentCheckpoint == 0 ){
					allowCheck = true;
				}else if (currentCheckpoint == check.checkpintID-1 ){
					allowCheck = true;
				}
				
				if (allowCheck){
					checkpointPos = check.checkpointPos.transform.position;
					checkpointDirection = check.checkpointPos.transform.forward;
					currentCheckpoint = check.checkpintID;
				}
			}
			
			
		}

		
		if (Input.GetKey(leftKey)){
			wheel_FL.transform.localEulerAngles = new Vector3(0,-45,0);
			wheel_FR.transform.localEulerAngles = new Vector3(0,-45,0);
			animObj.animation.CrossFade("kartL");
		}else if (Input.GetKey(rightKey)){
			wheel_FL.transform.localEulerAngles = new Vector3(0,45,0);
			wheel_FR.transform.localEulerAngles = new Vector3(0,45,0);
			animObj.animation.CrossFade("kartR");
		}else{
			wheel_FL.transform.localEulerAngles = new Vector3(0,0,0);
			wheel_FR.transform.localEulerAngles = new Vector3(0,0,0);
			animObj.animation.CrossFade("kart");
		}
		
		
		chassis.transform.localEulerAngles = new Vector3(Random.Range(-1f,1f),Random.Range(-1f,1f),Random.Range(-1f,1f));
		
		camObj.transform.position = Vector3.Lerp(camObj.transform.position, camTarget.transform.position, 5f * Time.deltaTime);
		//camTarget.transform.eulerAngles = new Vector3(0,camTarget.transform.eulerAngles.y,camTarget.transform.eulerAngles.z);
		camObj.transform.rotation = Quaternion.Slerp(camObj.transform.rotation, camTarget.transform.rotation, 5f * Time.deltaTime);
		
		
	}
}
