using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SharpDX;
using SharpDX.Direct3D;
using SharpDX.D3DCompiler;
using SharpDX.Direct3D11;
using SharpDX.DXGI;
using Framefield.Core.Rendering;

namespace Framefield.Core.ID25804797_d21e_4abd_8442_12ac343ee0c3
{
    public class Class_Layer2dWithZ : OperatorPart.Function
    {
        public Class_Layer2dWithZ()
        {
            try
            {
                using (var bytecode = ShaderBytecode.CompileFromFile("assets-common/fx/Layer2d.fx", "fx_5_0", ShaderFlags.None, EffectFlags.None, null, null))
                    _effect = new Effect(D3DDevice.Device, bytecode);
                _renderer = new BaseRenderer();
            }
            catch (Exception e)
            {
                Logger.Error(this,"error loading laye2d fx: {0} ", e.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 Image = inputs[0].Eval(context).Image; if (Image == null) return context;
            var MultiplyColor = Utilities.EvaluateVector4(context, inputs, 1);

            var subContext = new OperatorPartContext(context);
            subContext.Effect = _effect;
            subContext.Renderer = _renderer;
            subContext.InputLayout = context.Renderer.ScreenQuadInputLayout;
            subContext.CameraProjection = Matrix.OrthoLH(1, 1, -100, 100);
            subContext.WorldToCamera = Matrix.LookAtLH(new Vector3(0, 0, -5), new Vector3(0, 0, 0), new Vector3(0, 1, 0));
            subContext.ObjectTWorld = Matrix.Identity;


            using (var textureView = new ShaderResourceView(context.D3DDevice, Image))
            {
                _effect.GetVariableByName("hasDepth").AsScalar().Set(context.DepthImage != null);
                _effect.GetVariableByName("multiplyColor").AsVector().Set(MultiplyColor);


                var depthStencilDescription = new DepthStencilStateDescription();
                if (context.DepthImage != null) {

                    depthStencilDescription.IsDepthEnabled = true;
                    depthStencilDescription.DepthWriteMask = DepthWriteMask.All;
                    depthStencilDescription.DepthComparison = Comparison.Less;

                    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))
                    using (var depthStencilState = new DepthStencilState(context.D3DDevice, depthStencilDescription))
                    {
                        _effect.GetVariableByName("txDepth").AsShaderResource().SetResource(depthTexture); 
              
                        subContext.Texture0 = textureView;
                        subContext.Renderer.SetupEffect(subContext);

                        subContext.DepthStencilState = depthStencilState;

                        subContext.Renderer.Render(subContext.Renderer._screenQuadMesh, subContext);
                    }
                }
                else {
                    depthStencilDescription.IsDepthEnabled = false;
                    using (var depthStencilState = new DepthStencilState(context.D3DDevice, depthStencilDescription))
                    {
                        subContext.Texture0 = textureView;
                        subContext.Renderer.SetupEffect(subContext);
    
                        subContext.DepthStencilState = depthStencilState;
    
                        subContext.Renderer.Render(subContext.Renderer._screenQuadMesh, subContext);
                    }
                }

            }

            return context;
        }

        Effect _effect;
        BaseRenderer _renderer;
    }
}

