using UnityEngine;
using System.Collections;

public class Enemy : MonoBehaviour 
{
	public float m_SpeedVariance = 0.65f;
	public float m_TopSpeed		 = 10.0f;
	public float m_Accel		 = 1.0f;
	public float m_Drag			 = 1.0f;
	public float m_CollisionRadius=1.0f;
	public int	 m_HP			  = 2;
	public int   m_Score		 = 250;
	public bool  m_Spin			 = true;
	
	public float m_ShootInterval= 0.0f;
	public int   m_NumShots      = 5;
	
	
	float 	   m_fSpawnDuration = 2.0f;	
	
	GameObject m_SpawnWarning;
	GameObject m_MainMesh;
	GameObject m_Kaboom;
	Vector3	   m_vInitialScale;
	
	float	   m_fSpeedScale;
	float	   m_fTopSpeed;
	float	   m_fCollisionRadiusSquared;
	float      m_fSpinSpeed;
	
	int		   m_iHitPoints = 0;
	bool	   m_bDead = false;
	float	   m_fDespawnTimer = 1.5f;
	
	float      m_fNextVolley = 0.0f;
	
	// Use this for initialization
	void Awake () 
	{
		m_iHitPoints = m_HP;
		
		m_SpawnWarning = Util.FindChild( this.gameObject, "SpawnWarning" );
		m_SpawnWarning.SetActive(false);
		m_MainMesh	   = Util.FindChild( this.gameObject, "MainMesh" );		
		m_MainMesh.SetActive(false);
		m_Kaboom	   = Util.FindChild( this.gameObject, "Kaboom" );		
		m_Kaboom.SetActive(false);
		m_vInitialScale = m_MainMesh.transform.localScale;
		
		collider.enabled = false;
			
		m_fSpeedScale = Random.Range( 1.0f-m_SpeedVariance, 1.0f+m_SpeedVariance );
		m_fTopSpeed   = m_TopSpeed*m_fSpeedScale;
		
		m_fSpinSpeed = Random.Range( 30.0f, 80.0f );
		if ( Random.Range(0,2) == 1 ) m_fSpinSpeed=-m_fSpinSpeed;
		
		m_fCollisionRadiusSquared = m_CollisionRadius*m_CollisionRadius;
		
		m_fNextVolley = m_ShootInterval;
	}
	
	
	// Update is called once per frame
	void Update () 
	{
		GameController gc = GameController.GetInstance();
		float fTimeStep = Time.deltaTime;		
		GameObject p = null;
		Player ps = null;
		
		if ( gc!=null )
		{		
			p = gc.GetPlayer();			
			
			if (p!=null)
			{
				ps = p.GetComponent<Player>();
			}
		}
				
			
		if (m_bDead)
		{
			m_fDespawnTimer-=Time.deltaTime;
			
			if ( m_fDespawnTimer<0.0f )
			{
				Object.Destroy( this.gameObject );
			}
		}
		else
		{
			
			
			// Animation
			if ( m_Spin )
			{
				m_MainMesh.transform.Rotate( 0.0f, m_fSpinSpeed*fTimeStep, 0.0f );				
			}
			
			// Spawning
			if ( m_fSpawnDuration > 0.0f )
			{
				float fAlpha = 1.0f;
				if ( m_fSpawnDuration>1.5f ) fAlpha = (2.0f-m_fSpawnDuration)*2.0f;
				if ( m_fSpawnDuration<0.5f ) fAlpha = m_fSpawnDuration*2.0f;
				
				UnityEngine.Material mtl = m_SpawnWarning.renderer.material;
				Vector4 col = new Color(1.0f, 0.3f, 0.3f, fAlpha*0.7f );
				mtl.SetColor("_Color", col );
				m_SpawnWarning.renderer.material = mtl;
				
				m_fSpawnDuration -= Time.deltaTime;
				
				Quaternion q = Quaternion.Euler( 0.0f, m_fSpawnDuration*180.0f, 0.0f );
				m_SpawnWarning.transform.localRotation = q;
				m_SpawnWarning.SetActive(true);
				
				if ( m_fSpawnDuration < 0.0f )
				{
					m_fSpawnDuration = 0.0f;
					Object.Destroy( m_SpawnWarning.gameObject );			
				}
				
				
				if ( m_fSpawnDuration>1.0f )
				{
					m_MainMesh.SetActive(false);
				}
				else
				{
					collider.enabled = true;
					m_MainMesh.SetActive(true);
					
					float fScale = 1.0f-m_fSpawnDuration;				
					
					fScale += (Mathf.Sin( fScale*Mathf.PI )*1.0f);
					
					m_MainMesh.transform.localScale = m_vInitialScale * fScale;
				}
			}		
			else
			{	
				// Movement
				if ( gc!=null )
				{					
					Vector3 vOfs = p.transform.localPosition-transform.localPosition;
					vOfs.Normalize();
						
					float fAccScale = 0.25f*m_Accel*m_fSpeedScale;
					
					Vector3 vVel = rigidbody.velocity;
					Vector3 vNewVel = vVel * (1.0f-(fTimeStep*0.5f*m_Drag));			
					
					if ( !p.GetComponent<Player>().IsDead() )
					{
						vNewVel += fAccScale*vOfs;
					}
					
					if ( vNewVel.magnitude > m_fTopSpeed )
					{
						vNewVel.Normalize();
						vNewVel = vNewVel * m_fTopSpeed;
					}
					
					Vector3 vDV = vNewVel - vVel;
					
					rigidbody.AddForce( vDV, ForceMode.VelocityChange );						
					
					gc.AddActiveHPS( fTimeStep * (float)m_iHitPoints );
				}
				
				// Shooting
				if ( m_ShootInterval>0.0f )
				{
					m_fNextVolley-=fTimeStep;
					if ( m_fNextVolley<= 0.0f )
					{
						AudioSource asrc = this.GetComponent<AudioSource>();
						if ( asrc!=null ) asrc.Play();
						
						float fA = 0.0f;
						float fAngleStep = (360.0f)/(float)(m_NumShots);
						for( int i=0; i<m_NumShots;i++)
						{
							GameObject src = gc.GetEnemyBullet();
							
							// Spawn it
							GameObject bullet = Instantiate( src ) as GameObject;
							bullet.transform.parent = gc.GetActiveLevel().transform;
							bullet.transform.localPosition = transform.localPosition;
							bullet.transform.localRotation = m_MainMesh.transform.localRotation;	
							bullet.transform.Rotate(0.0f, fA, 0.0f);
								
							
							fA+=fAngleStep;
						}
						
						// Fire!
						m_fNextVolley = m_ShootInterval;
					}
				}
			}
		
		
			if ( m_fSpawnDuration<=0.5f )
			{
				// Bullet collisions
				foreach( Bullet b in Bullet.s_AllBullets )
				{
					if ( b.m_PlayerShot )
					{
						Vector3 vOfs = b.transform.localPosition-transform.localPosition;
						
						if ( vOfs.sqrMagnitude < m_fCollisionRadiusSquared )
						{
							b.OnHitTarget();
							
							m_iHitPoints--;
							
							if ( m_iHitPoints<=0 )
							{
								DoDeath();
							}
						}
					}
				}
				
				if ( ps!=null )
				{
					Vector3 vOfs = ps.transform.localPosition-transform.localPosition;
					
					if ( vOfs.sqrMagnitude < m_fCollisionRadiusSquared )
					{
						ps.Dead();
					}				
				}
			}
		}
	}
	
	
	void DoDeath()
	{
		m_bDead = true;
		collider.enabled = false;
		rigidbody.velocity = new Vector3(0,0,0);
		
		GameController.GetInstance().AddScore( m_Score, true, transform.localPosition );		
		
		m_MainMesh.SetActive(false);		
		if ( m_Kaboom!=null) m_Kaboom.SetActive(true);
		
		// Spawn coin
		GameObject coin = GameController.GetInstance().GetCoin( (m_Score>700) );
		
		GameObject inst = Instantiate( coin ) as GameObject;
		inst.transform.parent = GameController.GetInstance().GetActiveLevel().transform;
		inst.transform.localPosition = transform.localPosition;
		inst.transform.localRotation = Quaternion.identity;
	}
}
