using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using SharpDX;
using SharpDX.D3DCompiler;
using SharpDX.Direct3D11;
using SharpDX.DXGI;
using SharpDX.Windows;
using Framefield.Core.Rendering;

namespace Framefield.Core.ID57a27055_e2c1_44ea_a501_0e6b6ee1ede2
{
    public class Class_MagneticFieldsEffect : OperatorPart.Function
    {
        public class Renderer : BaseRenderer
        {
            public override void SetupEffect(OperatorPartContext context) {
                base.SetupEffect(context);
                context.Effect.GetVariableByName("color1").AsVector().Set(_color1);
                context.Effect.GetVariableByName("color2").AsVector().Set(_color2);
                context.Effect.GetVariableByName("color3").AsVector().Set(_color3);
                context.Effect.GetVariableByName("color4").AsVector().Set(_color4);
                context.Effect.GetVariableByName("lineColor").AsVector().Set(_lineColor);
                context.Effect.GetVariableByName("gridSize").AsScalar().Set(_gridSize);
                context.Effect.GetVariableByName("lineWeight").AsScalar().Set(_lineWeight);

                context.Effect.GetVariableByName("rotateScale").AsScalar().Set(_rotateScale);
                context.Effect.GetVariableByName("rotateAdd").AsScalar().Set(_rotateAdd);
                context.Effect.GetVariableByName("padding").AsScalar().Set(_padding);
            }

            public SharpDX.Vector4 _color1;
            public SharpDX.Vector4 _color2;
            public SharpDX.Vector4 _color3;
            public SharpDX.Vector4 _color4;
            public SharpDX.Vector4 _lineColor;
            public float _gridSize;
            public float _lineWeight;
            public float _rotateScale;
            public float _rotateAdd;
            public float _padding;
        }

        public Class_MagneticFieldsEffect() {
            try {
                using (var bytecode = ShaderBytecode.CompileFromFile("assets-common/fx/MagneticFields.fx", "fx_5_0", ShaderFlags.None, EffectFlags.None, null, null))
                    _effect = new Effect(D3DDevice.Device, bytecode);
                _renderer = new Renderer();
            }
            catch (Exception ex) {
                Logger.Error(this,"error creating effect: {0}", ex.Message);
            }
        }



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

        public override OperatorPartContext Eval(OperatorPartContext context, List<OperatorPart> inputs, int outputIdx) {
            var Scene = inputs[0];//.Eval(context);

            _renderer._color1 = Utilities.EvaluateVector4(context, inputs, 1);

            _renderer._color2 = Utilities.EvaluateVector4(context, inputs, 5);

            _renderer._lineColor = Utilities.EvaluateVector4(context, inputs, 9);
            _renderer._gridSize = inputs[13].Eval(context).Value;
            _renderer._lineWeight = inputs[14].Eval(context).Value;
            _renderer._rotateScale = inputs[15].Eval(context).Value;
            _renderer._rotateAdd = inputs[16].Eval(context).Value;

            _renderer._color3 = Utilities.EvaluateVector4(context, inputs, 17);

            _renderer._color4 = Utilities.EvaluateVector4(context, inputs, 21);
            _renderer._padding = inputs[25].Eval(context).Value;

            var D3DDevice = context.D3DDevice;
            var subContext = new OperatorPartContext(context);
            try {
                subContext.Effect = _effect;
                subContext.InputLayout = context.Renderer.SceneDefaultInputLayout;
                subContext.Renderer = _renderer;

                Scene.Eval(subContext);
            }
            catch (Exception exception) {
                Logger.Error(this,"Load Effect error: {0}", exception.Message);
            }

            return context;
        }


        Effect _effect;
        Renderer _renderer;
    }
}

