using UnityEngine;
using System.Collections;

public class RampagingRhino : PoacherKiller {

	public ParticleSystem explosionPrefab; // inspector

	private float timeLeft = 10.0f;

	private float angleDelta;

	public Transform target;
	private float lifeTime = 0.0f;

	public Vector3 lastSendPosition = Vector3.zero; // Last position send to server
	public Quaternion lastRotation = Quaternion.identity;
	private int ID;

	private bool destroying = false;

	public void init(Vector3 loc) {

		// move to the given position
		transform.position = loc;

		// follow a target
		if (target != null) {
			Vector2 dir = new Vector2(target.position.x, target.position.z) - getLoc ();
			angle = Mathf.Atan2 (dir.y, dir.x);
			speed = Data.rhinoMaxSpeed * 1.5f;
		}
		
		// random direction
		else {
			angle = Random.Range (0, 2.0f * Mathf.PI);
			speed = Data.rhinoMaxSpeed * 0.5f;
		}

		angleDelta = Random.Range (-0.6f, 0.6f);
		this.ID = networkController.controller.GetNextRampagingRhinoID();
		if (target != null) {
			networkController.controller.SendSpawnRampagingRhino (this, true);
		} else {
			networkController.controller.SendSpawnRampagingRhino (this, false);
		}
	}

	public void Update() {


		float dt = Time.deltaTime;
		lifeTime += dt;

		if (destroying) {
			if (lifeTime > 15.0f) {
				Destroy (gameObject);
				return;
			}
			return;
		}
		// we got a target - turn towards him
		if (target != null) {

			// compute the target angle
			Vector2 targetDir = new Vector2(target.position.x, target.position.z) - getLoc ();
			float targetAngle = Mathf.Atan2 (targetDir.y, targetDir.x);
			float currentAngle = angle;

			// compute the rotation
			float totalRotation = targetAngle - currentAngle;
			while (totalRotation < -Mathf.PI) totalRotation += 2 * Mathf.PI;
			while (totalRotation > Mathf.PI) totalRotation -= 2 * Mathf.PI;
			float rotation = totalRotation / Mathf.Abs(totalRotation) * 0.5f * dt;
			float newAngle = currentAngle + rotation;
			angle = newAngle;

			// lived too long
			if (lifeTime > 40.0f) {
				// spawn an explosion
				ParticleSystem explosion = Instantiate (explosionPrefab) as ParticleSystem;
				explosion.transform.position = transform.position;
				Destroy (gameObject);
				return;
			}
		}
		
		// no target, just move
		else {
			angle += angleDelta * dt;
		}

		// update position
		transform.position = transform.position + new Vector3(speed * Mathf.Cos (angle) * dt, 0.0f, speed * Mathf.Sin (angle) * dt);

		timeLeft -= dt;
		if (timeLeft <= 0.0f) {
			networkController.controller.SendKillRampagingRhino (this);
			// spawn an explosion
			ParticleSystem explosion = Instantiate (explosionPrefab) as ParticleSystem;
			explosion.transform.position = transform.position;
			Destroy (gameObject);
		}

		// fix y-axis
		fixYAxis ();
		fixOrientation();
	}

	public int GetRampagingRhinoID() {
		return ID;
	}

	public bool NeedsUpdate() {
		bool needsUpdate = (lastSendPosition - transform.position).sqrMagnitude > 1.0f;
		/*|| ((lastRotation.eulerAngles - transform.rotation.eulerAngles).sqrMagnitude > 1.0f);*/
		return needsUpdate;
	}
	
	public void UpdateLastSendPosition() {
		lastSendPosition = transform.position;
	}

	public void OnTriggerEnter(Collider collider) {
		if (destroying) return; // don't trigger again on dying rhino's
		collider.SendMessage ("OnMadRhino", this, SendMessageOptions.DontRequireReceiver);
	}

	void OnDestroy() {
		networkController.controller.SendDestroyRampagingRhino (this);
	}

	public void destroy() {
		networkController.controller.SendKillRampagingRhino (this);
		// spawn an explosion
		ParticleSystem explosion = Instantiate (explosionPrefab) as ParticleSystem;
		explosion.transform.position = transform.position;
		destroying = true;
		lifeTime = 0.0f;
		rigidbody.isKinematic = false;
		rigidbody.velocity = new Vector3(Random.Range (-10, 10), Random.Range (35, 45), Random.Range (-10, 10));
		rigidbody.useGravity = true;
	}
}
