using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class Unit : MonoBehaviour
{
	public int 			m_Speed = 50;
	public Vector3 		m_Target;
	public bool 		m_IsMoving = true;
	
	//Lameway pathfinding
	public int 			m_CurrentZone {get;private set;}
	private List<Zone> 	m_Zones;
	private int 		m_PreviousZone;
	
	//Stress & explosion
	public float 		m_StressMeter;
	private float 		m_StressTolerance;
	public GameObject 	m_Explosion;
	public bool			m_DoNotStress = false;
	
	//FIRE IN THE HOLE
	public GameObject	m_Fire;
	public GameObject	m_FlameCorpse;
	public GameObject	m_FlamesOnTop;
	private GameObject 	m_MyFlame;
	public bool			m_OnFire;
	
	//Animation
	public List<Material> m_Materials;
	private float m_AnimTimer; //1 loop per second
	private float m_TimePerFrame = 0.20f;
	
	// Use this for initialization
	void Start () 
	{
		m_Speed = Random.Range(40,80); 
		m_StressMeter = 0;
		m_StressTolerance = (float)Random.Range(10,300);
		m_StressTolerance /= 100;
		m_OnFire = false;
		
		//Let's be a random character
		int matId = Random.Range (0, m_Materials.Count);
		gameObject.GetComponent<MeshRenderer>().material = m_Materials[matId];
	}
	
	void OnDestroy()
	{
		Destroy(m_MyFlame);
	}
	
	//Post construction
	public void SetZones(List<Zone> zones, int currentZone)
	{
		m_Zones = zones;
		m_CurrentZone = currentZone;
		
		//Set the position to a random target
		transform.position = CreateRandomTarget();
		
		//Then set the target
		m_Target = CreateRandomTarget();
		
	}
	
	// Update is called once per frame
	private void Update () 
	{
		Move();
		HandleStress();
		HandleAnimtion();
		HandleFire();
	}
	
	private void Move()
	{
		gameObject.GetComponent<Rigidbody>().velocity = new Vector3(0,0,0);
		
		//move unit
		if (m_IsMoving)
		{
			Vector3 velocity, direction;
			direction = m_Target - transform.position;
			direction.Normalize();
			velocity = direction * m_Speed * Time.deltaTime;
		
			transform.position += velocity;
		
			//Make our character look at the direction he is walking in
			transform.LookAt(m_Target);
			
			//ShouldIStop();
			
			if(IsAtTarget())
				m_Target = CreateRandomTarget();
		}
	}
	
	private bool IsAtTarget()
	{
		if(Vector3.Distance(transform.position,m_Target) < 10) return true;
		return false;
	}
	
	public Vector3 CreateRandomTarget()
	{
		m_PreviousZone = m_CurrentZone;
		m_CurrentZone = m_Zones[m_CurrentZone].GetNeighbour(m_PreviousZone);

		int randX = (int)Random.Range(m_Zones[m_CurrentZone].GetSize().x + 5, m_Zones[m_CurrentZone].GetSize().x + m_Zones[m_CurrentZone].GetSize().width - 5);
		int randY = (int)Random.Range(m_Zones[m_CurrentZone].GetSize().y + 5, m_Zones[m_CurrentZone].GetSize().y + m_Zones[m_CurrentZone].GetSize().height -5);
		
		return new Vector3(randX, 10, randY);
	}
	
	private void ShouldIStop()
	{
		float rand = Random.Range(0,100);
		if(rand > 50)
		{
			m_IsMoving = !m_IsMoving;
			m_Target = CreateRandomTarget();
		}
	}
	
	void HandleStress()
	{
		if(!m_OnFire)
		{
			float rand = (float)Random.Range(0,500);
			rand /= 100;
			if(!m_DoNotStress)
				m_StressMeter += (Time.deltaTime * rand)/m_StressTolerance;
			if(m_StressMeter>= 100)
			{
				GameObject.Find("Radio").GetComponent<Radio>().MaleScream();
				Vector3 pos = transform.position;
				pos.y = 12;
				Instantiate(m_Explosion,pos,transform.rotation);
				Destroy(gameObject);	
			}	
		}
	}
	
	void HandleFire()
	{
		if(m_OnFire)
		{	
			m_StressMeter += Time.deltaTime;
			if(m_StressMeter >= 5.0f)
			{
				//Burn out (die)
				Destroy(m_MyFlame);
				Vector3 corpsePos = transform.position;
				corpsePos.y = 8;
				Instantiate(m_FlameCorpse, corpsePos, transform.rotation);
				Destroy(gameObject);
			}
			m_MyFlame.transform.position = transform.position;
		}
	}
	
	public void StartFire()
	{
		if(!m_OnFire)
		{
			GameObject.Find("Radio").GetComponent<Radio>().MaleScream();
			m_OnFire = true;
			GameObject newFlame =  (GameObject)Instantiate(m_Fire);
			gameObject.GetComponent<CapsuleCollider>().isTrigger = true;
			m_MyFlame = newFlame;
			m_StressMeter = 0;
			m_Speed = 200;
			
			//GameObject flames = (GameObject)Instantiate(m_FlamesOnTop);
			//flames.transform.parent = transform;
		}
	}
	
	public void SetOnFire()
	{
		if(!m_OnFire)
		{
			GameObject.Find("Radio").GetComponent<Radio>().MaleScream();
			m_OnFire = true;
			GameObject newFlame =  (GameObject)Instantiate(m_Fire);
			m_MyFlame = newFlame;
			m_StressMeter = 0;
			m_Speed = 200;	
			
			
			//GameObject flames = (GameObject)Instantiate(m_FlamesOnTop);
			//flames.transform.parent = transform;
		}
	}
	
	void OnTriggerEnter(Collider coll)
	{
		if(m_OnFire)
		{
			if(coll.gameObject.tag=="Unit")
				coll.gameObject.GetComponent<Unit>().SetOnFire();
			else if(coll.gameObject.GetComponent<Hero>()!=null)
			{
				coll.gameObject.GetComponent<Hero>().DestroyMe();
			}
		}
	}
	
	private void HandleAnimtion()
	{
		//Check if we are not moving, in that case reset the offset
		if (!m_IsMoving)
		{
			renderer.material.SetTextureOffset("_MainTex", new Vector2(0.0f, 0.0f));
			return;
		}
		
		//Increase the animation timer
		m_AnimTimer += Time.deltaTime;
		
		//Once we have to swap frame
		if (m_AnimTimer >= m_TimePerFrame)
		{
			//Get the x offset of the texture & increase it
			float offset = renderer.material.GetTextureOffset("_MainTex").x;
			offset += 0.25f;
			if (offset >= 1.0f) offset = 0.0f;
			
			//Set the new offset
			renderer.material.SetTextureOffset("_MainTex", new Vector2(offset, 0.0f));
			
			//Reset timer
			m_AnimTimer = 0.0f;
		}
	}	
}