/*
 * EnvConfiguration.cs
 * Copyright (c) 2007-2009 kbinani
 *
 * This file is part of LipSync.
 *
 * LipSync is free software; you can redistribute it and/or
 * modify it under the terms of the BSD License.
 *
 * LipSync is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 */
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Windows.Forms;

using Boare.Lib.AppUtil;

namespace LipSync {

    public partial class EnvConfiguration : Form, IMultiLanguageControl {
        const string _DEFAULT_LANGUAGE_STRING = "Default";
        EnvSettings m_config;

        public EnvConfiguration( EnvSettings config ) {
            InitializeComponent();
            ApplyLanguage();
            ApplyFont( AppManager.Config.Font.GetFont() );

            m_config = (EnvSettings)config.Clone();
            int selected = -1;

            string[] t_list = Messaging.GetRegisteredLanguage();
            comboLanguage.Items.Clear();
            comboLanguage.Items.Add( _DEFAULT_LANGUAGE_STRING );
            foreach ( string lang in t_list ) {
                comboLanguage.Items.Add( lang );
                if ( lang == Messaging.Language ) {
                    selected = comboLanguage.Items.Count - 1;
                }
            }
            if ( selected >= 0 ) {
                comboLanguage.SelectedIndex = selected;
            } else {
                comboLanguage.SelectedIndex = 0;
            }

            // nn
            string[] list_nn = new string[] { "b", "p", "m", "b'", "p'", "m'" };
            mListClose.Items.Clear();
            for ( int i = 0; i < list_nn.Length; i++ ) {
                string s = list_nn[i];
                mListClose.Items.Add( new ListViewItem( s ) );
                mListClose.Items[i].Checked = VowelType.IsRegisteredToNN( s );
            }

            // i
            string[] list_i = new string[] { "k'", "g'", "S", "dZ", "tS", "J", "C" };
            mListI.Items.Clear();
            for ( int i = 0; i < list_i.Length; i++ ) {
                string s = list_i[i];
                mListI.Items.Add( new ListViewItem( s ) );
                mListI.Items[i].Checked = VowelType.IsRegisteredToI( s );
            }

            // u
            string[] list_u = new string[] { @"p\", @"p\'", "w", "ts", "dz" };
            for ( int i = 0; i < list_u.Length; i++ ) {
                string s = list_u[i];
                mListU.Items.Add( new ListViewItem( s ) );
                mListU.Items[i].Checked = VowelType.IsRegisteredToU( s );
            }
            //mListClose.BackColor = tabLipSync.BackColor;
            //mListI.BackColor = tabLipSync.BackColor;
            //mListU.BackColor = tabLipSync.BackColor;

            ScreenFont = m_config.Font.GetFont();
            numWheelRatio.Value = (decimal)(1.0 / m_config.WheelRatio);

            chkGenCharacterAutomaticaly.Checked = m_config.GenerateCharacterAutomatically;
            chkHeavyOpenCharacterDialog.Checked = m_config.UseHeavyDialogInOpeningCharacterSettings;
            chkSerialVowel.Checked = m_config.CloseMouthWhenSameVowelsRepeated;

            txtFFmpeg.Text = m_config.PathFFmpeg;
            txtMEncoder.Text = m_config.PathMEncoder;

            chkSyncAtCenter.Checked = m_config.SyncAtCentre;
        }

        public void ApplyFont( Font font ) {
            this.Font = font;
            foreach ( Control c in this.Controls ) {
                Boare.Lib.AppUtil.Misc.ApplyFontRecurse( c, font );
            }
        }
        
        public void ApplyLanguage() {
            this.btnOK.Text = _( "OK" );
            this.btnCancel.Text = _( "Cancel" );
            this.groupLanguage.Text = _( "Language" );
            this.Text = _( "Option" );

            this.tabUserConfig.Text = _( "User Config" );
            this.tabAppearance.Text = _( "Appearance" );
            this.tabLipSync.Text = _( "lip-sync Option" );
            this.tabSystem.Text = _( "System" );

            this.lblTimeLineTitle.Text = _( "Title of timeline" );
            this.lblTimeLineVSQ.Text = _( "VSQ Entry" );
            this.lblTimeLinePlugin.Text = _( "Plugin Entry" );
            this.lblTimeLineDefault.Text = _( "Another Entry" );
            this.lblEntryHeight.Text = _( "Entry height (pixel)" );
            this.btnChangeTimeLineTitle.Text = _( "Change" );
            this.btnChangeTimeLineVSQ.Text = _( "Change" );
            this.btnChangeTimeLinePlugin.Text = _( "Change" );
            this.btnChangeTimeLineDefault.Text = _( "Change" );
            this.groupPhoneticSymbol.Text = _( "Check phonetic symbol to configure detailed mouth shape control" );
            this.mListClose.Header = _( "Close mouth before pronunciation" );
            this.mListI.Header = _( "\"i\" shaped mouth before pronunciation" );
            this.mListU.Header = _( "\"u\" shaped mouth before pronunciation" );
            this.groupColor.Text = _( "Color" );
            this.groupDesign.Text = _( "Design" );
            this.lblFFmpeg.Text = _( "Path of ffmpeg" );
            this.lblMEncoder.Text = _( "Path of mencoder" );
            this.lblFont.Text = _( "Font" );
            this.btnChangeFont.Text = _( "Change" );
            this.groupSerialVowel.Text = _( "Another settings" );
            this.chkSerialVowel.Text = _( "Close mouth when same vowels repeated" );
            this.groupEncoder.Text = _( "Encoder/Decoder" );
            this.chkGenCharacterAutomaticaly.Text = _( "Generate character automaticaly when importing vsq" );
            this.lblCombineThreshold.Text = _( "Threshold silence length(sec)" );
            this.groupAnotherBehavior.Text = _( "Another settings" );
            this.chkHeavyOpenCharacterDialog.Text = _( "Use preview-enabled dialog in character selection" );
            this.btnReloadLanguageConfig.Text = _( "Reload language configurations" );
            this.groupControl.Text = _( "Operation" );
            this.lblWheelRatio.Text = _( "mouse wheel rate" );
            this.chkSyncAtCenter.Text = _( "Fix cursor to center in Sync mode" );
        }

        public static string _( string s ) {
            return Messaging.GetMessage( s );
        }
        
        private Font ScreenFont {
            get {
                return m_config.Font.GetFont();
            }
            set {
                m_config.Font = new FontConfig( value );
                lblFontName.Text = m_config.Font.GetFont().FontFamily.Name + ", " + m_config.Font.GetFont().SizeInPoints + "pt, " + m_config.Font.GetFont().Style.ToString();
            }
        }        

        private void btnOK_Click( object sender, EventArgs e ) {
            m_config.CloseMouthPhoneticSymbols.Clear();
            foreach ( ListViewItem item in mListClose.Items ) {
                if ( item.Checked ) {
                    m_config.CloseMouthPhoneticSymbols.Add( item.Text );
                }
            }

            m_config.IMouthPhoneticSymbols.Clear();
            foreach ( ListViewItem item in mListI.Items ) {
                if ( item.Checked ) {
                    m_config.IMouthPhoneticSymbols.Add( item.Text );
                }
            }

            m_config.UMouthPhoneticSymbols.Clear();
            foreach ( ListViewItem item in mListU.Items ) {
                if ( item.Checked ) {
                    m_config.UMouthPhoneticSymbols.Add( item.Text );
                }
            }

            try {
                m_config.EntryCombineThreshold = float.Parse( txtCombineThreshold.Text );
            } catch {
                MessageBox.Show(
                    _( "Invalid value has been entered" ),
                    _( "Error" ),
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Exclamation );
                this.DialogResult = DialogResult.Cancel;
            }
            this.DialogResult = DialogResult.OK;
        }
        
        private void EnvConfiguration_Load( object sender, EventArgs e ) {
            ApplyColorConfig();
            numEntryHeight.Value = m_config.TrackHeight;
            txtCombineThreshold.Text = m_config.EntryCombineThreshold + "";
        }
        
        private void ApplyColorConfig() {
            lblTimelineTitleColor.BackColor = m_config.TimeLineTitleColor.Color;
            lblTimeLineVSQColor.BackColor = m_config.TimeLineVsqColor.Color;
            lblTimeLinePluginColor.BackColor = m_config.TimeLinePluginColor.Color;
            lblTimeLineDefaultColor.BackColor = m_config.TimeLineDefaultColor.Color;
            this.Invalidate();
        }

        private void btnChangeTimeLineTitle_Click( object sender, EventArgs e ) {
            colorDialog1.Reset();
            colorDialog1.Color = m_config.TimeLineTitleColor.Color;
            if ( colorDialog1.ShowDialog() == DialogResult.OK ) {
                m_config.TimeLineTitleColor = new ColorSet( colorDialog1.Color );
                ApplyColorConfig();
            }
        }

        private void btnChangeTimeLineVSQ_Click( object sender, EventArgs e ) {
            colorDialog1.Reset();
            colorDialog1.Color = m_config.TimeLineVsqColor.Color;
            if ( colorDialog1.ShowDialog() == DialogResult.OK ) {
                m_config.TimeLineVsqColor = new ColorSet( colorDialog1.Color );
                ApplyColorConfig();
            }
        }
        
        private void btnChangeTimeLinePlugin_Click( object sender, EventArgs e ) {
            colorDialog1.Reset();
            colorDialog1.Color = m_config.TimeLinePluginColor.Color;
            if ( colorDialog1.ShowDialog() == DialogResult.OK ) {
                m_config.TimeLinePluginColor = new ColorSet( colorDialog1.Color );
                ApplyColorConfig();
            }
        }
        
        private void btnChangeTimeLineDefault_Click( object sender, EventArgs e ) {
            colorDialog1.Reset();
            colorDialog1.Color = m_config.TimeLineDefaultColor.Color;
            if ( colorDialog1.ShowDialog() == DialogResult.OK ) {
                m_config.TimeLineDefaultColor = new ColorSet( colorDialog1.Color );
                ApplyColorConfig();
            }
        }

        private void btnTimeLineTitleDefault_Click( object sender, EventArgs e ) {
            m_config.TimeLineTitleColor = new ColorSet( Color.LightPink );
            ApplyColorConfig();
        }

        private void btnTimeLineVSQDefault_Click( object sender, EventArgs e ) {
            m_config.TimeLineVsqColor = new ColorSet( Color.FromArgb( 175, 222, 82 ) );
            ApplyColorConfig();
        }

        private void btnTimeLinePluginDefault_Click( object sender, EventArgs e ) {
            m_config.TimeLinePluginColor = new ColorSet( Color.FromArgb( 255, 184, 51 ) );
            ApplyColorConfig();
        }

        private void btnTimeLineDefaultDefault_Click( object sender, EventArgs e ) {
            m_config.TimeLineDefaultColor = new ColorSet( Color.LightBlue );
            ApplyColorConfig();
        }

        private void btnEntryHeightDefault_Click( object sender, EventArgs e ) {
            m_config.TrackHeight = 18;
            numEntryHeight.Value = m_config.TrackHeight;
        }

        private void numEntryHeight_ValueChanged( object sender, EventArgs e ) {
            m_config.TrackHeight = (int)numEntryHeight.Value;
        }

        private void btnFFmpeg_Click( object sender, EventArgs e ) {
            using ( OpenFileDialog dlg = new OpenFileDialog() ) {
                if ( m_config.PathFFmpeg != "" ) {
                    try {
                        dlg.InitialDirectory = Path.GetDirectoryName( m_config.PathFFmpeg );
                        dlg.FileName = m_config.PathFFmpeg;
                    } catch {
                    }
                }
                try {
                    dlg.Filter = _( "Executable file(*.exe)|*.exe" ) + "|" + _( "All Files(*.*)|*.*" );
                } catch {
                    dlg.Filter = "Executable file(*.exe)|*.exe|All Files(*.*)|*.*";
                }
                if ( dlg.ShowDialog() == DialogResult.OK ) {
                    string file = dlg.FileName;
                    if ( File.Exists( file ) ) {
                        txtFFmpeg.Text = file;
                        m_config.PathFFmpeg = file;
                    }
                }
            }
        }

        private void btnMEncoder_Click( object sender, EventArgs e ) {
            using ( OpenFileDialog dlg = new OpenFileDialog() ) {
                if ( m_config.PathMEncoder != "" ) {
                    try {
                        dlg.InitialDirectory = Path.GetDirectoryName( m_config.PathMEncoder );
                        dlg.FileName = m_config.PathMEncoder;
                    } catch {
                    }
                }
                try {
                    dlg.Filter = _( "Executable file(*.exe)|*.exe" ) + "|" + _( "All Files(*.*)|*.*" );
                } catch {
                    dlg.Filter = "Executable file(*.exe)|*.exe|All Files(*.*)|*.*";
                }
                if ( dlg.ShowDialog() == DialogResult.OK ) {
                    string file = dlg.FileName;
                    if ( File.Exists( file ) ) {
                        txtMEncoder.Text = file;
                        m_config.PathMEncoder = file;
                    }
                }
            }
        }
        
        public string PathFFmpeg {
            get {
                return txtFFmpeg.Text;
            }
            set {
                txtFFmpeg.Text = value;
            }
        }

        public string PathMEncoder {
            get {
                return txtMEncoder.Text;
            }
            set {
                txtMEncoder.Text = value;
            }
        }

        private void btnChangeFont_Click( object sender, EventArgs e ) {
            fontDialog.Font = ScreenFont;
            if ( fontDialog.ShowDialog() == DialogResult.OK ) {
                ScreenFont = fontDialog.Font;
            }
        }

        private void btnFontDefault_Click( object sender, EventArgs e ) {
            ScreenFont = new Font( "MS UI Gothic", 9 );
        }

        private void btnReloadLanguageConfig_Click( object sender, EventArgs e ) {
            Messaging.LoadMessages();
            string current_lang = m_config.Language;
            comboLanguage.Items.Clear();
            List<string> list = new List<string>( Messaging.GetRegisteredLanguage() );
            if ( !list.Contains( current_lang ) ) {
                current_lang = _DEFAULT_LANGUAGE_STRING;
            }
            list.Insert( 0, _DEFAULT_LANGUAGE_STRING );
            comboLanguage.Items.AddRange( list.ToArray() );
            for ( int i = 0; i < list.Count; i++ ) {
                if ( list[i] == current_lang ) {
                    comboLanguage.SelectedIndex = i;
                    break;
                }
            }
        }

        private void comboLanguage_SelectedIndexChanged( object sender, EventArgs e ) {
            string res = "";
            if( comboLanguage.SelectedIndex >= 0 ) {
                res = (string)comboLanguage.Items[comboLanguage.SelectedIndex];
            }
            if ( res == _DEFAULT_LANGUAGE_STRING ) {
                res = "";
            }
            m_config.Language = res;
        }

        private void numWheelRatio_ValueChanged( object sender, EventArgs e ) {
            m_config.WheelRatio = (float)(1.0 / (double)numWheelRatio.Value);
        }

        private void btnWheelRatioDefault_Click( object sender, EventArgs e ) {
            numWheelRatio.Value = 5;
        }

        public EnvSettings EnvSettings {
            get {
                return m_config;
            }
        }

        private void chkHeavyOpenCharacterDialog_CheckedChanged( object sender, EventArgs e ) {
            m_config.UseHeavyDialogInOpeningCharacterSettings = chkHeavyOpenCharacterDialog.Checked;
        }

        private void chkGenCharacterAutomaticaly_CheckedChanged( object sender, EventArgs e ) {
            m_config.GenerateCharacterAutomatically = chkGenCharacterAutomaticaly.Checked;
        }

        private void txtFFmpeg_TextChanged( object sender, EventArgs e ) {
            m_config.PathFFmpeg = txtFFmpeg.Text;
        }

        private void txtMEncoder_TextChanged( object sender, EventArgs e ) {
            m_config.PathMEncoder = txtMEncoder.Text;
        }

        private void chkSyncAtCenter_CheckedChanged( object sender, EventArgs e ) {
            m_config.SyncAtCentre = chkSyncAtCenter.Checked;
        }
    }

}
