//>>> _using
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SharpDX;
using SharpDX.Direct3D11;
using SharpDX.Windows;
//<<< _using

namespace Framefield.Core.ID79ca9be5_ad6f_41f0_a4e5_32e9f5191d1e
{
    public class Class_BeatPulse : OperatorPart.Function, Framefield.Core.OperatorPartTraits.ITimeAccessor
    {
        //>>> _inputids
        private enum InputId
        {
            BPM = 0,
            BPMTimeOffset = 1,
            Ticks = 2,
            BeatsPerBar = 3,
            OutputRangeMax = 4,
            OutputRangeMin = 5
        }
        //<<< _inputids
        
        //>>> _outputids
        private enum OutputId
        {
            Beat = 0
        }
        //<<< _outputids
        
        public override OperatorPartContext Eval(OperatorPartContext context, List<OperatorPart> inputs, int outputIdx) 
        {
            //>>> _params
            var BPM = inputs[(int)InputId.BPM].Eval(context).Value;
            var BPMTimeOffset = inputs[(int)InputId.BPMTimeOffset].Eval(context).Value;
            var Ticks = inputs[(int)InputId.Ticks].Eval(context).Text;
            var BeatsPerBar = inputs[(int)InputId.BeatsPerBar].Eval(context).Value;
            var OutputRangeMax = inputs[(int)InputId.OutputRangeMax].Eval(context).Value;
            var OutputRangeMin = inputs[(int)InputId.OutputRangeMin].Eval(context).Value;
            var OutputRange = new Vector2(OutputRangeMax, OutputRangeMin);
            //<<< _params

            var steps = (float)Ticks.Length;
            if( steps <=0){
                Logger.Warn(this, "Ticks must be at least a characters long");
                return context;
            }
            
            //steps = 4;
            var time = context.GlobalTime - BPMTimeOffset;

            var x = 60 / BPM * BeatsPerBar ;
            
            var barTime = (time % x) / x;
            
            float maxValue = 0;
            foreach(var c in Ticks) {
                double v =0;
                Double.TryParse(""+c, out v);
                if( v > maxValue)
                    maxValue = (float)v;                
            }
            
            var stepIndex = (int)Math.Floor( barTime * steps) ;
            if(stepIndex <0 )
                stepIndex = 0;
            double stepStrength;
            Double.TryParse( ""+Ticks[stepIndex], out stepStrength );
            var strength = (float)stepStrength / maxValue;

            float stepTime = barTime * steps - stepIndex;
            float stepBeat = (1-stepTime) * strength;
            
            context.Value =  stepBeat * (OutputRangeMax - OutputRangeMin) + OutputRangeMin;            
            
            return context;
        }
    }
}

