using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Xml;
using System.Threading;
using System.ComponentModel;

namespace Mix.Tool.FontEditor
{
    public partial class MainForm : Form
    {
        #region Native

        const uint SC_CLOSE = 0xF060;
        const uint MF_ENABLED = 0x00000000;
        const uint MF_GRAYED = 0x00000001;

        [System.Runtime.InteropServices.DllImport("user32.dll")]
        static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);

        [System.Runtime.InteropServices.DllImport("user32.dll")]
        static extern bool EnableMenuItem(IntPtr hMenu, uint enableItemID, uint enable);

        #endregion

        #region Private Constant

        private const string MFP_VERSION = "1.0.0.0";

        #endregion

        #region Private Value

        [Flags]
        private enum FontUpdateFlags: uint
        {
            Style = 0x00000001,
            Size = 0x00000002,
            Weight = 0x00000004,
            Effects = 0x00000008,
            BorderSize = 0x0000010,
            TextList = 0x00000020,
            OutputFileName = 0x00000040,
        };

        private delegate void DelegateLogClear();
        private delegate void DelegateLogPrint(Mix.Tool.Logger.Type type, String str);
        private delegate void DelegateFontCreatorProgress(int progress);
        private delegate void DelegateFontCreatorChangeState(Mix.Tool.Font.Creator.State state);

        private Mix.Tool.FileDirector fileDirector = null;
        private Mix.Tool.Font.Viewer viewer = null;

        private string fontStyle;
        private int fontSize;
        private int fontWeight;
        private Mix.Tool.Font.Effects fontEffcts;
        private int fontBorderSize;
        private List<string> fontTextList = new List<string>();
        private string fontFilePath;
        private FontUpdateFlags fontUpdateFlags;
        private bool outputting = false;

        private float horizRatio = 0.0f;
        private float vertRatio = 0.0f;

        #endregion

        #region Public Method

        public MainForm()
        {
            InitializeComponent();

            using (Mix.Tool.Font.StyleCollection fontStyleCollection = new Mix.Tool.Font.StyleCollection(Handle))
            {
                foreach (System.String fontStyle in fontStyleCollection)
                {
                    this.cbFontStyle.Items.Add(fontStyle);
                }

                this.cbFontStyle.SelectedIndex = 0;
            }

            this.fileDirector = new FileDirector(this);
            this.fileDirector.New = new FileDirector.DelegateNew(OnNew);
            this.fileDirector.Open = new FileDirector.DelegateOpen(OnOpen);
            this.fileDirector.Save = new FileDirector.DelegateSave(OnSave);
            this.fileDirector.NewName = "新規プロジェクト.xml";
            this.fileDirector.Filter = "プロジェクトファイル|*.xml";
            this.fileDirector.DoNew();

            this.viewer = new Mix.Tool.Font.Viewer(this.panelPreview.Handle);
            if (this.cbFontStyle.Items.Count > 0)
            {
                this.viewer.Style = this.cbFontStyle.SelectedText;
                this.viewer.Size = Convert.ToInt32(this.nudFontSize.Value);
                this.viewer.Weight = Convert.ToInt32(this.nudFontWeight.Value);
            }

            this.vsbPreview.SmallChange = 1;
            this.vsbPreview.LargeChange = 1;
            this.vsbPreview.Minimum = 0;
            this.vsbPreview.Maximum = this.viewer.ScrollMaximum;
            this.vsbPreview.Value = this.viewer.ScrollValue;

            this.panelPreview.MouseWheel += new MouseEventHandler(panelPreview_MouseWheel);

            this.UpdateHorizRatio();
            this.UpdateVertRatio();
            this.UpdateEffects();
        }

        #endregion

        #region FileDirector Method

        private bool OnNew()
        {
            this.fontStyle = (string)cbFontStyle.Items[0];
            this.fontSize = Mix.Tool.Font.Creator.DefSize;
            this.fontWeight = Mix.Tool.Font.Creator.DefWeight;
            this.fontEffcts = Mix.Tool.Font.Effects.None;
            this.fontBorderSize = 1;
            this.fontTextList.Clear();
            this.fontFilePath = "";
            this.fontUpdateFlags = 0;

            this.cbFontStyle.SelectedIndex = 0;
            this.nudFontSize.Value = fontSize;
            this.nudFontWeight.Value = fontWeight;
            this.cbFontItalic.Checked = false;
            this.cbBordering.Checked = false;
            this.nudBordering.Value = fontBorderSize;
            this.nudBordering.Enabled = this.cbBordering.Checked;
            this.lbFontText.Items.Clear();
            this.tbFontFilePath.Text = "";
            this.lbFontLog.Items.Clear();
            this.pbFontOutput.Value = 0;
            this.btFontOutput.Enabled = false;

            return true;
        }

        private bool OnOpen(string fileName)
        {
            string tempStyle = (string)cbFontStyle.Items[0];
            int tempSize = Mix.Tool.Font.Creator.DefSize;
            int tempWeight = Mix.Tool.Font.Creator.DefWeight;
            Mix.Tool.Font.Effects tempEffects = Mix.Tool.Font.Effects.None;
            int tempBorderSize = 1;
            List<string> tempTextList = new List<string>();
            string tempOutputFileName = "";

            //////////////////////////////////////////////////////////////////////////////////////////////////////////////
            // ドキュメントを開いてテンポラリを作成
            //////////////////////////////////////////////////////////////////////////////////////////////////////////////

            try
            {
                XmlDocument doc;
                XmlAttribute attr;
                XmlElement rootNode;

                doc = new XmlDocument();
                doc.Load(fileName);

                //ルートノード
                rootNode = doc.DocumentElement;
                if (rootNode.Name == "mfp")
                {
                    attr = rootNode.Attributes["version"];
                    if (attr.Value != MFP_VERSION)
                    {
                        throw new Exception();
                    }
                }
                else
                {
                    throw new Exception();
                }

                //スタイルノード
                foreach (XmlElement node in rootNode.ChildNodes)
                {
                    string value = node.Attributes["value"].Value;

                    if (node.Name == "style")
                    {
                        tempStyle = value;
                    }
                    else if (node.Name == "size")
                    {
                        tempSize = int.Parse(value);
                    }
                    else if (node.Name == "weight")
                    {
                        tempWeight = int.Parse(value);
                    }
                    else if (node.Name == "effects")
                    {
                        tempEffects = (Mix.Tool.Font.Effects)Enum.Parse(typeof(Mix.Tool.Font.Effects), value);
                    }
                    else if (node.Name == "borderSize")
                    {
                        tempBorderSize = int.Parse(value);
                    }
                    else if (node.Name == "text")
                    {
                        tempTextList.Add(value);
                    }
                    else if (node.Name == "outputFileName")
                    {
                        tempOutputFileName = value;
                    }
                    else
                    {
                        throw new Exception();
                    }
                }
            }
            catch (Exception)
            {
                return false;
            }

            //////////////////////////////////////////////////////////////////////////////////////////////////////////////
            // テンポラリからプロジェクトを作成
            //////////////////////////////////////////////////////////////////////////////////////////////////////////////

            this.fontStyle = tempStyle;
            this.fontSize = tempSize;
            this.fontWeight = tempWeight;
            this.fontEffcts = tempEffects;
            this.fontBorderSize = tempBorderSize;

            this.fontTextList.Clear();
            foreach (string textFileName in tempTextList)
            {
                this.fontTextList.Add(textFileName);
            }

            this.fontFilePath = tempOutputFileName;

            this.fontUpdateFlags = 0;

            //////////////////////////////////////////////////////////////////////////////////////////////////////////////
            // プロジェクトからコントロールに設定
            //////////////////////////////////////////////////////////////////////////////////////////////////////////////

            this.cbFontStyle.SelectedItem = fontStyle;

            this.nudFontSize.Value = this.fontSize;
            this.nudFontWeight.Value = this.fontWeight;

            this.cbFontItalic.Checked = (this.fontEffcts & Mix.Tool.Font.Effects.Italic) == Mix.Tool.Font.Effects.Italic;
            this.cbBordering.Checked = (this.fontEffcts & Mix.Tool.Font.Effects.Bordering) == Mix.Tool.Font.Effects.Bordering;
            this.nudBordering.Value = this.fontBorderSize;
            this.nudBordering.Enabled = this.cbBordering.Checked;

            this.lbFontText.Items.Clear();
            foreach (string textFileName in fontTextList)
            {
                this.lbFontText.Items.Add(textFileName);
            }

            this.tbFontFilePath.Text = fontFilePath;

            return true;
        }

        private bool OnSave(string fileName)
        {
            ////////////////////////////////////////////////////////////////////////////////////////////////////
            // XMLドキュメントを作成して保存
            ////////////////////////////////////////////////////////////////////////////////////////////////////

            Mix.Tool.Font.Effects saveFontEffects = Mix.Tool.Font.Effects.None;

            if (this.cbFontItalic.Checked == true) { saveFontEffects |= Mix.Tool.Font.Effects.Italic; }
            if (this.cbBordering.Checked == true) { saveFontEffects |= Mix.Tool.Font.Effects.Bordering; }

            try
            {
                XmlDocument doc;
                XmlAttribute attr;
                XmlElement rootNode;
                XmlElement tempNode;

                //ドキュメントを作成
                doc = new XmlDocument();

                //ルートノード
                rootNode = doc.CreateElement("mfp");
                attr = doc.CreateAttribute("version");
                attr.Value = MFP_VERSION;
                rootNode.Attributes.Append(attr);
                doc.AppendChild(rootNode);

                //スタイルノード
                tempNode = doc.CreateElement("style");
                attr = doc.CreateAttribute("value");
                attr.Value = (string)cbFontStyle.SelectedItem;
                tempNode.Attributes.Append(attr);
                rootNode.AppendChild(tempNode);

                //サイズノード
                tempNode = doc.CreateElement("size");
                attr = doc.CreateAttribute("value");
                attr.Value = nudFontSize.Value.ToString();
                tempNode.Attributes.Append(attr);
                rootNode.AppendChild(tempNode);

                //ウェイトノード
                tempNode = doc.CreateElement("weight");
                attr = doc.CreateAttribute("value");
                attr.Value = nudFontWeight.Value.ToString();
                tempNode.Attributes.Append(attr);
                rootNode.AppendChild(tempNode);

                //エフェクトノード
                tempNode = doc.CreateElement("effects");
                attr = doc.CreateAttribute("value");
                attr.Value = saveFontEffects.ToString();
                tempNode.Attributes.Append(attr);
                rootNode.AppendChild(tempNode);

                //ボーダーサイズ
                tempNode = doc.CreateElement("borderSize");
                attr = doc.CreateAttribute("value");
                attr.Value = nudBordering.Value.ToString();
                tempNode.Attributes.Append(attr);
                rootNode.AppendChild(tempNode);

                //テキストノード
                foreach (string textFileName in lbFontText.Items)
                {
                    tempNode = doc.CreateElement("text");
                    attr = doc.CreateAttribute("value");
                    attr.Value = textFileName;
                    tempNode.Attributes.Append(attr);
                    rootNode.AppendChild(tempNode);
                }

                //出力ファイル名
                tempNode = doc.CreateElement("outputFileName");
                attr = doc.CreateAttribute("value");
                attr.Value = tbFontFilePath.Text;
                tempNode.Attributes.Append(attr);
                rootNode.AppendChild(tempNode);

                //ドキュメントを保存
                doc.Save(fileName);
            }
            catch (Exception)
            {
                return false;
            }

            ////////////////////////////////////////////////////////////////////////////////////////////////////
            // プロジェクトデータを更新
            ////////////////////////////////////////////////////////////////////////////////////////////////////

            fontStyle = cbFontStyle.SelectedItem.ToString();
            fontSize = Convert.ToInt32(nudFontSize.Value);
            fontWeight = Convert.ToInt32(nudFontWeight.Value);

            fontTextList.Clear();
            foreach (string textFileName in lbFontText.Items)
            {
                fontTextList.Add(textFileName);
            }

            fontFilePath = tbFontFilePath.Text;

            fontUpdateFlags = 0;

            fileDirector.Update = false;

            return true;
        }

        #endregion

        #region MainForm Method

        private void MainForm_SizeChanged(object sender, EventArgs e)
        {
            float plWidthF = (float)this.Size.Width * this.horizRatio;
            float pcHeightF = (float)this.Size.Height * this.vertRatio;

            this.panelLeft.Size = new System.Drawing.Size((int)plWidthF, this.panelLeft.Size.Height);
            this.panelConfigure.Size = new System.Drawing.Size(this.panelConfigure.Size.Width, (int)pcHeightF);
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (fileDirector.DoClose() == true)
            {
                if (this.viewer != null)
                {
                    this.viewer.Dispose();
                    this.viewer = null;
                }
            }
            else
            {
                e.Cancel = true;
            }
        }

        private void mainMenuItem_New_Click(object sender, EventArgs e)
        {
            fileDirector.DoNew();
        }

        private void mainMenuItem_Open_Click(object sender, EventArgs e)
        {
            fileDirector.DoOpen();
        }

        private void mainMenuItem_Save_Click(object sender, EventArgs e)
        {
            fileDirector.DoSave();
        }

        private void mainMenuItem_SaveAs_Click(object sender, EventArgs e)
        {
            fileDirector.DoSaveAs();
        }

        private void mainMenuItem_Exit_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void mainMenuItem_Version_Click(object sender, EventArgs e)
        {
            using (AboutForm aboutForm = new AboutForm())
            {
                aboutForm.StartPosition = FormStartPosition.CenterParent;
                aboutForm.ShowDialog();
            }
        }

        private void splitterH_SplitterMoved(object sender, SplitterEventArgs e)
        {
            this.UpdateHorizRatio();
        }

        private void splitterV_SplitterMoved(object sender, SplitterEventArgs e)
        {
            this.UpdateVertRatio();
        }

        private void cbFontStyle_SelectedIndexChanged(object sender, EventArgs e)
        {
            if ((this.viewer != null) &&
                (this.cbFontStyle.SelectedIndex >= 0))
            {
                this.viewer.Style = this.cbFontStyle.SelectedItem.ToString();
                this.panelPreview.Invalidate();
            }

            UpdateFontUpdateFlags(FontUpdateFlags.Style, ((string)(cbFontStyle.SelectedItem) != fontStyle));
        }

        private void nudFontSize_ValueChanged(object sender, EventArgs e)
        {
            if (this.viewer != null)
            {
                this.viewer.Size = Convert.ToInt32(this.nudFontSize.Value);
                this.panelPreview.Invalidate();
            }

            UpdateFontUpdateFlags(FontUpdateFlags.Size, (nudFontSize.Value != fontSize));
        }

        private void nudFontWeight_ValueChanged(object sender, EventArgs e)
        {
            if (this.viewer != null)
            {
                this.viewer.Weight = Convert.ToInt32(this.nudFontWeight.Value);
                this.panelPreview.Invalidate();
            }

            UpdateFontUpdateFlags(FontUpdateFlags.Weight, (nudFontWeight.Value != fontWeight));
        }

        private void cbFontItalic_CheckedChanged(object sender, EventArgs e)
        {
            UpdateEffects();
        }

        private void cbBordering_CheckedChanged(object sender, EventArgs e)
        {
            UpdateEffects();
        }

        private void nudBordering_ValueChanged(object sender, EventArgs e)
        {
            if (this.viewer != null)
            {
                NumericUpDown nud = sender as NumericUpDown;
                int oldBorderSize = this.viewer.BorderSize;

                this.viewer.BorderSize = Convert.ToInt32(nud.Value);
                this.panelPreview.Invalidate();

                UpdateFontUpdateFlags(FontUpdateFlags.BorderSize, (oldBorderSize != this.viewer.BorderSize));
            }
        }

        private void textListCtrl_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                if (lbFontText.Items.Count > 0)
                {
                    textListMenu.Items["textListMenuItem_Add"].Enabled = true;
                    textListMenu.Items["textListMenuItem_Remove"].Enabled = ( lbFontText.SelectedIndex >= 0 );
                }
                else
                {
                    textListMenu.Items["textListMenuItem_Add"].Enabled = true;
                    textListMenu.Items["textListMenuItem_Remove"].Enabled = false;
                }
            }
        }

        private void textListMenuItem_Add_Click(object sender, EventArgs e)
        {
            openTextFileDialog.ShowDialog();
        }

        private void textListMenuItem_Remove_Click(object sender, EventArgs e)
        {
            System.Collections.Generic.List<object> objList = new System.Collections.Generic.List<object>();

            foreach (object obj in lbFontText.SelectedItems)
            {
                objList.Add(obj);
            }

            foreach (object obj in objList)
            {
                lbFontText.Items.Remove(obj);
            }

            UpdateFontUpdateFlags(FontUpdateFlags.TextList, CheckTextList());
        }

        private void openTextFileDialog_FileOk(object sender, CancelEventArgs e)
        {
            if (e.Cancel == false)
            {
                foreach (string fileName in openTextFileDialog.FileNames)
                {
                    if (lbFontText.Items.Contains(fileName) == false)
                    {
                        lbFontText.Items.Add(fileName);
                    }
                }

                UpdateFontUpdateFlags(FontUpdateFlags.TextList, CheckTextList());
            }
        }

        private void outputFileNameCtrl_TextChanged(object sender, EventArgs e)
        {
            btFontOutput.Enabled = (tbFontFilePath.Text.Length > 0) ? true : false;
            UpdateFontUpdateFlags(FontUpdateFlags.OutputFileName, (tbFontFilePath.Text != fontFilePath));
        }

        private void btFontFilePath_Click(object sender, EventArgs e)
        {
            outputFileDialog.ShowDialog();
        }

        private void outputFileDialog_FileOk(object sender, CancelEventArgs e)
        {
            if (e.Cancel == false)
            {
                tbFontFilePath.Text = outputFileDialog.FileName;
            }
        }

        private void btFontOutput_Click(object sender, EventArgs e)
        {
            Mix.Tool.Font.Creator fontCreator = new Mix.Tool.Font.Creator();
            Mix.Tool.Font.Effects fontEffects = Mix.Tool.Font.Effects.None;
            Thread mainThread = new Thread(new ParameterizedThreadStart(MainForm.ThreadMain));

            ////////////////////////////////////////////////////////////////////////////////////////////////////
            // ロガーのデリゲートを設定
            ////////////////////////////////////////////////////////////////////////////////////////////////////

            Mix.Tool.Logger.ProcClear = new Mix.Tool.Logger.DelegateProcClear(Logger_Clear);
            Mix.Tool.Logger.ProcPrint = new Mix.Tool.Logger.DelegateProcPrint(Logger_Print);

            ////////////////////////////////////////////////////////////////////////////////////////////////////
            // フォントクリエータのデリゲートを設定
            ////////////////////////////////////////////////////////////////////////////////////////////////////

            fontCreator.Progress = new Mix.Tool.Font.Creator.DelegateProgress(FontCreator_Progress);
            fontCreator.ChangeState = new Mix.Tool.Font.Creator.DelegateChangeState(FontCreator_ChangeState);

            ////////////////////////////////////////////////////////////////////////////////////////////////////
            // フォントクリエータの設定
            ////////////////////////////////////////////////////////////////////////////////////////////////////

            if (this.cbFontItalic.Checked == true)
            {
                fontEffects |= Mix.Tool.Font.Effects.Italic;
            }

            if (this.cbBordering.Checked == true)
            {
                fontEffects |= Mix.Tool.Font.Effects.Bordering;
            }

            fontCreator.Style = cbFontStyle.SelectedText;
            fontCreator.Size = Convert.ToInt32(nudFontSize.Value);
            fontCreator.Weight = Convert.ToInt32(nudFontWeight.Value);
            fontCreator.Effects = fontEffects;
            fontCreator.BorderSize = Convert.ToInt32(nudBordering.Value);

            foreach (Object obj in lbFontText.Items)
            {
                fontCreator.Texts.Add(obj as String);
            }

            fontCreator.FilePath = tbFontFilePath.Text;

            ////////////////////////////////////////////////////////////////////////////////////////////////////
            // フォントの作成を開始
            ////////////////////////////////////////////////////////////////////////////////////////////////////

            SetOutputting(true);

            mainThread.Start(fontCreator);
        }

        private void panelPreview_Paint(object sender, PaintEventArgs e)
        {
            if (this.viewer != null)
            {
                this.viewer.Draw();
            }
        }

        private void panelPreview_SizeChanged(object sender, EventArgs e)
        {
            if (this.viewer != null)
            {
                this.viewer.Update();
                this.vsbPreview.Maximum = this.viewer.ScrollMaximum;
                this.vsbPreview.Value = this.viewer.ScrollValue;
                this.panelPreview.Update();
            }
        }

        private void panelPreview_MouseEnter(object sender, EventArgs e)
        {
            this.panelPreview.Focus();
        }

        private void panelPreview_MouseWheel(object sender, MouseEventArgs e)
        {
            if (e.Delta < 0)
            {
                if (this.vsbPreview.Maximum > this.vsbPreview.Value)
                {
                    this.vsbPreview.Value = this.vsbPreview.Value + 1;
                }
            }
            else if (e.Delta > 0)
            {
                if (this.vsbPreview.Minimum < this.vsbPreview.Value)
                {
                    this.vsbPreview.Value = this.vsbPreview.Value - 1;
                }
            }
        }

        private void vsbPreview_ValueChanged(object sender, EventArgs e)
        {
            if (this.viewer != null)
            {
                this.viewer.ScrollValue = this.vsbPreview.Value;
                this.panelPreview.Invalidate();
            }
        }

        private void Logger_Clear()
        {
            if (lbFontLog.InvokeRequired == true)
            {
                this.Invoke( new DelegateLogClear( Logger_Clear ) );
            }
            else
            {
                lbFontLog.Items.Clear();
            }
        }

        private void Logger_Print( Mix.Tool.Logger.Type type, String str )
        {
            if (lbFontLog.InvokeRequired == true)
            {
                this.Invoke( new DelegateLogPrint( Logger_Print ), new object[]{type, str} );
            }
            else
            {
                lbFontLog.Items.Add(str);
                lbFontLog.SelectedIndex = (lbFontLog.Items.Count - 1);
            }
        }

        private void FontCreator_Progress(int progress)
        {
            if (lbFontLog.InvokeRequired == true)
            {
                this.Invoke( new DelegateFontCreatorProgress( FontCreator_Progress ), new object[]{progress} );
            }
            else
            {
                pbFontOutput.Value = progress;
            }
        }

        private void FontCreator_ChangeState(Mix.Tool.Font.Creator.State state)
        {
            if (lbFontLog.InvokeRequired == true)
            {
                this.Invoke(new DelegateFontCreatorChangeState(FontCreator_ChangeState), new object[] { state });
            }
            else
            {
                if (state != Mix.Tool.Font.Creator.State.Start)
                {
                    SetOutputting(false);
                }
            }
        }

        private bool CheckTextList()
        {
            if (lbFontText.Items.Count != fontTextList.Count)
            {
                return true;
            }

            foreach (string fileName in lbFontText.Items)
            {
                if (fontTextList.Contains(fileName) == false)
                {
                    return true;
                }
            }

            foreach (string fileName in fontTextList)
            {
                if (lbFontText.Items.Contains(fileName) == false)
                {
                    return true;
                }
            }

            return false;
        }

        private void SetOutputting(bool enable)
        {
            if (enable == true)
            {
                cbFontStyle.Enabled = false;
                nudFontSize.Enabled = false;
                nudFontWeight.Enabled = false;
                lbFontText.Enabled = false;
                tbFontFilePath.Enabled = false;
                btFontFilePath.Enabled = false;
                btFontOutput.Enabled = false;
            }
            else
            {
                cbFontStyle.Enabled = true;
                nudFontSize.Enabled = true;
                nudFontWeight.Enabled = true;
                lbFontText.Enabled = true;
                tbFontFilePath.Enabled = true;
                btFontFilePath.Enabled = true;
                btFontOutput.Enabled = true;
            }

            IntPtr hMenu = GetSystemMenu(Handle, false);
            if (hMenu != null)
            {
                EnableMenuItem(hMenu, SC_CLOSE, (enable == false) ? MF_ENABLED : MF_GRAYED);
            }

            outputting = enable;
        }

        private void UpdateFontUpdateFlags(FontUpdateFlags flag, bool set)
        {
            if (fileDirector == null)
            {
                return;
            }

            if (set == true)
            {
                if ((fontUpdateFlags & flag) != flag)
                {
                    fontUpdateFlags |= flag;
                }
            }
            else
            {
                if ((fontUpdateFlags & flag) == flag)
                {
                    fontUpdateFlags ^= flag;
                }
            }

            fileDirector.Update = (fontUpdateFlags != 0);
        }

        private void UpdateHorizRatio()
        {
            this.horizRatio = (float)this.panelLeft.Size.Width / (float)this.Size.Width;
        }

        private void UpdateVertRatio()
        {
            this.vertRatio = (float)this.panelConfigure.Size.Height / (float)this.Size.Height;
        }

        private void UpdateEffects()
        {
            if (this.viewer != null)
            {
                Mix.Tool.Font.Effects newFontEffects = Mix.Tool.Font.Effects.None;

                if (this.cbFontItalic.Checked == true)
                {
                    newFontEffects |= Mix.Tool.Font.Effects.Italic;
                }

                if (this.cbBordering.Checked == true)
                {
                    newFontEffects |= Mix.Tool.Font.Effects.Bordering;
                    this.nudBordering.Enabled = true;
                }
                else
                {
                    this.nudBordering.Enabled = false;
                }

                this.viewer.Effects = newFontEffects;
                this.panelPreview.Invalidate();

                UpdateFontUpdateFlags(FontUpdateFlags.Effects, (newFontEffects != this.fontEffcts));
            }
        }

        private static void ThreadMain(object obj)
        {
            Mix.Tool.Font.Creator fontCreator = obj as Mix.Tool.Font.Creator;

            fontCreator.Run();
            fontCreator.Dispose();
        }

        [System.Security.Permissions.SecurityPermission(
            System.Security.Permissions.SecurityAction.LinkDemand,
            Flags = System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode)]
        protected override void WndProc(ref Message m)
        {
            const int WM_SYSCOMMAND = 0x112;
            const int SC_CLOSE = 0xF060;

            Mix.Tool.Logger.WndProc(m);

            if ((outputting == true) &&
                (m.Msg == WM_SYSCOMMAND && m.WParam.ToInt32() == SC_CLOSE))
            {
                return;
            }

            base.WndProc(ref m);
        }

        #endregion
    }
}
