//>>> _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.ID0bd3efd4_6d55_4e63_988f_859ab02f5f45
{
    public class Class_RadialReplicate_2_ : FXSourceCodeFunction
    {
        //>>> _inputids
        private enum InputId
        {
            Code = 0,
            Scene = 1,
            NumberOfCopies = 2,
            Id = 3,
            Rotate = 4
        }
        //<<< _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_RadialReplicate_2_()
        {
            _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 NumberOfCopies = inputs[(int)InputId.NumberOfCopies].Eval(context).Value;
            var Id = inputs[(int)InputId.Id].Eval(context).Value;
            var Rotate = inputs[(int)InputId.Rotate].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("Range").AsVector().Set(new Vector2(RangeX, RangeY));
                _effect.GetVariableByName("NumberOfCopies").AsScalar().Set(NumberOfCopies);
                _effect.GetVariableByName("Id").AsScalar().Set(Id);
                _effect.GetVariableByName("Rotate").AsScalar().Set(0);
                context.Effect = _effect;
                context.Renderer = _renderer;
                
                var prevTransform = context.ObjectTWorld;
                for(var i=0; i < NumberOfCopies; i++) {
                    /*
                    var transform = prevTransform * Matrix.Transformation(new Vector3(), 
                                new Quaternion(), 
                                new Vector3(1*i,1,1), 
                                new Vector3(), 
                                new Quaternion(), 
                                new Matrix.Identity());
                    */
                    var r = Matrix.Identity;
                    Matrix.RotationY( (float)(i*2*Math.PI/NumberOfCopies  +  ( -90+90/(NumberOfCopies/2) ) /360*Math.PI*2 )  , out r);                    

                    var t= prevTransform * Matrix.Identity;


                    if( i % 2 > 0) {
                        t = t * Matrix.Scaling(-1 , 1,1);
                    }
                    t *= r;
                    
                    context.ObjectTWorld = t;
                    
                    _effect.GetVariableByName("Id").AsScalar().Set(i);
                    
                    Scene.Eval(context);
                }
                    
                //transform *= prevTransform; 
                //SceneInput.Connections[i%SceneInput.Connections.Count].Eval(context);
                context.ObjectTWorld = prevTransform;
                
                //SceneInput.Connections[i%SceneInput.Connections.Count].Eval(context);
                //context.ObjectTWorld = prevTransform;


            }

            /*
            //>>> _setup
            {
                _effect.GetVariableByName("RenderTargetSize").AsVector().Set(new Vector2(_usedViewport.Width, _usedViewport.Height));
                _effect.GetVariableByName("NumberOfCopies").AsScalar().Set(NumberOfCopies);
                _effect.GetVariableByName("Id").AsScalar().Set(Id);
                _effect.GetVariableByName("Rotate").AsScalar().Set(Rotate);
            //<<< _setup            
            */
            return context;
        }

        Renderer _renderer;
    }
}


