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

namespace Framefield.Core.ID4afa253d_e97b_4e80_9896_2f28d9e71675
{
    public class Class_For_i : OperatorPart.Function
    {
        OperatorPart.CollectOpPartFunctionsOfType<Framefield.Core.OperatorPartTraits.IVariableAccessor> _collector = new OperatorPart.CollectOpPartFunctionsOfType<Framefield.Core.OperatorPartTraits.IVariableAccessor>();
        List<OperatorPart.Function> _variableAccessorOpPartFunctions = new List<OperatorPart.Function>();
    
        // >>> _inputids
        private enum InputId
        {
            Subtree = 0,
            Counter = 1,
            Start = 2,
            Stop = 3,
            Step = 4
        }
        // <<< _inputids

        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 Start = inputs[(int)InputId.Start].Eval(context).Value;
            var Stop = inputs[(int)InputId.Stop].Eval(context).Value;
            var Step = inputs[(int)InputId.Step].Eval(context).Value;
            // <<< _params

            if (Step == 0)
                return context;
            
            if (Start > Stop && Step > 0)
            {
                //Utilities.Swap(ref Start, ref Stop);
                Step *= -1.0f;
            }

            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);
            var loopCounter = 0;
            for (var i = Start; i <= Math.Max(Start,Stop) && i >= Math.Min(Start,Stop); i += Step)
            {
                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.TraverseWithFunction(invalidator, null);
                //Subtree.TraverseWithFunctionUseSpecificBehavior(invalidator, null);

                Subtree.Eval(context);
                
                if (loopCounter++ > 10000)
                {
                    Logger.Warn("Stopped interaction over For i after 10000 loops.");
                    break;
                }                
            }
            
            OperatorPart.ChangedPropagationEnabled = true;
            return context;
        }
    }
}

