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

public class SequenceGenerator : MonoBehaviour {

	public Rail railQ;
	public Rail railW;
	public Rail railE;
	public Rail railR;
	public Rail railT;

	public Rail railLeft;
	public Rail railUp;
	public Rail railRight;

	public int geturesCountMin;
	public int gesturesCountMax;

	Rail[] gesturesRails = new Rail[5];
	Rail[] shoutsRails = new Rail[3];

	Cycle[] cycles;

	Cycle currentCycle;

	float cycleStartTime = 0f;

	bool wasUsed = false;

	readonly Dictionary<int, CharacterAnimationController.AnimationType> _railToAnimationMap = new Dictionary<int, CharacterAnimationController.AnimationType>()
	{
		{0, CharacterAnimationController.AnimationType.Salut},
		{1, CharacterAnimationController.AnimationType.ChestBeat},
		{2, CharacterAnimationController.AnimationType.Kiss},
		{3, CharacterAnimationController.AnimationType.Wave},
		{4, CharacterAnimationController.AnimationType.HandsUp},
	};

	// Use this for initialization
	void Start () {
		gesturesRails [0] = railQ;
		gesturesRails [1] = railW;
		gesturesRails [2] = railE;
		gesturesRails [3] = railR;
		gesturesRails [4] = railT;

		shoutsRails [0] = railLeft;
		shoutsRails [1] = railUp;
		shoutsRails [2] = railRight;

		cycles = GetComponentsInChildren<Cycle> (true);
		StartCoroutine (CoIterateCycles ());
		StartCoroutine (CoWaitAndStart ());
	}

	IEnumerator CoWaitAndStart()
	{
		yield return new WaitForSeconds (1f);
		GenerateSequence ();
	}

	IEnumerator CoIterateCycles()
	{
		foreach (var itCycle in cycles) 
		{
			wasUsed = false;
			currentCycle = itCycle;

			while (wasUsed == false) 
			{
				yield return null;
			}

			yield return new WaitForSeconds (itCycle.lifetime);
		}
	}

	public void GenerateSequence()
	{
		StartCoroutine (CoGenerateSequence ());
	}

	IEnumerator CoGenerateSequence()
	{
		wasUsed = true;
		Cycle cycle = currentCycle;

		int numberOfGestures = Random.Range (cycle.gesturesCountMin, cycle.gesturesCountMax + 1);

		int shoutsCount = cycle.shoutsCount;

		bool[] shoutsPlaces = new bool[numberOfGestures];
		for (int i = 0; i < shoutsCount; i++) 
		{
			bool isSuccess = false;
			while (isSuccess == false) 
			{
				int randomId = Random.Range (0, numberOfGestures);
			
				if (shoutsPlaces[randomId] == false) 
				{
					isSuccess = true;
					shoutsPlaces [randomId] = true;
				}
			}
		}

		for (int i = 0; i < numberOfGestures; i++) 
		{
			if (shoutsPlaces[i]) 
			{
				int shoutId = Random.Range (0, 3);
				shoutsRails [shoutId].SpawnHandle ();
			}

			bool[] occupiedRails = new bool[5];

			int falseGesturesNumber = Random.Range (cycle.wrongGesturesMin, cycle.wrongGesturesMax + 1);
		    for (int j = 0; j < falseGesturesNumber; j++)
		    {
		        bool isSucess = false;
		        int flsgestureId = 0;
		        while (isSucess == false)
		        {
		            flsgestureId = Random.Range(cycle.leftRailRange - 1, cycle.rightRailRange);
		            if (occupiedRails[flsgestureId] == false)
		            {
		                isSucess = true;
		                occupiedRails[flsgestureId] = true;
		            }
		        }
		        gesturesRails[flsgestureId].SpawnFalseHandle();
		    }
		    int gestureId = 0;
			bool isSucessG = false;
			while (isSucessG == false) 
			{
				gestureId = Random.Range (cycle.leftRailRange - 1, cycle.rightRailRange);
				if (occupiedRails [gestureId] == false)
				{
					isSucessG = true;
					occupiedRails [gestureId] = true;
				}
			}
			CharacterAnimationController.instance.PlayAnimation (_railToAnimationMap [gestureId]);
			gesturesRails [gestureId].SpawnHandle ();
			float delay = Random.Range (cycle.gesturesDelayMin, cycle.gesturesDelayMax + 1);
			yield return new WaitForSeconds (delay * 0.2f);
		}
		StartCoroutine (CoCheckCompletion ());

	}


	IEnumerator CoCheckCompletion()
	{
		int readyCount = gesturesRails.Length;
		int counter = 0;
		while (counter != readyCount) 
		{
			counter = 0;
			foreach (var itRail in gesturesRails) 
			{
				if (itRail.HasHandles() == false)
				{
					counter++;
				}
			}
			yield return null;
		}
		CharacterAnimationController.instance.PlayAnimation (CharacterAnimationController.AnimationType.Happy);
		ParticlesController.instance.PlayParticleHappy ();
        yield return new WaitForSeconds (1f);
        WomboComboShower.instance.ShowGreetingsComplete();
        GenerateSequence ();
	}

	IEnumerator CoSampleSequence()
	{
		while (true) {
			railQ.SpawnHandle ();
			yield return new WaitForSeconds (Random.Range (0.5f, 1f));
			railW.SpawnHandle ();
			yield return new WaitForSeconds (Random.Range (0.5f, 1f));
			railE.SpawnHandle ();
			yield return new WaitForSeconds (Random.Range (0.5f, 1f));
			railR.SpawnHandle ();
			yield return new WaitForSeconds (Random.Range (0.5f, 1f));
			railT.SpawnHandle ();
			yield return new WaitForSeconds (Random.Range (0.5f, 1f));
			railLeft.SpawnHandle ();
			yield return new WaitForSeconds (Random.Range (0.5f, 1f));
			railUp.SpawnHandle ();
			yield return new WaitForSeconds (Random.Range (0.5f, 1f));
			railRight.SpawnHandle ();
			yield return new WaitForSeconds (Random.Range (0.5f, 1f));
		}

	}
}
