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

namespace Framefield.Core.IDcb9977a3_9af6_4d15_9f3d_e7c2580e4068
{
    public class Class_SimpleSSAO : FXImageFunction
    {
        //>>> _inputids
        private enum InputId
        {
            Code = 0,
            NoiseTexture = 1,
            DepthImage = 2,
            Passes = 3,
            KernelSize = 4,
            Seed = 5,
            DepthClipMin = 6,
            MixOriginal = 7,
            MultiplyOriginal = 8,
            ColorR = 9,
            ColorG = 10,
            ColorB = 11,
            ColorA = 12,
            BoostShadowsAdd = 13,
            BoostShadowsMultiply = 14,
            DepthRangeNear = 15,
            DepthRangeFar = 16,
            NoiseOffsetX = 17,
            NoiseOffsetY = 18,
            DepthClipMax = 19
        }
        //<<< _inputids

        public override OperatorPartContext Eval(OperatorPartContext context, List<OperatorPart> inputs, int outputIdx) {
            //>>> _params
            var Code = inputs[(int)InputId.Code].Eval(context).Text;
            var NoiseTexture = inputs[(int)InputId.NoiseTexture].Eval(context).Image; // Needs to be checked for null!
            var DepthImage = inputs[(int)InputId.DepthImage].Eval(context).Image; // Needs to be checked for null!
            var Passes = inputs[(int)InputId.Passes].Eval(context).Value;
            var KernelSize = inputs[(int)InputId.KernelSize].Eval(context).Value;
            var Seed = inputs[(int)InputId.Seed].Eval(context).Value;
            var DepthClipMin = inputs[(int)InputId.DepthClipMin].Eval(context).Value;
            var DepthClipMax = inputs[(int)InputId.DepthClipMax].Eval(context).Value;
            var DepthClip = new Vector2(DepthClipMin, DepthClipMax);
            var MixOriginal = inputs[(int)InputId.MixOriginal].Eval(context).Value;
            var MultiplyOriginal = inputs[(int)InputId.MultiplyOriginal].Eval(context).Value;
            var ColorR = inputs[(int)InputId.ColorR].Eval(context).Value;
            var ColorG = inputs[(int)InputId.ColorG].Eval(context).Value;
            var ColorB = inputs[(int)InputId.ColorB].Eval(context).Value;
            var ColorA = inputs[(int)InputId.ColorA].Eval(context).Value;
            var Color = new Color4(ColorR, ColorG, ColorB, ColorA);
            var BoostShadowsAdd = inputs[(int)InputId.BoostShadowsAdd].Eval(context).Value;
            var BoostShadowsMultiply = inputs[(int)InputId.BoostShadowsMultiply].Eval(context).Value;
            var BoostShadows = new Vector2(BoostShadowsAdd, BoostShadowsMultiply);
            var DepthRangeNear = inputs[(int)InputId.DepthRangeNear].Eval(context).Value;
            var DepthRangeFar = inputs[(int)InputId.DepthRangeFar].Eval(context).Value;
            var DepthRange = new Vector2(DepthRangeNear, DepthRangeFar);
            var NoiseOffsetX = inputs[(int)InputId.NoiseOffsetX].Eval(context).Value;
            var NoiseOffsetY = inputs[(int)InputId.NoiseOffsetY].Eval(context).Value;
            var NoiseOffset = new Vector2(NoiseOffsetX, NoiseOffsetY);
            //<<< _params

            return PrepareAndEvalOnChange(context, () => {
                ClearRenderTarget(context, new SharpDX.Color4(0, 0, 0, 1));

                var shaderDesc = new ShaderResourceViewDescription();
                shaderDesc.Format = Format.R32_Float;
                shaderDesc.Dimension = ShaderResourceViewDimension.Texture2D;
                shaderDesc.Texture2D.MipLevels = 1;
                using (var depthTexture = new ShaderResourceView(context.D3DDevice, context.DepthImage, shaderDesc)) {
                    _effect.GetVariableByName("txDepth").AsShaderResource().SetResource(depthTexture); 

                //>>> _setup
                using (var NoiseTextureView = new ShaderResourceView(context.D3DDevice, NoiseTexture))
                using (var DepthImageView = new ShaderResourceView(context.D3DDevice, DepthImage))
                {
                    _effect.GetVariableByName("RenderTargetSize").AsVector().Set(new Vector2(_usedViewport.Width, _usedViewport.Height));
                    _effect.GetVariableByName("NoiseTexture").AsShaderResource().SetResource(NoiseTextureView);
                    _effect.GetVariableByName("DepthImage").AsShaderResource().SetResource(DepthImageView);
                    _effect.GetVariableByName("Passes").AsScalar().Set(Passes);
                    _effect.GetVariableByName("KernelSize").AsScalar().Set(KernelSize);
                    _effect.GetVariableByName("Seed").AsScalar().Set(Seed);
                    _effect.GetVariableByName("DepthClip").AsVector().Set(new Vector2(DepthClipMin, DepthClipMax));
                    _effect.GetVariableByName("MixOriginal").AsScalar().Set(MixOriginal);
                    _effect.GetVariableByName("MultiplyOriginal").AsScalar().Set(MultiplyOriginal);
                    _effect.GetVariableByName("Color").AsVector().Set(new Vector4(ColorR, ColorG, ColorB, ColorA));
                    _effect.GetVariableByName("BoostShadows").AsVector().Set(new Vector2(BoostShadowsAdd, BoostShadowsMultiply));
                    _effect.GetVariableByName("DepthRange").AsVector().Set(new Vector2(DepthRangeNear, DepthRangeFar));
                    _effect.GetVariableByName("NoiseOffset").AsVector().Set(new Vector2(NoiseOffsetX, NoiseOffsetY));
                //<<< _setup

                Render(context);

                //>>> _cleanup
                }
                //<<< _cleanup
                }
            });
        }

    }
}

