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.Geometry;
using VisiMath;
using VisimBox.Scene;
using VisimBox;
using VisimBox.Renderer;

namespace VisimBuilder.ObjectCreation
{
    public partial class ObjectCreationBasePhysical : ObjectCreationBase
    {

        MainBuilderForm.MaterialChangedCallback MaterialCallback;

        private bool _RigidBodyEnabled = true;
        protected bool RigidBodyEnabled
        {
            get
            {
                return _RigidBodyEnabled;
            }
            set
            {
                if (_RigidBodyEnabled != value)
                {
                    _RigidBodyEnabled = value;
                    if (value)
                    {
                        radioButtonRigidBody.Enabled = true;
                        checkBoxScale.Enabled = true;
                    }
                    else
                    {
                        if (radioButtonRigidBody.Checked)
                        {
                            radioButtonStaticCol.Checked = true;
                        }
                        radioButtonRigidBody.Enabled = false;
                        if (checkBoxScale.Checked)
                            checkBoxScale.Checked = false;
                        checkBoxScale.Enabled = false;
                    }
                }
            }
        }

        public ObjectCreationBasePhysical()
        {
            InitializeComponent();
        }

        

        public void UpdateMaterials()
        {
            var matman = VisimBox.VisimEngine.Instance.Renderer.MaterialMan;

            string selected = (string)comboBoxMaterials.SelectedItem;

            comboBoxMaterials.Items.Clear();

            foreach (var mat in matman)
            {
                comboBoxMaterials.Items.Add(mat.Value.Name);
            }

            if (selected != null)
                comboBoxMaterials.SelectedItem = selected;
            else
                comboBoxMaterials.SelectedItem = "default";

        }

        public override void Init(MainBuilderForm boss)
        {
            //stupid c# GUI designer;
            Boss = boss;
            if (Boss.SelectedMaterial != null)
                comboBoxMaterials.SelectedItem = Boss.SelectedMaterial;

            MaterialCallback = new MainBuilderForm.MaterialChangedCallback(Boss_SelectedMaterialChanged);
            NodeCallback = new MainBuilderForm.NodeChangedCallback(Boss_SelectedNodeChanged);

            Boss.SelectedMaterialChanged += MaterialCallback;
            Boss.SelectedNodeChanged += NodeCallback;

            UpdateMaterials();
        }

        void Boss_SelectedMaterialChanged()
        {
            UpdateMaterials();
            if (Boss.SelectedMaterial != null)
                comboBoxMaterials.SelectedItem = Boss.SelectedMaterial;
        }


        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            if (DesignMode)
                return;

            physdlg = new PhysSettingDlg();
            UpdateMaterials();
            if (Boss.SelectedMaterial != null)
                comboBoxMaterials.SelectedItem = Boss.SelectedMaterial;
        }

        public virtual Node ObjectCreation(string name, ITransformation itrans, Type VertexType, PhysBodyType physbody, PhysSettingsEdit physsettings, BoundingObjectType bounding, IRenderMaterial mat, Node owner)
        {
            //do nothing
            return null;
        }

        public override Node ObjectCreation(string name, ITransformation itrans, Node owner)
        {            
            #region vertex type
            Type VertexType;

            if (checkBoxTextured.Checked)
            {
                if (checkBoxNormals.Checked)
                {
                    if (checkBoxColors.Checked)
                    {
                        VertexType = typeof(Vertex);
                    }
                    else
                        VertexType = typeof(TexturedVertex);
                }
                else
                    VertexType = typeof(SimpleTexturedVertex);
            }
            else
            {
                if (checkBoxNormals.Checked)
                {
                    if (checkBoxColors.Checked)
                    {
                        VertexType = typeof(ColoredNormalVertex);
                    }
                    else
                        VertexType = typeof(NormalVertex);
                }
                else
                {
                    VertexType = typeof(PositionVertex);
                }
            }
            #endregion

            #region Bounding Object

            BoundingObjectType bt;

            if (checkBoxGenerateBO.Checked)
            {
                if (checkBoxSphere.Checked)
                    bt = BoundingObjectType.Sphere;
                else if (checkBoxBox.Checked)
                    bt = BoundingObjectType.Box;
                else
                    bt = BoundingObjectType.BestFit;
            }
            else bt = BoundingObjectType.None;


            #endregion

            #region material

            IRenderMaterial mat = null;


            if (VisimEngine.Instance.Renderer.MaterialMan.Contains((string)comboBoxMaterials.SelectedItem))
                mat = VisimEngine.Instance.Renderer.MaterialMan[(string)comboBoxMaterials.SelectedItem];

            #endregion

            PhysBodyType physbody = PhysBodyType.None;

            if (radioButtonRigidBody.Checked)
                if (checkBoxDoVisible.Checked)
                    physbody = PhysBodyType.RigidVisual;
                else physbody = PhysBodyType.Rigid;
            else if (radioButtonStaticCol.Checked)
                if (checkBoxDoVisible.Checked)
                    physbody = PhysBodyType.StaticVisual;
                else physbody = PhysBodyType.Static;
            
            return ObjectCreation(name, itrans, VertexType, physbody, this.physdlg.PhysData, bt, mat, owner);
        }

        //note, this is really stupid, change object creating completely!

        protected bool DoVisual(PhysBodyType type)
        {
            switch (type)
            {
                case PhysBodyType.Rigid:
                case PhysBodyType.Static:
                    return false;
                default:
                    return true;
            }
        }

        protected bool DoRigid(PhysBodyType type)
        {
            if ((type == PhysBodyType.Rigid) || (type == PhysBodyType.RigidVisual))
                return true;
            return false;
        }

        protected bool DoStatic(PhysBodyType type)
        {
            if ((type == PhysBodyType.Static) || (type == PhysBodyType.StaticVisual))
                return true;
            return false;
        }

        #region Bounding Box creation

        private void BOChanged(object sender, EventArgs e)
        {
            if (checkBoxGenerateBO.Checked)
            {
                if (!checkBoxChoose.Checked && !checkBoxBox.Checked && !checkBoxSphere.Checked)
                {
                    checkBoxChoose.Checked = true;
                }
            }
            else
            {
                checkBoxChoose.Checked = false;
                checkBoxBox.Checked = false;
                checkBoxSphere.Checked = false;
            }
        }

        private void SphereCheckBox(object sender, EventArgs e)
        {
            if (checkBoxSphere.Checked)
            {
                if (!checkBoxGenerateBO.Checked)
                    checkBoxGenerateBO.Checked = true;
                if (checkBoxChoose.Checked)
                    checkBoxChoose.Checked = false;
                if (checkBoxBox.Checked)
                    checkBoxBox.Checked = false;
            }
            else
            {
                if (checkBoxGenerateBO.Checked)
                {
                    if (!checkBoxBox.Checked && !checkBoxChoose.Checked)
                        checkBoxChoose.Checked = true;
                }
            }
        }

        private void CheckBoxChanged(object sender, EventArgs e)
        {
            if (checkBoxBox.Checked)
            {
                if (!checkBoxGenerateBO.Checked)
                    checkBoxGenerateBO.Checked = true;
                if (checkBoxChoose.Checked)
                    checkBoxChoose.Checked = false;
                if (checkBoxSphere.Checked)
                    checkBoxSphere.Checked = false;
            }
            else
            {
                if (checkBoxGenerateBO.Checked)
                {
                    if (!checkBoxSphere.Checked && !checkBoxChoose.Checked)
                        checkBoxChoose.Checked = true;
                }
            }
        }

        private void CheckBoxChooseChange(object sender, EventArgs e)
        {
            if (checkBoxChoose.Checked)
            {
                if (!checkBoxGenerateBO.Checked)
                    checkBoxGenerateBO.Checked = true;
                if (checkBoxBox.Checked)
                    checkBoxBox.Checked = false;
                if (checkBoxSphere.Checked)
                    checkBoxSphere.Checked = false;
            }
            else
            {
                if (checkBoxGenerateBO.Checked)
                {
                    if (!checkBoxSphere.Checked && !checkBoxBox.Checked)
                        checkBoxBox.Checked = true;
                }
            }

        }

        #endregion

        #region Material

        private void ChooseMaterial(object sender, EventArgs e)
        {
            Boss.ShowMatEditor();
        }

        private void CheckMaterial()
        {
            MaterialManager man = VisimEngine.Instance.Renderer.MaterialMan;
            if (!man.Contains((string)comboBoxMaterials.SelectedItem))
            {
                MessageBox.Show("Material not found!");
            }
        }


        private void MatNameKeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)13)
            {
                CheckMaterial();
            }
        }

        private void MatNameFocusLeave(object sender, EventArgs e)
        {
            CheckMaterial();
        }

        #endregion


        public override void SetDefault()
        {
            textBoxName.Text = "New object";
            checkBoxColors.Checked = false;
            checkBoxNormals.Checked = true;
            checkBoxTextured.Checked = true;

            //MaterialName.Text = "default";

            checkBoxDoTrans.Checked = true;
            checkBoxRot.Checked = true;
            checkBoxScale.Checked = true;

            checkBoxGenerateBO.Checked = true;
            checkBoxSphere.Checked = checkBoxBox.Checked = false;
            checkBoxChoose.Checked = true;

            checkBoxToRoot.Checked = true;
            checkBoxToSelected.Checked = false;
        }

        private void PhysTypeChanged(object sender, EventArgs e)
        {
            if (radioButtonVisualOnly.Checked)
            {
                buttonPhysSettings.Enabled = false;
                if (checkBoxDoVisible.Enabled)
                    checkBoxDoVisible.Enabled = false;
                if (!checkBoxDoVisible.Checked)
                    checkBoxDoVisible.Checked = true;
            }
            else 
            {
                if (!checkBoxDoVisible.Enabled)
                    checkBoxDoVisible.Enabled = true;
                buttonPhysSettings.Enabled = true;
            }
        }

        private PhysSettingDlg physdlg;

        private void buttonPhysSettings_Click(object sender, EventArgs e)
        {
            if (radioButtonStaticCol.Checked)
            {
                physdlg.PhysData.StaticCol = true;
                physdlg.PhysData.StayStatic = true;
            }
            else
            {
                physdlg.PhysData.StaticCol = false;
                physdlg.PhysData.StayStatic = false;
            }
            physdlg.ShowDialog();   //todo - undo changing values if cancel!
        }

    }

    public enum BoundingObjectType { None, Box, Sphere, BestFit };

    public enum PhysBodyType { None, Static, Rigid, StaticVisual, RigidVisual };

}
