using System.Collections.Generic;
using SharpDX;
using Framefield.Core.OperatorPartTraits;

namespace Framefield.Core.ID19e861a2_07ad_45d8_a465_d09e6a47dcde
{
    public class Class_Transform : OperatorPart.Function, ISceneTransform
    {
        // ISceneTransform
        public Matrix Transform
        {
            get
            {
                UpdateTransform(new OperatorPartContext(), OperatorPart.Connections);
                return _transform;
            }
        }
        
        public override OperatorPartContext Eval(OperatorPartContext context, List<OperatorPart> inputs, int outputIdx) {
            var SceneInput = inputs[0];
            
            UpdateTransform(context, inputs);
            var prevTransform = context.ObjectTWorld;

            context.ObjectTWorld = _transform * prevTransform;
            SceneInput.Eval(context);
            context.ObjectTWorld = prevTransform;

            return context;
        }
        
        // >>> _inputids
        private enum InputId
        {
            SceneInput = 0,
            TranslateX = 1,
            TranslateY = 2,
            TranslateZ = 3,
            RotateX = 4,
            RotateY = 5,
            RotateZ = 6,
            ScaleX = 7,
            ScaleY = 8,
            ScaleZ = 9,
            PivotX = 10,
            PivotY = 11,
            PivotZ = 12
        }
        // <<< _inputids

        private void UpdateTransform(OperatorPartContext context, List<OperatorPart> inputs)
        {
            if (!Changed)
                return;
                
            // >>> _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 PivotX = inputs[(int)InputId.PivotX].Eval(context).Value;
            var PivotY = inputs[(int)InputId.PivotY].Eval(context).Value;
            var PivotZ = inputs[(int)InputId.PivotZ].Eval(context).Value;
            var Pivot = new Vector3(PivotX, PivotY, PivotZ);
            // <<< _params

            var translation = new Vector3(TranslateX, TranslateY, TranslateZ);
            var rotation = Quaternion.RotationYawPitchRoll(MathUtil.DegreesToRadians(RotateY),
                                                           MathUtil.DegreesToRadians(RotateX),
                                                           MathUtil.DegreesToRadians(RotateZ));
            var scale = new Vector3(ScaleX, ScaleY, ScaleZ);

            _transform = Matrix.Transformation(Pivot, Quaternion.Zero, scale, Pivot, rotation, translation);
        }

        private Matrix _transform;
    }
}
