using System;
using System.Xml;
using System.Windows.Forms;
using System.Drawing;

namespace Mix.Tool.ModelEditor
{
    /// <summary>
    /// プロジェクトテンプレートクラス
    /// </summary>
    public partial class ProjectTemplateForm : Form
    {
        [Flags]
        private enum LockKeyBits
        {
            None = 0x00,
            Mask = 0x07,

            Ctrl = 0x01,
            Shift = 0x02,
            L = 0x04,
        }

        private string rootDir = "";
        private Project.Template template = null;
        private LockKeyBits lockKeyBits = LockKeyBits.None;
        private bool editLock = false;

        public ProjectTemplateForm(string _rootDir, Project.Template _template)
        {
            InitializeComponent();

            this.rootDir = _rootDir;
            this.template = _template;

            this.UpdateControlsState();
        }

        private void ProjectTemplateForm_Load(object sender, EventArgs e)
        {
            if (this.tbGeneFilePath.Text.Length > 0)
            {
                try
                {
                    this.editLock = true;
                }
                catch
                {
                    this.editLock = false;
                }
            }

            this.partGene.Enabled = !this.editLock;
            this.lbGeneFilePath.Enabled = !this.editLock;
            this.tbGeneFilePath.Enabled = !this.editLock;
            this.btGeneFilePath.Enabled = !this.editLock;
            this.lbGeneDesc.Enabled = !this.editLock;
            this.tbGeneDesc.Enabled = !this.editLock;

            this.partEffect.Enabled = !this.editLock;
            this.gbShaderModel.Enabled = !this.editLock;
            this.gbShaderProcess.Enabled = !this.editLock;
            this.gbEffectPackage.Enabled = !this.editLock;
            this.gbCUSearchDir.Enabled = !this.editLock;

            this.UpdateOKButton();
        }

        private void ProjectTemplateForm_KeyDown(object sender, KeyEventArgs e)
        {
            if (this.editLock == true)
            {
                if (e.KeyCode == Keys.ControlKey)
                {
                    this.lockKeyBits |= LockKeyBits.Ctrl;
                }

                if (e.KeyCode == Keys.ShiftKey)
                {
                    this.lockKeyBits |= LockKeyBits.Shift;
                }

                if (e.KeyCode == Keys.L)
                {
                    this.lockKeyBits |= LockKeyBits.L;
                }

                if (this.lockKeyBits == LockKeyBits.Mask)
                {
                    this.partGene.Enabled = true;
                    this.lbGeneFilePath.Enabled = true;
                    this.tbGeneFilePath.Enabled = true;
                    this.btGeneFilePath.Enabled = true;
                    this.lbGeneDesc.Enabled = true;
                    this.tbGeneDesc.Enabled = true;

                    this.partEffect.Enabled = true;
                    this.gbShaderModel.Enabled = true;
                    this.gbShaderProcess.Enabled = true;
                    this.gbEffectPackage.Enabled = true;
                    this.gbCUSearchDir.Enabled = true;

                    this.editLock = false;

                    this.UpdateOKButton();
                }
            }
        }

        private void ProjectTemplateForm_KeyUp(object sender, KeyEventArgs e)
        {
            if (this.editLock == true)
            {
                if (e.KeyCode == Keys.ControlKey)
                {
                    this.lockKeyBits ^= LockKeyBits.Ctrl;
                }

                if (e.KeyCode == Keys.ShiftKey)
                {
                    this.lockKeyBits ^= LockKeyBits.Shift;
                }

                if (e.KeyCode == Keys.L)
                {
                    this.lockKeyBits ^= LockKeyBits.L;
                }
            }
        }

        private void btGeneFilePath_Click(object sender, EventArgs e)
        {
            using (SaveFileDialog dlg = new SaveFileDialog())
            {
                if (this.template.FilePath.Length > 0)
                {
                    try
                    {
                        dlg.InitialDirectory = System.IO.Path.GetDirectoryName(this.template.FilePath);
                    }
                    catch
                    {
                        dlg.InitialDirectory = System.IO.Path.GetPathRoot(this.template.FilePath);
                    }

                    dlg.FileName = System.IO.Path.GetFileName(this.template.FilePath);
                }
                else
                {
                    dlg.InitialDirectory = "";
                    dlg.FileName = "";
                }

                dlg.Filter = Properties.Resources.FILE_FILTER_PTM;
                dlg.CheckFileExists = false;

                if (dlg.ShowDialog() == DialogResult.OK)
                {
                    this.template.FilePath = dlg.FileName;
                    this.tbGeneFilePath.Text = template.FilePath;

                    try
                    {
                        this.template.Load();
                        this.UpdateControlsState();
                    }
                    catch
                    {
                    }
                }
            }
        }

        private void tbGeneFilePath_TextChanged(object sender, EventArgs e)
        {
            this.UpdateOKButton();
        }

        private void tbGeneDesc_TextChanged(object sender, EventArgs e)
        {
            this.UpdateOKButton();
        }

        private void cbShaderModel3_CheckedChanged(object sender, EventArgs e)
        {
            this.UpdateOKButton();
        }

        private void cbShaderModel4_CheckedChanged(object sender, EventArgs e)
        {
            this.UpdateOKButton();
        }

        private void cbShaderModel5_CheckedChanged(object sender, EventArgs e)
        {
            this.UpdateOKButton();
        }

        private void tbEffectPackageName_TextChanged(object sender, EventArgs e)
        {
            this.UpdateOKButton();
        }

        private void tbEffectPackageDirPath_TextChanged(object sender, EventArgs e)
        {
            this.UpdateOKButton();
        }

        private void btEffectPackageDirPath_Click(object sender, EventArgs e)
        {
            using (Mix.Tool.DirectoryBrowseDialog dlg = new DirectoryBrowseDialog())
            {
                dlg.Root = DirectoryBrowseDialog.RootType.Specify;
                dlg.RootDirectoryName = this.rootDir;
                dlg.DirectoryName = System.IO.Path.Combine(this.rootDir, this.tbEffectPackageDirPath.Text);

                if (dlg.ShowDialog() == DialogResult.OK)
                {
                    this.tbEffectPackageDirPath.Text = dlg.ShortDirectoryName;
                }
            }
        }

        private void cmsCUSearchDir_Opening(object sender, System.ComponentModel.CancelEventArgs e)
        {
            Point mousePos = this.lbCUSearchDir.PointToClient(System.Windows.Forms.Cursor.Position);
            int index = this.lbCUSearchDir.IndexFromPoint(mousePos);

            this.miSearchDir_Add.Enabled = true;

            if (index != ListBox.NoMatches)
            {
                this.lbCUSearchDir.SelectedIndex = index;
                this.miSearchDir_Remove.Enabled = true;
            }
            else
            {
                this.miSearchDir_Remove.Enabled = false;
            }
        }

        private void miSearchDir_Add_Click(object sender, EventArgs e)
        {
            using (Mix.Tool.DirectoryBrowseDialog dlg = new DirectoryBrowseDialog())
            {
                dlg.Root = DirectoryBrowseDialog.RootType.MyComputer;

                if (dlg.ShowDialog() == DialogResult.OK)
                {
                    if (this.lbCUSearchDir.Items.Contains(dlg.DirectoryName) == false)
                    {
                        this.lbCUSearchDir.Items.Add(dlg.DirectoryName);
                    }
                    else
                    {
                        Mix.Tool.MessageDialog.ShowOK(Properties.Resources.EXISTS_DIR, Properties.Resources.TITLE, MessageDialogIcon.Error);
                    }
                }
            }
        }

        private void miSearchDir_Remove_Click(object sender, EventArgs e)
        {
            this.lbCUSearchDir.Items.RemoveAt(this.lbCUSearchDir.SelectedIndex);
        }

        private void btOK_Click(object sender, EventArgs e)
        {
            bool closeEdit = true;

            try
            {
                Mix.Tool.Graphics.ShaderModels shaderModels = Mix.Tool.Graphics.ShaderModels.Init;
                Mix.Tool.Graphics.ShaderProcessFlags shaderEffects = Mix.Tool.Graphics.ShaderProcessFlags.Init;

                if (this.cbShaderModel3.Checked == true) shaderModels |= Mix.Tool.Graphics.ShaderModels.DirectX9_3_0;
                if (this.cbShaderModel4.Checked == true) shaderModels |= Mix.Tool.Graphics.ShaderModels.DirectX10_4_0;
                if (this.cbShaderModel5.Checked == true) shaderModels |= Mix.Tool.Graphics.ShaderModels.DirectX11_5_0;

                if (this.cbProcFog.Checked == true) shaderEffects |= Mix.Tool.Graphics.ShaderProcessFlags.Fog;
                if (this.cbProcShadow.Checked == true) shaderEffects |= Mix.Tool.Graphics.ShaderProcessFlags.Shadow;
                if (this.cbProcRefract.Checked == true) shaderEffects |= Mix.Tool.Graphics.ShaderProcessFlags.Refract;
                if (this.cbProcScattering.Checked == true) shaderEffects |= Mix.Tool.Graphics.ShaderProcessFlags.Atmosphere;
                if (this.cbProcSSAO.Checked == true) shaderEffects |= Mix.Tool.Graphics.ShaderProcessFlags.SSAO;

                this.template.FilePath = tbGeneFilePath.Text;
                this.template.Desc = this.tbGeneDesc.Text;
                this.template.ShaderModels = shaderModels;
                this.template.ShaderProcFlags = shaderEffects;
                this.template.EffectPackageName = this.tbEffectPackageName.Text;
                this.template.EffectPackageDirectoryPath = this.tbEffectPackageDirPath.Text;

                this.template.EffectSearchDirCollection.Clear();
                foreach( string dirPath in this.lbCUSearchDir.Items )
                {
                    this.template.EffectSearchDirCollection.Add(dirPath);
                }
            }
            catch
            {
                if (Mix.Tool.MessageDialog.Show(Properties.Resources.XML_PT_ERROR_EDITSAVE, Properties.Resources.TITLE, MessageDialogButtons.OK, MessageDialogIcon.Error) != DialogResult.OK)
                {
                    closeEdit = false;
                }
            }

            if (closeEdit == true)
            {
                this.Close();
            }
        }

        private void btCancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void UpdateControlsState()
        {
            this.tbGeneFilePath.Text = this.template.FilePath;
            this.tbGeneDesc.Text = this.template.Desc;
            this.cbShaderModel3.Checked = (this.template.ShaderModels & Mix.Tool.Graphics.ShaderModels.DirectX9_3_0) == Mix.Tool.Graphics.ShaderModels.DirectX9_3_0;
            this.cbShaderModel4.Checked = (this.template.ShaderModels & Mix.Tool.Graphics.ShaderModels.DirectX10_4_0) == Mix.Tool.Graphics.ShaderModels.DirectX10_4_0;
            this.cbShaderModel5.Checked = (this.template.ShaderModels & Mix.Tool.Graphics.ShaderModels.DirectX11_5_0) == Mix.Tool.Graphics.ShaderModels.DirectX11_5_0;
            this.cbProcFog.Checked = (this.template.ShaderProcFlags & Mix.Tool.Graphics.ShaderProcessFlags.Fog) == Mix.Tool.Graphics.ShaderProcessFlags.Fog;
            this.cbProcShadow.Checked = (this.template.ShaderProcFlags & Mix.Tool.Graphics.ShaderProcessFlags.Shadow) == Mix.Tool.Graphics.ShaderProcessFlags.Shadow;
            this.cbProcRefract.Checked = (this.template.ShaderProcFlags & Mix.Tool.Graphics.ShaderProcessFlags.Refract) == Mix.Tool.Graphics.ShaderProcessFlags.Refract;
            this.cbProcScattering.Checked = (this.template.ShaderProcFlags & Mix.Tool.Graphics.ShaderProcessFlags.Atmosphere) == Mix.Tool.Graphics.ShaderProcessFlags.Atmosphere;
            this.cbProcSSAO.Checked = (this.template.ShaderProcFlags & Mix.Tool.Graphics.ShaderProcessFlags.SSAO) == Mix.Tool.Graphics.ShaderProcessFlags.SSAO;
            this.tbEffectPackageName.Text = template.EffectPackageName;
            this.tbEffectPackageDirPath.Text = template.EffectPackageDirectoryPath;

            this.lbCUSearchDir.Items.Clear();
            foreach (string dirPath in this.template.EffectSearchDirCollection)
            {
                this.lbCUSearchDir.Items.Add(dirPath);
            }
        }

        private void UpdateOKButton()
        {
            bool okEnabled = true;

            if (this.editLock == true)
            {
                okEnabled = false;
            }
            else if (this.tbGeneFilePath.Text.Length == 0)
            {
                okEnabled = false;
            }
            else if (this.tbGeneDesc.Text.Length == 0)
            {
                okEnabled = false;
            }
            else if ((this.cbShaderModel3.Checked == false) &&
                (this.cbShaderModel4.Checked == false) &&
                (this.cbShaderModel5.Checked == false))
            {
                okEnabled = false;
            }
            else if (this.tbEffectPackageName.Text.Length == 0)
            {
                okEnabled = false;
            }
            else if (this.tbEffectPackageDirPath.Text.Length == 0)
            {
                okEnabled = false;
            }

            this.btOK.Enabled = okEnabled;
        }
    }
}
