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;

namespace Mix.Tool.ModelEditor
{
    /// <summary>
    /// オブジェクトコリジョンエディタフォームクラス
    /// </summary>
    public partial class ShapeEditorForm : Mix.Tool.Docking.DockContent
    {
        private ShapeEditorSource src = null;
        private bool validateChangeSrc = true;

        /// <summary>
        /// ソースの取得、または設定
        /// </summary>
        public ShapeEditorSource Source
        {
            get { return this.src; }
            set
            {
                this.src = value;

                if (this.src != null)
                {
                    Mix.Tool.Dynamics.Design.Shape shape = this.src.Shape;

                    //ソースの変更開始
                    this.BeginInitControl();

                    //タイトル
                    if (shape is Mix.Tool.Dynamics.Design.BoxShape)
                    {
                        this.Text = string.Format("{0} - {1}", Properties.Resources.JP_SHAPE_EDITOR, Properties.Resources.JP_BOX);
                    }
                    else if (shape is Mix.Tool.Dynamics.Design.CapsuleShape)
                    {
                        this.Text = string.Format("{0} - {1}", Properties.Resources.JP_SHAPE_EDITOR, Properties.Resources.JP_CAPSULE);
                    }
                    else if (shape is Mix.Tool.Dynamics.Design.SphereShape)
                    {
                        this.Text = string.Format("{0} - {1}", Properties.Resources.JP_SHAPE_EDITOR, Properties.Resources.JP_SPHERE);
                    }
                    else
                    {
                        this.Text = string.Format("{0} - {1}", Properties.Resources.JP_SHAPE_EDITOR, Properties.Resources.JP_UNKNOWN);
                    }

                    //ベース
                    this.cbBase.DataSource = this.src.Document.BoundingBoxes.DataSource;
                    this.cbBase.SelectedIndex = this.IndexOfBase(src.Shape.BoundingBox);

//                  this.nudBaseDepth.Enabled = this.src.Shape.BoundingBox.IsAvailableDescend;
                    this.nudBaseDepth.Enabled = this.src.Document is Mix.Tool.Graphics.Node; //ノードの場合のみ( オブジェクトモデルは無効 )
                    this.nudBaseDepth.Value = Convert.ToDecimal(this.src.Shape.BoundingBox.Depth);

                    //シェイプ( プロパティグリッド )
                    this.pgShape.SelectedObject = this.src.Shape;

                    //角度
                    this.nudRX.Value = Convert.ToDecimal(this.src.Shape.Rotation.X);
                    this.nudRY.Value = Convert.ToDecimal(this.src.Shape.Rotation.Y);
                    this.nudRZ.Value = Convert.ToDecimal(this.src.Shape.Rotation.Z);

                    //位置
                    this.nudPX.Value = Convert.ToDecimal(this.src.Shape.Position.X);
                    this.nudPY.Value = Convert.ToDecimal(this.src.Shape.Position.Y);
                    this.nudPZ.Value = Convert.ToDecimal(this.src.Shape.Position.Z);

                    //ソースの変更終了
                    this.EndInitControl();
                }
                else
                {
                    this.pgShape.SelectedObject = null;
                }

                this.UpdateControlState();
            }
        }

        public ShapeEditorForm(Project.Dynamics _dynamics)
        {
            InitializeComponent();

            ////////////////////////////////////////////////////////////////////////////////////////////////////
            // コントロールの初期化
            ////////////////////////////////////////////////////////////////////////////////////////////////////

            this.UpdateControlState();
        }

        private void cbBase_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (this.AvailableSource == true)
            {
                ComboBox cb = sender as ComboBox;

                if (cb.SelectedIndex >= 0)
                {
                    Mix.Tool.Dynamics.Design.BoundingBox boundingBox = cb.Items[cb.SelectedIndex] as Mix.Tool.Dynamics.Design.BoundingBox;

                    this.src.Shape.BoundingBox = boundingBox;
                    this.nudBaseDepth.Enabled = this.src.Shape.BoundingBox.IsAvailableDescend;

                    this.ChangedBase();
                }
            }
        }

        private void nudBaseDepth_ValueChanged(object sender, EventArgs e)
        {
            if (this.AvailableSource == true)
            {
                int index = this.cbBase.SelectedIndex;

                if (index >= 0)
                {
                    Mix.Tool.Dynamics.Design.BoundingBox boundingBox = this.cbBase.Items[index] as Mix.Tool.Dynamics.Design.BoundingBox;

                    if (boundingBox.IsAvailableDescend == true)
                    {
                        NumericUpDown nud = sender as NumericUpDown;

                        this.src.Shape.BoundingBox = boundingBox.Descend(Convert.ToInt32(nud.Value));

                        this.ChangedBase();
                    }
                }
            }
        }

        private void btShapeReset_Click(object sender, EventArgs e)
        {
            if (this.AvailableSource == true)
            {
                this.src.Shape.Reset();
                this.pgShape.SelectedObject = this.src.Shape;

                this.ChangedBase();
            }
        }

        private void nudRX_ValueChanged(object sender, EventArgs e)
        {
            this.ChangedRotation();
        }

        private void nudRY_ValueChanged(object sender, EventArgs e)
        {
            this.ChangedRotation();
        }

        private void nudRZ_ValueChanged(object sender, EventArgs e)
        {
            this.ChangedRotation();
        }

        private void btRotReset_Click(object sender, EventArgs e)
        {
            if (this.AvailableSource == true)
            {
                this.src.Shape.ResetRotation();

                this.BeginInitControl();
                this.nudRX.Value = Convert.ToDecimal(this.src.Shape.Rotation.X);
                this.nudRY.Value = Convert.ToDecimal(this.src.Shape.Rotation.Y);
                this.nudRZ.Value = Convert.ToDecimal(this.src.Shape.Rotation.Z);
                this.EndInitControl();
            }
        }

        private void nudPX_ValueChanged(object sender, EventArgs e)
        {
            this.ChangedPosition();
        }

        private void nudPY_ValueChanged(object sender, EventArgs e)
        {
            this.ChangedPosition();
        }

        private void nudPZ_ValueChanged(object sender, EventArgs e)
        {
            this.ChangedPosition();
        }

        private void btPosReset_Click(object sender, EventArgs e)
        {
            if (this.AvailableSource == true)
            {
                this.src.Shape.ResetPosition();

                this.BeginInitControl();
                this.nudPX.Value = Convert.ToDecimal(this.src.Shape.Position.X);
                this.nudPY.Value = Convert.ToDecimal(this.src.Shape.Position.Y);
                this.nudPZ.Value = Convert.ToDecimal(this.src.Shape.Position.Z);
                this.EndInitControl();
            }
        }

        #region Misc Method

        private void BeginInitControl()
        {
            this.validateChangeSrc = false;
        }

        private void EndInitControl()
        {
            this.validateChangeSrc = true;
        }

        private void UpdateControlState()
        {
            bool enabled = this.src != null;

            foreach (Control ctrl in this.Controls)
            {
                ctrl.Enabled = enabled;
            }

            if (enabled == true)
            {
                this.Activate();
            }
        }

        private bool AvailableSource
        {
            get
            {
                if ((this.validateChangeSrc == false) ||
                    (this.src == null))
                {
                    return false;
                }

                return true;
            }
        }

        private int IndexOfBase(Mix.Tool.Dynamics.Design.BoundingBox boundingBox)
        {
            int index = 0;

            foreach (Mix.Tool.Dynamics.Design.BoundingBox item in this.cbBase.Items)
            {
                if (item.Name.Equals(boundingBox.Name) == true)
                {
                    return index;
                }

                index++;
            }

            return -1;
        }

        private void ChangedRotation()
        {
            if( this.AvailableSource == true )
            {
                Mix.Tool.Math.Vector rot = this.src.Shape.Rotation;

                rot.X = (float)Convert.ToDecimal(this.nudRX.Value);
                rot.Y = (float)Convert.ToDecimal(this.nudRY.Value);
                rot.Z = (float)Convert.ToDecimal(this.nudRZ.Value);

                this.src.Shape.Rotation = rot;
            }
        }

        private void ChangedPosition()
        {
            if (this.AvailableSource == true)
            {
                Mix.Tool.Math.Vector pos = this.src.Shape.Position;

                pos.X = (float)Convert.ToDecimal(this.nudPX.Value);
                pos.Y = (float)Convert.ToDecimal(this.nudPY.Value);
                pos.Z = (float)Convert.ToDecimal(this.nudPZ.Value);

                this.src.Shape.Position = pos;
            }
        }

        private void ChangedBase()
        {
            if (this.AvailableSource == true)
            {
                Mix.Tool.Math.Vector rot = this.src.Shape.Rotation;
                Mix.Tool.Math.Vector pos = this.src.Shape.Position;

                this.pgShape.SelectedObject = this.src.Shape;

                this.nudRX.Value = Convert.ToDecimal(rot.X);
                this.nudRY.Value = Convert.ToDecimal(rot.Y);
                this.nudRZ.Value = Convert.ToDecimal(rot.Z);

                this.nudPX.Value = Convert.ToDecimal(pos.X);
                this.nudPY.Value = Convert.ToDecimal(pos.Y);
                this.nudPZ.Value = Convert.ToDecimal(pos.Z);
            }
        }

        #endregion
    }
}
