using UnityEngine;
using System.Collections;

public class ShipThrusters : MonoBehaviour {

	GameObject Station;

	GameObject ViewCam;
	Transform CockpitView;
	Transform OverheadView;
	TextMesh Text;
	float LookUpTime = 0f;
	float LookDownTime = 0f;

	GameObject ThrustStick;
	Vector3 ThrustStickNeutralPos;
	GameObject GimbalStick;
	Vector3 GimbalStickNeutralPos;

	GameObject Gimbal;
	GameObject GimbalTarget;

	GameObject ShipPort;
	GameObject StationPort;

	private float ThrustForce = 0.08f;
	private float Mult = 1f;

	// Use this for initialization
	void Start () {
		Station = GameObject.Find("Space Station");
		Gimbal = transform.Find("Gimbal").gameObject;
		GimbalTarget = transform.Find("GimbalTarget").gameObject;
		ThrustStick = transform.Find("ThrustStick").gameObject;
		ThrustStickNeutralPos = ThrustStick.transform.localPosition;
		GimbalStick = transform.Find("GimbalStick").gameObject;
		GimbalStickNeutralPos = GimbalStick.transform.localPosition;
		ViewCam = transform.Find("ViewCam").gameObject;
		CockpitView = transform.Find("CockpitView");
		OverheadView = transform.Find("OverheadView");
		// give the ship a bump so that you can't just line straight up
		/*
		Vector3 InitialOffset = new Vector3( Random.Range( -.1f, .1f ), Random.Range( -.1f, .1f ), Random.Range( -.1f, .1f ) );
		rigidbody.AddForce( Random.Range( -1f, 1f ), Random.Range( -1f, 1f ), Random.Range( -1f, 1f ) );
		rigidbody.MovePosition( transform.position + InitialOffset );
		GameObject.Find("Ship-Ring").transform.position += InitialOffset;
		*/

		Text = transform.Find("Stats").GetComponent<TextMesh>();

		ShipPort = GameObject.Find("Ship-Ring");
		StationPort = GameObject.Find("Space Station").transform.Find("Ring").gameObject;


		// TODO fudge for velocity
		Station.rigidbody.AddForce( Station.transform.up*0.5f, ForceMode.Impulse );
	}
	
	// Update is called once per frame
	void Update () {

		// set temp vars
		Vector3 RotOffset = Vector3.zero;
		Vector3 BaseRot = new Vector3( 0f, 0f, 90f );

		if ( Input.GetKey("left shift") ) {
			Mult = 5f;
		} else {
			Mult = 1f;
		}

		/* original mode
		// Pitch Yaw Roll controls
		if ( Input.GetKey("w") ) { // pitch down
			rigidbody.AddTorque( transform.forward*ThrustForce*Mult, ForceMode.Impulse );
			RotOffset.x += 10f;
		}
		if ( Input.GetKey("s") ) { // pitch up
			rigidbody.AddTorque( -transform.forward*ThrustForce*Mult, ForceMode.Impulse );
			RotOffset.x -= 10f;
		}
		if ( Input.GetKey("a") ) { // yaw right
			rigidbody.AddTorque( transform.right*ThrustForce*Mult, ForceMode.Impulse );
			RotOffset.z += 10f;
		}
		if ( Input.GetKey("d") ) { // yaw left
			rigidbody.AddTorque( -transform.right*ThrustForce*Mult, ForceMode.Impulse );
			RotOffset.z -= 10f;
		}
		if ( Input.GetKey("q") ) { // roll right
			rigidbody.AddTorque( -transform.up*ThrustForce*Mult, ForceMode.Impulse );
			RotOffset.y += 10f;
		}
		if ( Input.GetKey("e") ) { // roll left
			rigidbody.AddTorque( transform.up*ThrustForce*Mult, ForceMode.Impulse );
			RotOffset.y -= 10f;
		}
		*/
		// new mode
		// Pitch Yaw Roll controls
		if ( Input.GetKey("w") ) { // pitch down
			rigidbody.AddTorque( transform.right*ThrustForce*Mult, ForceMode.Impulse );

			RotOffset.x += 10f;
		}
		if ( Input.GetKey("s") ) { // pitch up
			rigidbody.AddTorque( -transform.right*ThrustForce*Mult, ForceMode.Impulse );

			RotOffset.x -= 10f;
		}
		if ( Input.GetKey("a") ) { // yaw right
			rigidbody.AddTorque( -transform.up*ThrustForce*Mult, ForceMode.Impulse );
			RotOffset.z += 10f;
		}
		if ( Input.GetKey("d") ) { // yaw left
			rigidbody.AddTorque( transform.up*ThrustForce*Mult, ForceMode.Impulse );
			RotOffset.z -= 10f;
		}
		if ( Input.GetKey("q") ) { // roll right
			rigidbody.AddTorque( transform.forward*ThrustForce*Mult, ForceMode.Impulse );
			RotOffset.y += 10f;
		}
		if ( Input.GetKey("e") ) { // roll left
			rigidbody.AddTorque( -transform.forward*ThrustForce*Mult, ForceMode.Impulse );
			RotOffset.y -= 10f;
		}

		// only rotation is needed for right stick
		GimbalStick.transform.localRotation = Quaternion.Slerp( GimbalStick.transform.localRotation, Quaternion.Euler( RotOffset+BaseRot ), 0.3f );


		//reset temp vars
		RotOffset = Vector3.zero;
		BaseRot = new Vector3( 0f, 0f, 90f );
		Vector3 PosOffset = Vector3.zero;

		/* original mode
		// Thrust controls
		if ( Input.GetKey("i") ) { // thrust forwards
			rigidbody.AddForce( transform.up*ThrustForce*Mult, ForceMode.Impulse );
			RotOffset.x += 10f;
		}
		if ( Input.GetKey("k") ) { // thrust backwards
			rigidbody.AddForce( -transform.up*ThrustForce*Mult, ForceMode.Impulse );
			RotOffset.x -= 10f;
		}
		if ( Input.GetKey("j") ) { // thrust left
			rigidbody.AddForce( -transform.forward*ThrustForce*Mult, ForceMode.Impulse );
			RotOffset.z += 10f;
		}
		if ( Input.GetKey("l") ) { // thrust right
			rigidbody.AddForce( transform.forward*ThrustForce*Mult, ForceMode.Impulse );
			RotOffset.z -= 10f;
		}
		if ( Input.GetKey("y") ) { // thrust up
			rigidbody.AddForce( transform.right*ThrustForce*Mult, ForceMode.Impulse );
			PosOffset += new Vector3( 0f, ThrustForce*Mult, 0f );
		}
		if ( Input.GetKey("h") ) { // thrust down
			rigidbody.AddForce( -transform.right*ThrustForce*Mult, ForceMode.Impulse );
			PosOffset += new Vector3( 0f, -0.02f, 0f );
		}
		*/

		// new mode
		// Thrust Controls
		if ( Input.GetKey("i") ) { // thrust forwards
			rigidbody.AddForce( transform.forward*ThrustForce*Mult, ForceMode.Impulse );
			RotOffset.x += 10f;
		}
		if ( Input.GetKey("k") ) { // thrust backwards
			rigidbody.AddForce( -transform.forward*ThrustForce*Mult, ForceMode.Impulse );
			RotOffset.x -= 10f;
		}
		if ( Input.GetKey("j") ) { // thrust left
			rigidbody.AddForce( -transform.right*ThrustForce*Mult, ForceMode.Impulse );
			RotOffset.z += 10f;
		}
		if ( Input.GetKey("l") ) { // thrust right
			rigidbody.AddForce( transform.right*ThrustForce*Mult, ForceMode.Impulse );
			RotOffset.z -= 10f;
		}
		if ( Input.GetKey("y") ) { // thrust up
			rigidbody.AddForce( transform.up*ThrustForce*Mult, ForceMode.Impulse );
			PosOffset += new Vector3( 0f, ThrustForce*Mult, 0f );
		}
		if ( Input.GetKey("h") ) { // thrust down
			rigidbody.AddForce( -transform.up*ThrustForce*Mult, ForceMode.Impulse );
			PosOffset += new Vector3( 0f, -0.02f, 0f );
		}


		ThrustStick.transform.localRotation = Quaternion.Slerp( ThrustStick.transform.localRotation, Quaternion.Euler( RotOffset+BaseRot ), 0.3f );
		ThrustStick.transform.localPosition = Vector3.Lerp( ThrustStick.transform.localPosition, ThrustStickNeutralPos+PosOffset, 0.3f );



		// No matter what way the ship is facing, align the gimbal to the world
		Gimbal.transform.rotation = Quaternion.Euler( 180f, 90f, 0f );
		GimbalTarget.transform.rotation = Quaternion.Euler( 180f, 180f, 0f )*Station.transform.rotation;



		// TODO put in a better place? TODO
		try {
			Text.text = "Closing Velocity:"+ VelocitySign()+Mathf.Abs(rigidbody.velocity.magnitude - Station.rigidbody.velocity.magnitude).ToString("F2") + "m/s";
		}
		catch {
			Text.text = "Closing Velocity: 0 m/s";
		}
		Text.text += "\nRange: "+ (ShipPort.transform.position - StationPort.transform.position).magnitude.ToString("F3") +"m";
		Text.text += "\nAlignment: "+ Vector3.Angle(transform.up, -Station.transform.up).ToString("F2") +"°";
		Text.text += "\n\nWASD+QE Pitch/Yaw/Roll\nIJKL+YH Thrust";
		Text.text += "\n\nR to restart\nT to increment difficulty\nSpace to look up";


		if ( Input.GetKey("space") ){
			LookUpTime += Time.deltaTime;
			LookDownTime = 0f;
			ViewCam.transform.rotation = Quaternion.Slerp( ViewCam.transform.rotation, OverheadView.rotation, LookUpTime );
			ViewCam.transform.position = Vector3.Lerp( ViewCam.transform.position, OverheadView.position, LookUpTime );
		} else {
			LookUpTime = 0f;
			LookDownTime += Time.deltaTime;
			ViewCam.transform.rotation = Quaternion.Slerp( ViewCam.transform.rotation, CockpitView.rotation, LookDownTime );
			ViewCam.transform.position = Vector3.Lerp( ViewCam.transform.position, CockpitView.position, LookDownTime );
		}


		/*

		// TODO put in a better place later: TODO
		if ( Input.GetKeyDown("c") ) {
			if ( cam1.activeInHierarchy ) {
				cam1.SetActive(false);
				cam2.SetActive(true);
			} else {
				cam1.SetActive(true);
				cam2.SetActive(false);
			}
		}

		*/

		if ( Input.GetKeyDown("r") ) {
			Application.LoadLevel(0);
		}
		if ( Input.GetKeyDown("t") ) {
			Difficulty.Increment();
			Application.LoadLevel(0);
		}
	}

	string VelocitySign() {

		if ( Vector3.Angle( rigidbody.velocity, Station.rigidbody.velocity ) > 90f ) {
			return "+";
		} else {
			return "-";
		}
	}
}
