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


namespace Framefield.Core.ID4c5fc54c_4173_41e5_a5bb_a6fc3daf46ff
{
    public class Class_SceneRepeat : OperatorPart.Function
    {
        //>>> _inputids
        private enum InputId
        {
            SceneInput = 0,
            TranslateX = 1,
            TranslateY = 2,
            TranslateZ = 3,
            RotateX = 4,
            RotateY = 5,
            RotateZ = 6,
            ScaleX = 7,
            ScaleY = 8,
            ScaleZ = 9,
            FocusRotateX = 10,
            FocusRotateY = 11,
            FocusRotateZ = 12,
            FocusBlend = 13,
            FocusItem = 14,
            InitialRotateX = 15,
            InitialRotateY = 16,
            InitialRotateZ = 17
        }
        //<<< _inputids 
        public override OperatorPartContext Eval(OperatorPartContext context, List<OperatorPart> inputs, int outputIdx) {
           //>>> params
           var SceneInput = inputs[(int)InputId.SceneInput];
           var TranslateX = inputs[(int)InputId.TranslateX].Eval(context).Value;
           var TranslateY = inputs[(int)InputId.TranslateY].Eval(context).Value;
           var TranslateZ = inputs[(int)InputId.TranslateZ].Eval(context).Value;
           var Translate = new Vector3(TranslateX, TranslateY, TranslateZ);
           var RotateX = inputs[(int)InputId.RotateX].Eval(context).Value;
           var RotateY = inputs[(int)InputId.RotateY].Eval(context).Value;
           var RotateZ = inputs[(int)InputId.RotateZ].Eval(context).Value;
           var Rotate = new Vector3(RotateX, RotateY, RotateZ);
           var ScaleX = inputs[(int)InputId.ScaleX].Eval(context).Value;
           var ScaleY = inputs[(int)InputId.ScaleY].Eval(context).Value;
           var ScaleZ = inputs[(int)InputId.ScaleZ].Eval(context).Value;
           var Scale = new Vector3(ScaleX, ScaleY, ScaleZ);
           var FocusRotateX = inputs[(int)InputId.FocusRotateX].Eval(context).Value;
           var FocusRotateY = inputs[(int)InputId.FocusRotateY].Eval(context).Value;
           var FocusRotateZ = inputs[(int)InputId.FocusRotateZ].Eval(context).Value;
           var FocusRotate = new Vector3(FocusRotateX, FocusRotateY, FocusRotateZ);
           var FocusBlend = inputs[(int)InputId.FocusBlend].Eval(context).Value;
           var FocusItem = inputs[(int)InputId.FocusItem].Eval(context).Value;
           var Focus = new  Vector2(FocusBlend, FocusItem);
           var InitialRotateX = inputs[(int)InputId.InitialRotateX].Eval(context).Value;
           var InitialRotateY = inputs[(int)InputId.InitialRotateY].Eval(context).Value;
           var InitialRotateZ = inputs[(int)InputId.InitialRotateZ].Eval(context).Value;
           var InitialRotate = new Vector3(InitialRotateX, InitialRotateY, InitialRotateZ);
            //<<< params

            var initialRotation = Quaternion.RotationYawPitchRoll((InitialRotateX) / 360.0f * (float)(2.0 * Math.PI),
                                                           (InitialRotateY) / 360.0f * (float)(2.0 * Math.PI),
                                                           (InitialRotateZ) / 360.0f * (float)(2.0 * Math.PI));


            var translation = new Vector3(TranslateX, TranslateY, TranslateZ);
            var rotation = Quaternion.RotationYawPitchRoll((RotateX) / 360.0f * (float)(2.0 * Math.PI),
                                                           (RotateY) / 360.0f * (float)(2.0 * Math.PI),
                                                           (RotateZ) / 360.0f * (float)(2.0 * Math.PI));
            var scale = new Vector3(ScaleX, ScaleY, ScaleZ);
            
            var repeatTransform = Matrix.Transformation(new Vector3(), new Quaternion(), scale, new Vector3(), rotation, translation);
            
            var prevTransform = context.ObjectTWorld;
            
            for(int i=0; i< inputs[0].Connections.Count; ++i) {
                var input = inputs[0].Connections[i];
                // Override with focus rotation
                if( i == (int) FocusItem) {
                    var t = context.ObjectTWorld;   // keep original
                    
                    var focusRotation = Quaternion.RotationYawPitchRoll(FocusRotateX / 360.0f * (float)(2.0 * Math.PI),
                                                           FocusRotateY / 360.0f * (float)(2.0 * Math.PI),
                                                           FocusRotateZ / 360.0f * (float)(2.0 * Math.PI));
                    var focusTransform = Matrix.Transformation(new Vector3(), new Quaternion(), new Vector3(1, 1, 1), new Vector3(), focusRotation, new Vector3(1, 1, 1));                                       
                    
                    
                    var m = focusTransform;
                    float a= FocusBlend;
                    float b= 1 - FocusBlend;
                    
                    m.M11 = m.M11 * a + t.M11 *b;
                    m.M12 = m.M12 * a + t.M12 *b;
                    m.M13 = m.M13 * a + t.M13 *b;
                    m.M14 = m.M14 * a + t.M14 *b;
                    m.M21 = m.M21 * a + t.M21 *b;
                    m.M22 = m.M22 * a + t.M22 *b;
                    m.M23 = m.M23 * a + t.M23 *b;
                    m.M24 = m.M24 * a + t.M24 *b;
                    
                    m.M31 = m.M31 * a + t.M31 *b;
                    m.M32 = m.M32 * a + t.M32 *b;
                    m.M33 = m.M33 * a + t.M33 *b;
                    m.M34 = m.M34 * a + t.M34 *b;
                    m.M41 = m.M41 * a + t.M41 *b;
                    m.M42 = m.M42 * a + t.M42 *b;
                    m.M43 = m.M43 * a + t.M43 *b;
                    m.M44 = m.M44 * a + t.M44 *b;
                    
                    context.ObjectTWorld = Matrix.RotationX(InitialRotateX) * m * prevTransform;
                    //var focusTransform = Matrix.Transformation(new Vector3(), new Quaternion(), new Vector3(1, 1, 1), new Vector3(), focusRotation, new Vector3(1, 1, 1));                                       

                   input.Eval(context);
                   context.ObjectTWorld = t;
                }   
                // Use repeat animation                
                else {
                    var t2= context.ObjectTWorld;
                    context.ObjectTWorld = Matrix.RotationX(InitialRotateX) * Matrix.RotationY(InitialRotateY) * Matrix.RotationZ(InitialRotateZ) * context.ObjectTWorld;
                    input.Eval(context);
                    context.ObjectTWorld = t2;
                }
                context.ObjectTWorld = repeatTransform * context.ObjectTWorld;
            }
            
            /** original sceneRepeat code
            for (var i = 0; i < Count; ++i) {
                SceneInput.Eval(context);
                context.ObjectTWorld = transform * context.ObjectTWorld;
            }
            */
            
            context.ObjectTWorld = prevTransform;
            
            //!!automatic generated code starts here
            return context;
        }
    }
}

