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

namespace VisimBuilder
{
    public partial class TransformationControl : UserControl
    {
        public ITransformation attachedTrans;

        public TransformationControl()
        {
            InitializeComponent();
            attachedTrans = null;
        }

        public TransformationControl(ITransformation trans)
        {
            attachedTrans = trans;
            InitializeComponent();
            UpdateFrom();
        }

        public void ChangeTrans(ITransformation trans)
        {
            attachedTrans = trans;
            UpdateFrom();
        }

        public void UpdateFrom()
        {
            if (attachedTrans == null)
            {
                this.textBoxPos.ReadOnly = this.textBoxRot.ReadOnly = this.textBoxScale.ReadOnly = true;
                this.textBoxPos.Text = this.textBoxRot.Text = this.textBoxScale.Text = "";
                return;
            }

            Vector3 pos;
            Vector3 rot;
            Vector3 scale;
            float uniscale;
            attachedTrans.GetAll(out pos, out rot, out scale, out uniscale);
            this.textBoxPos.Text = string.Format("{0} : {1} : {2}",
                pos.X.ToString("F"), pos.Y.ToString("F"), pos.Z.ToString("F"));

            this.textBoxPos.ReadOnly = !attachedTrans.Movable;
            this.textBoxRot.ReadOnly = !attachedTrans.Rotable;
            this.textBoxScale.ReadOnly = !attachedTrans.Scalable;


            MathTools.RadToDeg(ref rot);

            this.textBoxRot.Text = string.Format("{0} : {1} : {2}",
                rot.X.ToString("F"), rot.Y.ToString("F"), rot.Z.ToString("F"));

            if (uniscale != 0)
            {
                this.textBoxScale.Text = string.Format("{0}%", uniscale * 100);
            }
            else
            {
                this.textBoxScale.Text = string.Format("{0} : {1} : {2}",
                    scale.X.ToString("F"), scale.Y.ToString("F"), scale.Z.ToString("F"));
            }           
        }

        public void UpdateTo()
        {
            UpdateToPosition();
            UpdateToRotation();
            UpdateToScale();
        }

        public Vector3 ParseString(string str)
        {
            StringParser parser = new StringParser(str, ':');
            if (parser.WordCount != 3)
                return Vector3.Invalid;
            if (!parser.IsFloat(0) || !parser.IsFloat(1) || !parser.IsFloat(2))
                return Vector3.Invalid;

            return new Vector3(parser.GetFloat(0), parser.GetFloat(1), parser.GetFloat(2));
        }

        public void UpdateToPosition()
        {
            //try parse the textbox to vector
            Vector3 pos = ParseString(textBoxPos.Text);

            if (pos.IsValid())
            {
                if (attachedTrans != null)
                {
                    attachedTrans.Position = pos;
                }
            }
            else
            {
                MessageBox.Show("Invalid vector format!");
                UpdateFrom();
            }
        }

        public void UpdateToRotation()
        {
            //try parse the textbox to vector
            Vector3 rot = ParseString(this.textBoxRot.Text);

            if (rot.IsValid())
            {
                if (attachedTrans != null)
                {
                    MathTools.DegToRad(ref rot);                    
                    attachedTrans.RPY = rot;
                }
            }
            else
            {
                MessageBox.Show("Invalid vector format!");
                UpdateFrom();
            }
        }

        public void UpdateToScale()
        {
            //check if uniform
            string str = this.textBoxScale.Text;

            int idx = str.IndexOf('%');
            if (idx >= 0)
            {
                if (idx == str.Length - 1)
                {
                    string subs = str.Substring(0, str.Length - 1);
                    float f;
                    try
                    {
                        f = (float)Convert.ToDouble(subs);
                        f = f / 100;
                        if (attachedTrans != null)
                        {
                            attachedTrans.UniformScale = f;
                        }
                        return;
                    }
                    catch
                    {
                    }
                }
            }
            else
            {
                Vector3 scal = ParseString(str);
                if (scal.IsValid())
                {
                    attachedTrans.Scale = scal;
                    return;
                }
            }
            MessageBox.Show("Invalid scale format!");
            UpdateFrom();
        }



        private void poschanged(object sender, EventArgs e)
        {
        }

        private void keyPressPos(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)13)
            {
                UpdateToPosition();
                e.Handled = true;
            }
        }

        private void focusLeavePos(object sender, EventArgs e)
        {
            UpdateToPosition();
        }

        private void keyPressRot(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)13)
            {
                UpdateToRotation();
                e.Handled = true;
            }

        }

        private void focusLeaveRot(object sender, EventArgs e)
        {
            UpdateToRotation();
        }

        private void focusLeaveScale(object sender, EventArgs e)
        {
            UpdateToScale();
        }

        private void keyPressScale(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)13)
            {
                UpdateToScale();
                e.Handled = true;
            }
        }




    }
}
