using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using VisiMath;
using VisimBox;
using VisiMath.Geometry;
using VisimBox.Renderer;
using VisimBox.Scene;

namespace RobotArmDemo
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }


        protected Node Waist, Shoulder, Arm, Wrist;

        public Node CreateArm()
        {
            var matman = VisimEngine.Instance.Renderer.MaterialMan;
            IRenderMaterial mat = matman.Add("robot", new StandardColorValues(ColorByte.Blue));

            Node rval = new Node();

            AABox box0 = new AABox(3, 3, 1);
            GeometryNode gb0 = new GeometryNode(box0, mat);
            gb0.Trans = new QTransformation();
            gb0.Trans.Position = new Vector3(20, 0, -5);
            //gb0.Trans.Pitch(0.57f);
            rval.AddNode(gb0, "Waist");
            Waist = gb0;

            AABox box1 = new AABox(new Vector3(-0.7f, -0.7f, 0.5f), new Vector3(0.7f, 0.7f, 4.5f));
            GeometryNode gb1 = new GeometryNode(box1, mat);
            gb0.AddNode(gb1, "Box1");

            AABox box11 = new AABox(new Vector3(-0.5f, -0.5f, 4.5f), new Vector3(0.5f, 1.5f, 5.5f));

            GeometryNode gb11 = new GeometryNode(box11, mat);
            gb0.AddNode(gb11, "Box11");



            AABox box2 = new AABox(new Vector3(-1.0f, -0.2f, -1.0f), new Vector3(3.5f, 0.2f, 1.0f));
            GeometryNode gb2 = new GeometryNode(box2, mat);
            gb2.Trans = new QTransformation();
            gb2.Trans.Position = new Vector3(0, 1.5f, 5.0f);
            gb0.AddNode(gb2, "Shoulder");
            Shoulder = gb2;

            AABox box3 = new AABox(new Vector3(-0.5f, -0.5f, 0), new Vector3(0.5f, 0.5f, 4));

            GeometryNode gb3 = new GeometryNode(box3, mat);
            gb3.Trans = new QTransformation();
            gb3.Trans.Position = new Vector3(3, 0.7f, 0);

            gb2.AddNode(gb3, "Arm");

            Arm = gb3;

            AABox box4 = new AABox(new Vector3(-0.3f, -0.3f, 0), new Vector3(0.3f, 0.3f, 0.8f));
            GeometryNode gb4 = new GeometryNode(box4, mat);
            gb4.Trans = new QTransformation();
            gb4.Trans.Position = new Vector3(0, 0, 4);

            gb3.AddNode(gb4, "Wrist");

            Wrist = gb4;

            AABox box5 = new AABox(new Vector3(-0.8f, -0.3f, 0), new Vector3(0.8f, 0.3f, 0.1f));

            GeometryNode gb5 = new GeometryNode(box5, mat);
            gb5.Trans = new QTransformation();
            gb5.Trans.Position = new Vector3(0, 0, 0.85f);

            gb4.AddNode(gb5, "Fingers");

            AABox boxfinger = new AABox(new Vector3(-0.1f, -0.3f, 0), new Vector3(0.1f, 0.3f, 0.5f));

            GeometryNode gb6 = new GeometryNode(boxfinger, mat);
            gb6.Trans = new QTransformation();
            gb6.Trans.Position = new Vector3(-0.8f, 0, 0);

            gb5.AddNode(gb6, "Finger1");

            GeometryNode gb7 = new GeometryNode(boxfinger, mat);
            gb7.Trans = new QTransformation();
            gb7.Trans.Position = new Vector3(0.8f, 0, 0);

            gb5.AddNode(gb7, "Finger2");



            var light = VisimEngine.Instance.Renderer.LightMan.AddDirectional("light", new Vector3(0, 0, 1), new ColorByte(50, 50, 50), ColorByte.White);


            var lnode = new LightNode(light);
            lnode.Visible = false;
            lnode.Trans = new QTransformation();
            lnode.Trans.Move(new Vector3(0, 0, 15));
            lnode.Trans.Yaw(1.0f);
            lnode.Trans.Pitch(-0.4f);
            lnode.UpdateLight(0);

            rval.AddNode(lnode, "Light");

            return rval;
        }

        private void Startup(object sender, EventArgs e)
        {
            if (DesignMode)
                return;

            VisimEngine.Instance.Initialize(new VisimBox.Renderer.RenderContextSettings(this.visimBoxControl1));
            VisimEngine.Instance.NewScene();
            VisimEngine.Instance.MainScene.AddNode(CreateArm());

            VisimEngine.Instance.Renderer.MainContext.MainCamera = new FPSCamera();

            Application.Idle += new EventHandler(Application_Idle);
        }

        void Application_Idle(object sender, EventArgs e)
        {
            while (IddleCheck())
            {
                RenderScreen();
            }
        }

        bool IddleCheck()
        {
            if (!ContainsFocus)
                return false;
            return VisimEngine.Instance.Renderer.IsIdle();
        }

        private void RenderScreen()
        {
            var irc = VisimEngine.Instance.Renderer.MainContext;
            irc.StartFrame();
            irc.RenderNodes(VisimEngine.Instance.MainScene);
            irc.EndFrame();
        }

        private void RenderScreen(object sender, PaintEventArgs e)
        {
            RenderScreen();
        }

        int mousex, mousey;

        private void MouseMoving(object sender, MouseEventArgs e)
        {
            int deltax = mousex - e.X;
            int deltay = mousey - e.Y;

            mousex = e.X;
            mousey = e.Y;

            if (e.Button == System.Windows.Forms.MouseButtons.Right)
            {
                var irc = VisimEngine.Instance.Renderer.MainContext;

                if (irc.MainCamera != null)
                {
                    irc.MainCamera.Yaw(VisiMath.MathTools.DegToRad(deltay));
                    irc.MainCamera.Pitch(VisiMath.MathTools.DegToRad(-deltax));
                }
            }

        }

        private void WaistChange(object sender, EventArgs e)
        {
            float angle = MathTools.DegToRad((float)numericUpDown1.Value);
            Waist.Trans.Rotation = Quaternion.CreateFromRPY(0, 0, angle);
        }

        private void ShoulderChanged(object sender, EventArgs e)
        {
            float angle = MathTools.DegToRad((float)numericUpDown2.Value);
            Shoulder.Trans.Rotation = Quaternion.CreateFromRPY(0, angle, 0);

        }

        private void ArmChanged(object sender, EventArgs e)
        {
            float angle = MathTools.DegToRad((float)numericUpDown3.Value);
            Arm.Trans.Rotation = Quaternion.CreateFromRPY(0, angle, 0);

        }

        private void WristChanged(object sender, EventArgs e)
        {
            float angle = MathTools.DegToRad((float)numericUpDown4.Value);
            Wrist.Trans.Rotation = Quaternion.CreateFromRPY(0, 0, angle);

        }    



    }
}
