using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using VisiMath;
using VisiMath.Geometry;
using VisimBox.Scene;
using VisimBox;

namespace VisimBuilder
{
    class RotateGizmo : MoveGizmo
    {

        public RotateGizmo(MainBuilderForm boss)
            : base(boss)
        {
            InLocalCoords = true;
        }

        public override void ConstructArrows()
        {
            Ring ring = new Ring(new Vector3(0, 0, 0), ArrowLength + ArrowSize/2, ArrowSize/2, ArrowSize / 4, 4, MathTools.Pi);
            ZArrow = ring;

            ring = new Ring(new Vector3(0, 0, 0), ArrowLength + ArrowSize / 2, ArrowSize / 2, ArrowSize / 4, 4, MathTools.Pi);
            Matrix4 trans = Matrix4.CreateRotationY(MathTools.HalfPi);
            trans.Transform(ring.Vertices);

            XArrow = ring;

            ring = new Ring(new Vector3(0, 0, 0), ArrowLength + ArrowSize / 2, ArrowSize / 2, ArrowSize / 4, 4, MathTools.Pi);
            trans = Matrix4.CreateRotationX(MathTools.HalfPi);
            trans.Transform(ring.Vertices);
            YArrow = ring;
        }


        public override void MyMove(float dist, VisiMath.Vector3 origo)
        {
            //todo!!! better rotation control (correct direction etc), this will suffice for now

            //dist *= 5;
            if (Boss.SelectedNode.Trans == null)
                return;

            VisimBox.Physics.RigidBody rb = Boss.SelectedNode as VisimBox.Physics.RigidBody;

            bool validtrans = false;
            int maxiterations = 64;

            while (!validtrans)
            {
                maxiterations--;
                if (maxiterations < 0)
                    return;

                if (Boss.Settings.RigidBodyColCheck && rb != null)
                {
                    Boss.SelectedNode.Trans.PushState();
                }
                else validtrans = true;

                switch ((MoveGizmoSelected)SelectedPart)
                {
                    case MoveGizmoSelected.XArrow:
                        if (InLocalCoords)
                            Boss.SelectedNode.Trans.Roll(dist * origo.X);
                        else
                            Boss.SelectedNode.Trans.Rotate(new Vector3(dist * origo.X, 0, 0));
                        break;
                    case MoveGizmoSelected.YArrow:
                        if (InLocalCoords)
                            Boss.SelectedNode.Trans.Yaw(dist * origo.Y);
                        else
                            Boss.SelectedNode.Trans.Rotate(new Vector3(0, dist * origo.Y, 0));
                        break;
                    case MoveGizmoSelected.ZArrow:
                        if (InLocalCoords)
                            Boss.SelectedNode.Trans.Pitch(dist * origo.Z);
                        else
                            Boss.SelectedNode.Trans.Rotate(new Vector3(0, 0, dist * origo.Z));
                        break;
                }

                if (Boss.Settings.RigidBodyColCheck && rb != null)
                {
                    if (VisimEngine.Instance.MainScene.CheckPhysicalCollision(rb))
                    {
                        dist *= 0.8f;
                        rb.Trans.PopState();
                    }
                    else
                    {
                        rb.Trans.UndoPushState();
                        validtrans = true;
                    }
                }
            }

            Boss.SceneChanged = true;
            VisimBox.Physics.StaticCollision sc = Boss.SelectedNode as VisimBox.Physics.StaticCollision;
            if (sc!= null)
            {
                if (Boss.Settings.StaticColUpdate)
                {
                    VisimEngine.Instance.MainScene.PhysScene.UpdateStaticCol(sc);
                }
                else Boss.StaticCollisionInvalid = true;
            }

        }

    }
}
