using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using SharpDX;
using SharpDX.Direct3D11;
using Framefield.Core.Rendering;
using Framefield.Core.OperatorPartTraits;
using Buffer = SharpDX.Direct3D11.Buffer;

namespace Framefield.Core.IDeed574eb_5051_4481_898e_96e069c133df
{
    public class Class_Visibility : FXSourceCodeFunction, IFXSceneSourceCode, IMaterial, ITraverseModifier
    {

        class Renderer : BaseRenderer
        {
        }

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

        public IEnumerable<OperatorPart> GetRelevantConnections()
        {
            List<OperatorPart> connections = new List<OperatorPart>(OperatorPart.Connections);

            if (_alpha < 0.001f)
            {
                connections.RemoveAt(0);
            }            

            return connections;
        }

        //>>> _inputids
        private enum InputId
        {
            Code = 0,
            Scene = 1,
            Alpha = 2,
            OverrideAlpha = 3
        }
        //<<< _inputids
        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 Alpha = inputs[(int)InputId.Alpha].Eval(context).Value;
            var OverrideAlpha = (int) inputs[(int)InputId.OverrideAlpha].Eval(context).Value;
            //<<< _params

            _alpha = Alpha;
            if (_firstEval) {
                for (int i = 0; i < NumCodes(); ++i)
                    Compile(i);
                _firstEval = false;
                Changed = true;
            }

            using (new PropertyStasher<OperatorPartContext>(context, "Effect", "Renderer")) {
                context.Effect = _effect;
                context.Renderer = _renderer;

                var prevMaterial = (IMaterial) context.Objects[OperatorPartContext.MATERIAL_ID];
                Ambient = prevMaterial.Ambient;
                Specular = prevMaterial.Specular;
                Emission = prevMaterial.Emission;
                Shininess = prevMaterial.Shininess;
                
                var d = prevMaterial.Diffuse;
                Diffuse = new Color4(d.Red, d.Green, d.Blue, Alpha);
                
                if (OverrideAlpha > 0.5f) 
                {
                    Alpha *= d.Alpha;
                    Diffuse = new Color4(d.Red, d.Green, d.Blue, Alpha);
                }
                                
                if( Alpha > 0) {
                    context.Objects[OperatorPartContext.MATERIAL_ID] = this;
                    _effect.GetVariableByName("ColorMul").AsVector().Set(Diffuse); 
                    Scene.Eval(context);
                    context.Objects[OperatorPartContext.MATERIAL_ID] = prevMaterial;
                }
                
                
            }
            return context;
        }

        private float _alpha;
        private Renderer _renderer = new Renderer();

        public Color4 Ambient { get; private set; }
        public Color4 Diffuse { get; private set; }
        public Color4 Specular { get; private set; }
        public Color4 Emission { get; private set; }
        public float Shininess { get; private set; }
    }
}


