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

public class ObjectsManager : MonoBehaviour
{
	[SerializeField]
	private float radius = 16f;

	[SerializeField]
	private GameObject[] energy;
	[SerializeField]
	private List<GameObject> smallEnergyObjects = new List<GameObject>();
	[SerializeField]
	private List<GameObject> medEnergyObjects = new List<GameObject>();
	[SerializeField]
	private List<int> energyIndexList = new List<int>();

	[SerializeField]
	private GameObject[] gamaRay;
	[SerializeField]
	private List<GameObject> smallGamaRayObjects = new List<GameObject>();
	[SerializeField]
	private List<GameObject> medGamaRayObjects = new List<GameObject>();
	[SerializeField]
	private List<GameObject> bigGamaRayObjects = new List<GameObject>();
	[SerializeField]
	private List<int> gamaIndexList = new List<int>();

	[SerializeField]
	private Transform objectsParent;

	[SerializeField]
	private int ammountOfObjects = 10;

	[SerializeField]
	private float energySpawnTime = 4f;
	[SerializeField]
	private float gamaSpawnTime = 10f;

	[Range(0, 0.1f)]
	[SerializeField]
	private float timeEnergyFrequencyDecay;

	[Range(0, 0.1f)]
	[SerializeField]
	private float timeGamaFrequencyDecay;

	void Awake()
	{
		InstantiateAllObjects();
	}

	void Update()
	{
		energySpawnTime -= timeEnergyFrequencyDecay * Time.deltaTime;
		gamaSpawnTime -= timeGamaFrequencyDecay * Time.deltaTime;

		if(energySpawnTime <= 0)
			energySpawnTime = 0;
		if(gamaSpawnTime <= 0)
			gamaSpawnTime = 0;
	}

	public void StartObjectsManager()
	{
		StartCoroutine("SpawnEnergy");
		StartCoroutine("SpawnGama");
		StartCoroutine("AddIndex");

		enabled = true;
	}

	public void StopObjectsManager()
	{
		StopCoroutine("SpawnEnergy");
		StopCoroutine("SpawnGama");
		StopCoroutine("AddIndex");

		Debug.Log("Stop objects");

		enabled = false;
	}

	IEnumerator AddIndex()
	{
		while(true)
		{
			yield return new WaitForSeconds(5);

			float rand = Random.Range(0f, 1f);

			if(rand >= 0 && rand < 0.2f)
			{
				energyIndexList.Add(0);
				gamaIndexList.Add(0);
			}
			else if(rand >= 0.2f && rand < 0.5f)
			{
				energyIndexList.Add(1);
				gamaIndexList.Add(1);
			}
			else if(rand >= 0.5f)
			{
				gamaIndexList.Add(2);
			}
		}
	}

	void InstantiateAllObjects()
	{
		for(int i = 0; i < energy.Length; i++)
		{
			for(int j = 0; j < ammountOfObjects; j++)
			{
				GameObject GO = (GameObject)Instantiate(energy[i], Vector3.zero, Quaternion.identity);

				GO.SetActive(false);

				GO.transform.SetParent(objectsParent);

				if(i == 0)
					smallEnergyObjects.Add(GO);
				else
					medEnergyObjects.Add(GO);
			}
		}

		for(int i = 0; i < gamaRay.Length; i++)
		{
			for(int j = 0; j < ammountOfObjects; j++)
			{
				GameObject GO = (GameObject)Instantiate(gamaRay[i], Vector3.zero, Quaternion.identity);

				GO.SetActive(false);

				GO.transform.SetParent(objectsParent);

				if(i == 0)
					smallGamaRayObjects.Add(GO);
				else if(i == 1)
					medGamaRayObjects.Add(GO);
				else
					bigGamaRayObjects.Add(GO);
			}
		}
	}

	IEnumerator SpawnEnergy()
	{
		while(true)
		{
			float angle = Random.Range(0f, 360f);

			angle = angle * Mathf.Deg2Rad;

			int index = energyIndexList[Random.Range(0, energyIndexList.Count - 1)];

			if(index == 0)
			{
				for(int i = 0; i < smallEnergyObjects.Count; i++)
				{
					if(!smallEnergyObjects[i].activeSelf)
					{
						smallEnergyObjects[i].transform.position = new Vector3(Mathf.Cos(angle) * radius, Mathf.Sin(angle) * radius, 0);

						smallEnergyObjects[i].SetActive(true);

						smallEnergyObjects[i].GetComponent<BaseObject>().SetDirection(-smallEnergyObjects[i].transform.position.normalized);

						break;
					}

					if(i == smallEnergyObjects.Count - 1)
					{
						//TODO
						GameObject GO = (GameObject)Instantiate(energy[0], new Vector3(Mathf.Cos(angle) * radius, Mathf.Sin(angle) * radius, 0), Quaternion.identity);

						GO.transform.SetParent(objectsParent);

						GO.GetComponent<BaseObject>().SetDirection(-smallEnergyObjects[i].transform.position.normalized);

						smallEnergyObjects.Add(GO);

						break;
					}
				}
			}
			else
			{
				for(int i = 0; i < medEnergyObjects.Count; i++)
				{
					if(!medEnergyObjects[i].activeSelf)
					{
						medEnergyObjects[i].transform.position = new Vector3(Mathf.Cos(angle) * radius, Mathf.Sin(angle) * radius, 0);

						medEnergyObjects[i].SetActive(true);

						medEnergyObjects[i].GetComponent<BaseObject>().SetDirection(-medEnergyObjects[i].transform.position.normalized);

						break;
					}

					if(i == medEnergyObjects.Count - 1)
					{
						//TODO
						GameObject GO = (GameObject)Instantiate(energy[0], new Vector3(Mathf.Cos(angle) * radius, Mathf.Sin(angle) * radius, 0), Quaternion.identity);

						GO.transform.SetParent(objectsParent);

						GO.GetComponent<BaseObject>().SetDirection(-medEnergyObjects[i].transform.position.normalized);

						medEnergyObjects.Add(GO);

						break;
					}
				}
			}
				
			Debug.LogWarning("Obj manager coroutine running!");
			yield return new WaitForSeconds(Random.Range(energySpawnTime, energySpawnTime + 2));
		}
	}

	IEnumerator SpawnGama()
	{
		while(true)
		{
			yield return new WaitForSeconds(Random.Range(gamaSpawnTime, gamaSpawnTime + 2));

			float angle = Random.Range(0f, 360f);

			angle = angle * Mathf.Deg2Rad;

			int index = gamaIndexList[Random.Range(0, gamaIndexList.Count - 1)];

			//Gama
			if(index == 0)
			{
				for(int i = 0; i < smallGamaRayObjects.Count; i++)
				{
					if(!smallGamaRayObjects[i].activeSelf)
					{
						smallGamaRayObjects[i].transform.position = new Vector3(Mathf.Cos(angle) * radius, Mathf.Sin(angle) * radius, 0);

						smallGamaRayObjects[i].SetActive(true);

						smallGamaRayObjects[i].GetComponent<BaseObject>().SetDirection(-smallGamaRayObjects[i].transform.position.normalized);

						break;
					}

					if(i == smallGamaRayObjects.Count - 1)
					{
						//TODO
						GameObject GO = (GameObject)Instantiate(gamaRay[0], new Vector3(Mathf.Cos(angle) * radius, Mathf.Sin(angle) * radius, 0), Quaternion.identity);

						GO.transform.SetParent(objectsParent);

						GO.GetComponent<BaseObject>().SetDirection(-smallGamaRayObjects[i].transform.position.normalized);

						smallGamaRayObjects.Add(GO);

						break;
					}
				}
			}
			else if(index == 1)
			{
				for(int i = 0; i < medGamaRayObjects.Count; i++)
				{
					if(!medGamaRayObjects[i].activeSelf)
					{
						medGamaRayObjects[i].transform.position = new Vector3(Mathf.Cos(angle) * radius, Mathf.Sin(angle) * radius, 0);

						medGamaRayObjects[i].SetActive(true);

						medGamaRayObjects[i].GetComponent<BaseObject>().SetDirection(-medGamaRayObjects[i].transform.position.normalized);

						break;
					}

					if(i == medGamaRayObjects.Count - 1)
					{
						//TODO
						GameObject GO = (GameObject)Instantiate(gamaRay[0], new Vector3(Mathf.Cos(angle) * radius, Mathf.Sin(angle) * radius, 0), Quaternion.identity);

						GO.transform.SetParent(objectsParent);

						GO.GetComponent<BaseObject>().SetDirection(-medGamaRayObjects[i].transform.position.normalized);

						smallGamaRayObjects.Add(GO);

						break;
					}
				}
			}
			else
			{
				for(int i = 0; i < bigGamaRayObjects.Count; i++)
				{
					if(!bigGamaRayObjects[i].activeSelf)
					{
						bigGamaRayObjects[i].transform.position = new Vector3(Mathf.Cos(angle) * radius, Mathf.Sin(angle) * radius, 0);

						bigGamaRayObjects[i].SetActive(true);

						bigGamaRayObjects[i].GetComponent<BaseObject>().SetDirection(-bigGamaRayObjects[i].transform.position.normalized);

						break;
					}

					if(i == bigGamaRayObjects.Count - 1)
					{
						//TODO
						GameObject GO = (GameObject)Instantiate(gamaRay[0], new Vector3(Mathf.Cos(angle) * radius, Mathf.Sin(angle) * radius, 0), Quaternion.identity);

						GO.transform.SetParent(objectsParent);

						GO.GetComponent<BaseObject>().SetDirection(-bigGamaRayObjects[i].transform.position.normalized);

						bigGamaRayObjects.Add(GO);

						break;
					}
				}
			}
		}
	}

	public void EmitGama(int type)
	{
		float angle = Random.Range(0f, 360f);

		angle = angle * Mathf.Deg2Rad;

		Vector3 dir = new Vector3(Mathf.Cos(angle), Mathf.Sin(angle), 0);

		if(type == 0)
		{
			for(int i = 0; i < smallGamaRayObjects.Count; i++)
			{
				if(!smallGamaRayObjects[i].activeSelf)
				{
					smallGamaRayObjects[i].transform.position = dir * 2f;

					smallGamaRayObjects[i].SetActive(true);

					smallGamaRayObjects[i].GetComponent<BaseObject>().SetDirection(dir);

					break;
				}

				if(i == smallGamaRayObjects.Count - 1)
				{
					//TODO
					GameObject GO = (GameObject)Instantiate(gamaRay[0], dir * 2f, Quaternion.identity);

					GO.transform.SetParent(objectsParent);

					GO.GetComponent<BaseObject>().SetDirection(dir);

					smallGamaRayObjects.Add(GO);

					break;
				}
			}
		}
		else if(type == 1)
		{
			for(int i = 0; i < medGamaRayObjects.Count; i++)
			{
				if(!medGamaRayObjects[i].activeSelf)
				{
					medGamaRayObjects[i].transform.position = dir * 2f;

					medGamaRayObjects[i].SetActive(true);

					medGamaRayObjects[i].GetComponent<BaseObject>().SetDirection(dir);

					break;
				}

				if(i == medGamaRayObjects.Count - 1)
				{
					//TODO
					GameObject GO = (GameObject)Instantiate(gamaRay[0], dir * 2f, Quaternion.identity);

					GO.transform.SetParent(objectsParent);

					GO.GetComponent<BaseObject>().SetDirection(dir);

					smallGamaRayObjects.Add(GO);

					break;
				}
			}
		}
		else
		{
			for(int i = 0; i < bigGamaRayObjects.Count; i++)
			{
				if(!bigGamaRayObjects[i].activeSelf)
				{
					bigGamaRayObjects[i].transform.position = dir * 2f;

					bigGamaRayObjects[i].SetActive(true);

					bigGamaRayObjects[i].GetComponent<BaseObject>().SetDirection(dir);

					break;
				}

				if(i == bigGamaRayObjects.Count - 1)
				{
					//TODO
					GameObject GO = (GameObject)Instantiate(gamaRay[0], dir * 2f, Quaternion.identity);

					GO.transform.SetParent(objectsParent);

					GO.GetComponent<BaseObject>().SetDirection(dir);

					bigGamaRayObjects.Add(GO);

					break;
				}
			}
		}
	}
}