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


namespace Framefield.Core.ID020fcdc5_69b7_47b8_abd4_59d01e689ab3
{

    public class Class_AdjustProjectionShader : FXSourceCodeFunction
    {
        //>>> _inputids
        private enum InputId
        {
            Code = 0,
            Scene = 1,
            RangeXMin = 2,
            RangeXMax = 3,
            RangeYMin = 4,
            RangeYMax = 5,
            P1X = 6,
            P1Y = 7,
            P2X = 8,
            P2Y = 9,
            P3X = 10,
            P3Y = 11,
            P4X = 12,
            P4Y = 13,
            Tangent1X = 14,
            Tangent1Y = 15,
            Tangent2X = 16,
            Tangent2Y = 17,
            Tangent3X = 18,
            Tangent3Y = 19,
            Tangent4X = 20,
            Tangent4Y = 21,
            TangentPow = 22
        }
        //<<< _inputids
        #region Renderer
        public class Renderer : BaseRenderer
        {
            public override void SetupEffect(OperatorPartContext context) {
                base.SetupEffect(context);

                try {
                    SetupMaterialConstBuffer(context);
                    SetupFogSettingsConstBuffer(context);
                    SetupPointLightsConstBuffer(context);
                }
                catch (Exception e) {
                    Logger.Error(ParentFunc, "Error building constant buffer: {0} - Source: {1}", e.Message, e.Source);
                }
            }
            public OperatorPart.Function ParentFunc {get;set;}            
        }
        #endregion

        public Class_AdjustProjectionShader() {
            _renderer = new Renderer(){ParentFunc = this};
        }

        public override void Dispose() {
            Utilities.DisposeObj(ref _renderer);
            base.Dispose();
        }

        bool _firstEval = true;
        public override OperatorPartContext Eval(OperatorPartContext context, List<OperatorPart> inputs, int outputIdx) {
            // >>> _params
            var Code = inputs[(int)InputId.Code].Eval(context).Text;
            var Scene = inputs[(int)InputId.Scene];
            var RangeXMin = inputs[(int)InputId.RangeXMin].Eval(context).Value;
            var RangeXMax = inputs[(int)InputId.RangeXMax].Eval(context).Value;
            var RangeX = new Vector2(RangeXMin, RangeXMax);
            var RangeYMin = inputs[(int)InputId.RangeYMin].Eval(context).Value;
            var RangeYMax = inputs[(int)InputId.RangeYMax].Eval(context).Value;
            var RangeY = new Vector2(RangeYMin, RangeYMax);
            var P1X = inputs[(int)InputId.P1X].Eval(context).Value;
            var P1Y = inputs[(int)InputId.P1Y].Eval(context).Value;
            var P1 = new Vector2(P1X, P1Y);
            var P2X = inputs[(int)InputId.P2X].Eval(context).Value;
            var P2Y = inputs[(int)InputId.P2Y].Eval(context).Value;
            var P2 = new Vector2(P2X, P2Y);
            var P3X = inputs[(int)InputId.P3X].Eval(context).Value;
            var P3Y = inputs[(int)InputId.P3Y].Eval(context).Value;
            var P3 = new Vector2(P3X, P3Y);
            var P4X = inputs[(int)InputId.P4X].Eval(context).Value;
            var P4Y = inputs[(int)InputId.P4Y].Eval(context).Value;
            var P4 = new Vector2(P4X, P4Y);
            var Tangent1X = inputs[(int)InputId.Tangent1X].Eval(context).Value;
            var Tangent1Y = inputs[(int)InputId.Tangent1Y].Eval(context).Value;
            var Tangent1 = new Vector2(Tangent1X, Tangent1Y);
            var Tangent2X = inputs[(int)InputId.Tangent2X].Eval(context).Value;
            var Tangent2Y = inputs[(int)InputId.Tangent2Y].Eval(context).Value;
            var Tangent2 = new Vector2(Tangent2X, Tangent2Y);
            var Tangent3X = inputs[(int)InputId.Tangent3X].Eval(context).Value;
            var Tangent3Y = inputs[(int)InputId.Tangent3Y].Eval(context).Value;
            var Tangent3 = new Vector2(Tangent3X, Tangent3Y);
            var Tangent4X = inputs[(int)InputId.Tangent4X].Eval(context).Value;
            var Tangent4Y = inputs[(int)InputId.Tangent4Y].Eval(context).Value;
            var Tangent4 = new Vector2(Tangent4X, Tangent4Y);
            var TangentPow = inputs[(int)InputId.TangentPow].Eval(context).Value;
            // <<< _params
            if (_firstEval) {
                for (int i = 0; i < NumCodes(); ++i)
                    Compile(i);
                _firstEval = false;
                Changed = true;
            }

            using (new PropertyStasher<OperatorPartContext>(context, "Effect", "Renderer")) {                
                _effect.GetVariableByName("RangeX").AsVector().Set(new Vector2(RangeXMin, RangeXMax));
                _effect.GetVariableByName("RangeY").AsVector().Set(new Vector2(RangeYMin, RangeYMax));
                _effect.GetVariableByName("P1").AsVector().Set(new Vector2(P1X, P1Y));
                _effect.GetVariableByName("P2").AsVector().Set(new Vector2(P2X, P2Y));
                _effect.GetVariableByName("P3").AsVector().Set(new Vector2(P3X, P3Y));
                _effect.GetVariableByName("P4").AsVector().Set(new Vector2(P4X, P4Y));
                _effect.GetVariableByName("Tangent1").AsVector().Set(new Vector2(Tangent1X, Tangent1Y));
                _effect.GetVariableByName("Tangent2").AsVector().Set(new Vector2(Tangent2X, Tangent2Y));
                _effect.GetVariableByName("Tangent3").AsVector().Set(new Vector2(Tangent3X, Tangent3Y));
                _effect.GetVariableByName("Tangent4").AsVector().Set(new Vector2(Tangent4X, Tangent4Y));
                _effect.GetVariableByName("TangentPow").AsScalar().Set(TangentPow);
                context.Effect = _effect;
                context.Renderer = _renderer;
                Scene.Eval(context);
            }

            /*
            //>>> _setup
            {
                _effect.GetVariableByName("RenderTargetSize").AsVector().Set(new Vector2(_usedViewport.Width, _usedViewport.Height));
                _effect.GetVariableByName("RangeX").AsVector().Set(new Vector2(RangeXMin, RangeXMax));
                _effect.GetVariableByName("RangeY").AsVector().Set(new Vector2(RangeYMin, RangeYMax));
                _effect.GetVariableByName("P1").AsVector().Set(new Vector2(P1X, P1Y));
                _effect.GetVariableByName("P2").AsVector().Set(new Vector2(P2X, P2Y));
                _effect.GetVariableByName("P3").AsVector().Set(new Vector2(P3X, P3Y));
                _effect.GetVariableByName("P4").AsVector().Set(new Vector2(P4X, P4Y));
                _effect.GetVariableByName("Tangent1").AsVector().Set(new Vector2(Tangent1X, Tangent1Y));
                _effect.GetVariableByName("Tangent2").AsVector().Set(new Vector2(Tangent2X, Tangent2Y));
                _effect.GetVariableByName("Tangent3").AsVector().Set(new Vector2(Tangent3X, Tangent3Y));
                _effect.GetVariableByName("Tangent4").AsVector().Set(new Vector2(Tangent4X, Tangent4Y));
                _effect.GetVariableByName("TangentPow").AsScalar().Set(TangentPow);
            //<<< _setup            
            */
            return context;
        }

        Renderer _renderer;
    }
}


