using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SharpDX;

namespace Framefield.Core.IDb8d99d67_67ab_4daf_ac08_7bf6bbdd83d5
{
    public class Class_Iterate : OperatorPart.Function
    {
        //>>> _inputids
        private enum InputId
        {
            Subtree = 0,
            Counter = 1,
            Count = 2
        }
        //<<< _inputids

        //OperatorPart.CollectOpPartFunctionsOfType<Framefield.Core.OperatorPartTraits.IVariableAccessor> _collector = new OperatorPart.CollectOpPartFunctionsOfType<Framefield.Core.OperatorPartTraits.IVariableAccessor>();
        //List<OperatorPart.Function> _variableAccessorOpPartFunctions = new List<OperatorPart.Function>();

        public override OperatorPartContext Eval(OperatorPartContext context, List<OperatorPart> inputs, int outputIdx)
        {
            //>>> _params
            var Subtree = inputs[(int)InputId.Subtree];
            var Counter = inputs[(int)InputId.Counter].Eval(context).Text;
            var Count = inputs[(int)InputId.Count].Eval(context).Value;
            //<<< _params

            OperatorPart.ChangedPropagationEnabled = false;

            //collect all ops within the Subtree that access the Counter variable
            /*
            _collector.Clear();
            Subtree.TraverseWithFunction(_collector, null);
            _variableAccessorOpPartFunctions.Clear();

            foreach (var possibleOpPartFunction in _collector.CollectedOpPartFunctions) {
                if (possibleOpPartFunction.VariableName == Counter)
                    _variableAccessorOpPartFunctions.Add(possibleOpPartFunction as OperatorPart.Function);
            }
            */

            var invalidator = new OperatorPart.InvalidateVariableAccessors(Counter);
            for (var i = 0;  i < Count; i += 1)
            {
                if (context.Variables.ContainsKey(Counter))
                    context.Variables[Counter] = i;
                else
                    context.Variables.Add(Counter, i);

                //foreach (var opPartFunc in _variableAccessorOpPartFunctions)
                //    opPartFunc.OperatorPart.EmitChangedEvent();
                
                //invalidate all variable accessors
                invalidator.Clear();
                Subtree.TraverseWithFunctionUseSpecificBehavior(null, invalidator);                
                
                Subtree.Eval(context);
            }

            OperatorPart.ChangedPropagationEnabled = true;

            return context;
        }
    }
}


