using UnityEngine;
using System.Collections;

public class Rhino : PoacherKiller {

	public Camera camera; // inspector

	public float hunger { get; private set;}

	public int treasures { get; private set;}

	private World world;

	// Use this for initialization
	void Start () {
		treasures = 0;
		hunger = 1;
		body = GetComponent<Rigidbody> ();
		speed = 0.0f;
		angle = Random.Range (0, 2.0f * Mathf.PI);
	}

	public void Init (World world) {
		this.world = world;
	}

	// Update is called once per frame
	void Update () {
		float dt = Time.deltaTime;

		// accelerate?
		float acceleration = 0.0f;
		if (Input.GetKey ("up")) {
			speed += Data.rhinoMoveAcceleration;
			//acceleration += Data.rhinoMoveAcceleration;
		}
		else if (Input.GetKey ("down")) {
			speed -= Data.rhinoMoveDeceleration;
			//acceleration -= Data.rhinoMoveDeceleration;
		}
		else {
			speed -= Data.rhinoMoveAcceleration;
		}

		if (speed < Data.rhinoMinSpeed) speed = Data.rhinoMinSpeed;
		if (speed > Data.rhinoMaxSpeed) speed = Data.rhinoMaxSpeed;
		//body.velocity = new Vector2(speed * Mathf.Cos (angle), speed * Mathf.Sin (angle));

		// turn left/right
		if (Input.GetKey ("left")) {
			angle += Data.rhinoTurnSpeed * dt;
		}
		if (Input.GetKey ("right")) {
			angle -= Data.rhinoTurnSpeed * dt;
		}

		//body.velocity = new Vector2 (body.velocity.x + acceleration * Mathf.Cos (angle), body.velocity.y + acceleration * Mathf.Sin (angle));
		/*body.velocity = new Vector2 (speed * Mathf.Cos (angle), speed * Mathf.Sin (angle));
		if (body.velocity.magnitude > Data.rhinoMaxSpeed)
						body.velocity = body.velocity.normalized * Data.rhinoMaxSpeed;
*/
		transform.position = new Vector3 (transform.position.x + speed * Mathf.Cos (angle) * dt, transform.position.y, transform.position.z + speed * Mathf.Sin (angle) * dt);
		// move
		//Vector2 direction = new Vector2(Mathf.Cos (angle), Mathf.Sin (angle));
		//transform.position = new Vector2(transform.position.x + speed * direction.x, transform.position.y + speed * direction.y);

		// rotate
		transform.rotation = Quaternion.identity;
		transform.RotateAround (Vector3.down, angle - Mathf.PI / 2.0f);

		// fix y-axis
		fixYAxisRhino ();
		fixOrientation();

		// reduce hunger
		hunger -= Data.foodHungerSpeed * dt;

		if (hunger <= 0.0f) {
			CreditsController.rhinosSaved = treasures;
			Application.LoadLevel ("credits");
		}
	}
	
	public override void addPoacherHit() {
		this.hunger -= Data.foodHungerSpeed * 10.0f * Time.deltaTime;
	}

	public void fixYAxisRhino() {
		float dt = Time.deltaTime;
		
		// update our y-axis by doing a raycast for terrain
		Ray ray = new Ray (transform.position + new Vector3(0, 500, 0), new Vector3(0, -1, 0));
		RaycastHit hitInfo;
		if (Physics.Raycast (ray, out hitInfo, float.MaxValue, 1 << 9)) {
			Vector3 p = hitInfo.point;

			// too big a difference - we bounce!
			if (p.y > transform.position.y + 1.5f) {
				float ourAngle = angle;
				float theirAngle = Mathf.Atan2 (hitInfo.normal.y, hitInfo.normal.x);
				float dAngle = Mathf.DeltaAngle(ourAngle, theirAngle);

				// reflect the angle if this is a brush, stop if this is a straight ahead
				//if (dAngle >= Mathf.PI/4.0f) {
					angle += Mathf.PI;
				/*}
				else {
					// move back a bit
					transform.position = new Vector3 (transform.position.x - speed * Mathf.Cos (angle) * dt * 5.0f, 0.0f, transform.position.z - speed * Mathf.Sin (angle) * dt * 5.0f);
					speed = 0;
				}*/
				transform.position = new Vector3 (transform.position.x + speed * Mathf.Cos (angle) * dt, 0.0f, transform.position.z + speed * Mathf.Sin (angle) * dt);
			}
			else {
				transform.position = new Vector3(transform.position.x, hitInfo.point.y + transform.localScale.y / 2.0f, transform.position.z);
			}
		}
	}

	public void OnFood(Food food) {
		//SoundPlayer.player.PlayFoodPickup ();
		hunger += food.value;
		if (hunger > 1.0f) hunger = 1.0f;
		world.RemoveFood (food);
	}

	
	public void OnTreasure(Treasure treasure) {
		SoundPlayer.player.PlayRhinoRelease ();
		int rhinosFreed = world.RemoveTreasure (treasure);
		treasures += rhinosFreed;
		networkController.controller.UpdateRhinoScore (treasures);
		Destroy (treasure.gameObject);
	}

	public void OnDestructibleTerrain(ChildExploder exploder) {
		exploder.explode ();
	}

	public void OnTriggerEnter(Collider collider) {
	}

	public void OnMadRhino(RampagingRhino madRhino) {
		this.hunger -= 0.25f;
		madRhino.destroy();
	}
}
