// An ActionSequence encapsulates a series of IBlockActions to perform.
// It represents a single logical coordinated "action". The action may have
// multiple steps, each with multiple actions. It provides a method to asynchronously
// perform those steps in sequence.

using System.Collections.Generic;

namespace IngameScript
{
    partial class Program
    {
        public class ActionSequence
        {
            public string Name { get; private set; }
            public bool Running { get; private set; } = false;

            private SortedDictionary<int, List<BlockAction>> _steps = new SortedDictionary<int, List<BlockAction>>();

            public ActionSequence(string name)
            {
                Name = name;
            }

            public void Add(int step, BlockAction action)
            {
                if (!_steps.ContainsKey(step)) _steps[step] = new List<BlockAction>();
                _steps[step].Add(action);
            }

            public IEnumerator<bool> Run()
            {
                if (Running) yield break;
                Running = true;

                List<IEnumerator<bool>> jobs = new List<IEnumerator<bool>>();
                foreach (List<BlockAction> step in _steps.Values)
                {
                    foreach (BlockAction action in step)
                    {
                        jobs.Add(action.Run());
                    }

                    bool stepRunning = true;
                    while (stepRunning)
                    {
                        stepRunning = false;
                        foreach (IEnumerator<bool> job in jobs)
                        {
                            if (job.MoveNext()) stepRunning = true;
                        }
                        yield return true;
                    }

                    foreach (IEnumerator<bool> job in jobs)
                    {
                        job.Dispose();
                    }
                    jobs.Clear();
                }

                Running = false;
            }
        }
    }
}