using UnityEngine;
using System.Collections.Generic;

public class InfintyQueue : MonoBehavclops
{

	private class QueueSphereInfo
	{
		public Transform transform;
		public float age;

		public QueueSphereInfo(ElementalSphere sphere)
		{
			this.transform = sphere.transform;
			age = 0f;
		}
	}

	new public ParticleSystem particleSystem;
	public float sphereLapTime = 10f;

	private ParticleSystem.Particle[] _particles;
	private Dictionary<ElementalSphere, QueueSphereInfo> _spheres;

	public void Awake()
	{
		_spheres = new Dictionary<ElementalSphere, QueueSphereInfo>();
	}

	public void Update()
	{
		PositionParticles();
		PositionSpheres();
	}

	public void SphereWasPickedUp(ElementalSphere sphere)
	{
		sphere.WasDropped += SphereWasDropped;
	}

	public void SphereWasDropped(ElementalSphere sphere)
	{
		if (_spheres.ContainsKey(sphere)) return;
		var info = new QueueSphereInfo(sphere);
		_spheres[sphere] = info;
		sphere.IsTriggerable = true;
		sphere.WillEnd += SphereWillEnd;
		var delta = info.transform.position - Cached<Transform>().position;
		if (delta.x > 0f) {
			if (delta.y > 0f) {
				info.age = Mathf.Clamp(delta.x, 0f, 1f) * 0.25f;
			} else {
				info.age = 0.25f + (1f - Mathf.Clamp(delta.x, 0f, 1f)) * 0.25f;
			}
		} else{
			if (delta.y > 0f) {
				info.age = 0.5f + Mathf.Clamp(Mathf.Abs(delta.x), 0f, 1f) * 0.25f;
			} else {
				info.age = 0.75f + (1f - Mathf.Clamp(Mathf.Abs(delta.x), 0f, 1f)) * 0.25f;
			}
		}
		info.age *= sphereLapTime;
	}

	public void SphereWillEnd(ElementalSphere sphere)
	{
		if (!_spheres.ContainsKey(sphere)) return;
		_spheres.Remove(sphere);
	}

	private void PositionSpheres()
	{
		Vector3 pos = Vector3.zero;
		float t;
		foreach(KeyValuePair<ElementalSphere,QueueSphereInfo> kvp in _spheres) {
			kvp.Value.age += Time.deltaTime;
			if (kvp.Value.age > sphereLapTime) kvp.Value.age -= sphereLapTime;
			if (kvp.Value.age < sphereLapTime * 0.5f) kvp.Key.direction = Direction.Clockwise;
			else kvp.Key.direction = Direction.CounterClockwise;
			t = kvp.Value.age / sphereLapTime;
			pos.x = 2f * Mathf.Sin(t * Mathf.PI * 2f);
			pos.y = 1.2f * Mathf.Sin(t * Mathf.PI * 4f);
			pos.z = -1f;
			pos += Cached<Transform>().position;
			kvp.Value.transform.position = Vector3.Lerp(kvp.Value.transform.position, pos, 10f * Time.deltaTime);
		}
	}

	private void PositionParticles()
	{
		var pos = Vector3.zero;
		var rot = 0f;
		_particles = new ParticleSystem.Particle[particleSystem.particleCount];
		particleSystem.GetParticles(_particles);
		ParticleSystem.Particle particle;
		float t;
		for(int i = 0; i < _particles.Length; i++) {
			particle = _particles[i];
			t = (particle.startLifetime - particle.lifetime) / particle.startLifetime;
			pos.x = 2f * Mathf.Sin(t * Mathf.PI * 2f);
			pos.y = 1.2f * Mathf.Sin(t * Mathf.PI * 4f);
			// pos += (Vector3)Random.insideUnitCircle * 0.03f;
			rot = 45f + Mathf.Sin(t * Mathf.PI * 0.5f) * 360f;
			particle.position = pos;
			particle.rotation = rot;
			_particles[i] = particle;
		}
		particleSystem.SetParticles(_particles, _particles.Length); 
	}

}
