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

public class Spawner : MonoBehaviour 
{
	public GameObject[] m_Spawnables;
	public string[]	    m_WaveDefs;
	
	Vector3 		    m_vPos;

	List<SpawnerWave>   m_Waves			 = new List<SpawnerWave>();
	int					m_iCurrentWave	 = -1;	
	int					m_iNextWave		 = 0;
	int					m_iCurrentWaveSpawn=0;
	float			    m_fTimeWithinWave= 0.0f;
	float				m_fOverallTime	 = 0.0f;
	
	
	// Use this for initialization
	void Start () 
	{
		renderer.enabled = false;		
		m_vPos = transform.localPosition;
		m_vPos.y = 0.0f;
	
		// Parse 
		foreach( string str in m_WaveDefs )
		{
			char[] delimiters = {','};
			string[] tokens = str.Split(delimiters);
			
			if ( tokens.Length==4 )
			{
				float fSpawnTime = float.Parse( tokens[0] );
				float fSpawnDuration = float.Parse ( tokens[1] );
				int   iCount	 = int.Parse( tokens[2] );				
				m_Waves.Add( new SpawnerWave( fSpawnTime, fSpawnDuration, iCount, tokens[3] ) );
			}
		}
	}
	
	// Update is called once per frame
	void Update () 
	{	
		float fTimeStep = Time.deltaTime;
		m_fOverallTime+=fTimeStep;
		
		if ( m_iCurrentWave<0 )
		{
			if ( m_iNextWave<m_Waves.Count )
			{
				if ( m_fOverallTime >= m_Waves[m_iNextWave].m_fSpawnTime )
				{
					// Activate next wave
					m_iCurrentWave=m_iNextWave;
					m_iCurrentWaveSpawn=0;
					m_fTimeWithinWave = 0.0f;
					m_iNextWave++;
				}
			}
		}
		else
		{			
			m_fTimeWithinWave += fTimeStep;
			
			// Ready for the next spawn?
			SpawnerWave wave = m_Waves[m_iCurrentWave];
			
			bool bSpawned;
			do
			{				
				bSpawned = false;
				float fSpawnSpacing = wave.m_fSpawnDuration / (float)wave.m_iSpawnCount;
				float fTargetTime = fSpawnSpacing * (float)m_iCurrentWaveSpawn;
				
				if ( m_fTimeWithinWave>=fTargetTime )
				{
					// Spawn it
					int iIdx = 0;
					GameObject level = GameController.GetInstance().GetActiveLevel();
					GameObject nme = Instantiate( m_Spawnables[iIdx] ) as GameObject;
					
					nme.transform.parent = level.transform;
					wave.SetTransform( this.gameObject, nme, m_iCurrentWaveSpawn );

					bSpawned = true;
					m_iCurrentWaveSpawn++;
					if ( m_iCurrentWaveSpawn>=wave.m_iSpawnCount )
					{
						// Make all spawners loop forever
						if ( m_iCurrentWave == m_Waves.Count-1 )
						{
							m_iNextWave=0;
							m_fOverallTime = 0.0f;
						}
						m_iCurrentWave = -1;												
					}
				}						
			} while(bSpawned && m_iCurrentWave>=0);
		}						
	}
}


class SpawnerWave
{
	public float m_fSpawnTime;
	public float m_fSpawnDuration;
	public float m_iSpawnCount;
	
	public SpawnerWave( float fSpawnTime, float fDuration, int iCount, string strPattern )
	{
		m_fSpawnTime = fSpawnTime;
		m_fSpawnDuration = fDuration;
		m_iSpawnCount = iCount;
	}
	
	public void SetTransform( GameObject spawner, GameObject obj, int iSpawnIdx )
	{		
		float fRadius = 0.5f*spawner.transform.localScale.x;
		float fA      = (float)iSpawnIdx / (float)m_iSpawnCount;
		
		Vector3 vPos = spawner.transform.localPosition;
		vPos.y = 0.0f;
		Quaternion qRot;
		
		// Outer ring
		vPos.x += fRadius * Mathf.Sin( fA*Mathf.PI*2.0f );
		vPos.z += fRadius * Mathf.Cos( fA*Mathf.PI*2.0f );
		qRot = Quaternion.Euler( 0.0f, fA*360.0f, 0.0f );
				
		obj.transform.localPosition = vPos;
		obj.transform.localRotation = qRot;			
	}
}
