using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using ChaKi.Common.Settings;
using System.IO;
using MessageBox = ChaKi.Common.Widgets.MessageBox;
using ChaKi.GUICommon;
using ChaKi.Service.Lexicons;
using ChaKi.Entity.Corpora;
using ChaKi.Service.Database;
using ChaKi.Common.Wdigets;
using ChaKi.Common;

namespace DependencyEditSLA
{
    public partial class DictionarySettingDialog : Form
    {
        public List<Corpus> Corpora { get; set; }
        private DataTable m_Table;
        private const int C_READONLY = 2;
        private const int C_USERDIC = 3;


        public DictionarySettingDialog()
        {
            this.Corpora = new List<Corpus>();

            InitializeComponent();
        }

        private void DictionarySettingDialog_Load(object sender, EventArgs e)
        {
            DictionarySettings settings = DictionarySettings.Instance;

            m_Table = new DataTable();
            DataColumn col;
            col = new DataColumn("Name", typeof(string));
            m_Table.Columns.Add(col);
            col = new DataColumn("Path", typeof(string)) { ReadOnly = true };
            m_Table.Columns.Add(col);
            col = new DataColumn("ReadOnly", typeof(bool)) { ReadOnly = true };
            m_Table.Columns.Add(col);
            col = new DataColumn("UserDic", typeof(bool));
            m_Table.Columns.Add(col);

            foreach (DictionarySettingItem item in settings)
            {
                DataRow row = m_Table.NewRow();
                row[0] = item.Name;
                row[1] = item.Path;
                row[2] = item.ReadOnly;
                row[3] = item.IsUserDic;
                m_Table.Rows.Add(row);
            }

            this.dataGridView1.DataSource = m_Table;
            this.dataGridView1.Columns[0].Width = 100;
            this.dataGridView1.Columns[1].Width = 200;
            this.dataGridView1.Columns[2].Width = 70;
            this.dataGridView1.Columns[3].Width = 70;
        }

        private void Accept()
        {
            DictionarySettings settings = DictionarySettings.Instance;
            settings.Clear();

            m_Table.AcceptChanges();
            foreach (DataRow row in m_Table.Rows)
            {
                DictionarySettingItem item = new DictionarySettingItem();
                item.Name = (string)row[0];
                item.Path = (string)row[1];
                item.ReadOnly = (bool)row[2];
                item.IsUserDic = (bool)row[3];
                settings.Add(item);
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Title = "Select Dictionary DB to add";
            dlg.CheckFileExists = true;
            dlg.DefaultExt = ".db";

            if (dlg.ShowDialog() == DialogResult.OK)
            {
                DataRow row = m_Table.NewRow();
                row[0] = Path.GetFileNameWithoutExtension(dlg.FileName);
                row[1] = dlg.FileName;
                row[2] = true;
                row[3] = false;
                m_Table.Rows.Add(row);
            }
        }

        private void button4_Click(object sender, EventArgs e)
        {
            while (this.dataGridView1.SelectedRows.Count > 0)
            {
                this.dataGridView1.Rows.Remove(this.dataGridView1.SelectedRows[0]);
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Accept();
        }

        /// <summary>
        /// ユーザー辞書更新コマンド
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button5_Click(object sender, EventArgs e)
        {
            var refdics = new List<string>();
            var userdic = string.Empty;

            try
            {
                m_Table.AcceptChanges();
                foreach (DataRow row in m_Table.Rows)
                {
                    refdics.Add((string)row[1]);
                    if ((bool)row[3])
                    {
                        if (userdic.Length == 0)
                        {
                            userdic = (string)row[1];
                        }
                        else
                        {
                            MessageBox.Show("Only one userdic is allowed.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                            return;
                        }
                    }
                }
                if (this.Corpora.Count == 0)
                {
                    MessageBox.Show("No Corpus selected.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }
                if (userdic.Length == 0)
                {
                    MessageBox.Show("No User Dictionary found.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }

                ILexemeEditService service = new LexemeEditService();
                List<LexemeCorpusBoolTuple> list = null;
                var progress = new ProgressDialog();
                progress.Work = (s, ev) =>
                { 
                    list = service.ListLexemesNotInRefDic(this.Corpora, refdics, progress);
                };
                progress.ShowDialog();
                if (progress.Canceled || list == null)
                {
                    return;
                }
                if (list.Count > 0)
                {
                    var checkdlg = new LexemeListCheckDialog();
                    checkdlg.Model = list;
                    // 参照用辞書を含め、全ての使用可能なPOS, CType, CFormタグのリストを得て、PropTreeにセットする.
                    Dictionary<string, IList<PartOfSpeech>> pos;  // stringはDictionary名（カレントコーパスは"Default"）
                    Dictionary<string, IList<CType>> ctypes;
                    Dictionary<string, IList<CForm>> cforms;
                    service.GetLexiconTags(out pos, out ctypes, out cforms);
                    checkdlg.SetLexiconTags(pos, ctypes, cforms);
                    if (checkdlg.ShowDialog() == DialogResult.OK)
                    {
                        var oldCur = this.Cursor;
                        try
                        {
                            this.Cursor = Cursors.WaitCursor;
                            service.UpdateCorpusInternalDictionaries(list);
                            service.AddToUserDictionary(list, userdic);
                        }
                        finally
                        {
                            this.Cursor = oldCur;
                        }
                        MessageBox.Show("UserDic Successfully Updated.");
                    }
                }
                else
                {
                    MessageBox.Show("Nothing to add to UserDic.");
                }
            }
            catch (Exception ex)
            {
                ErrorReportDialog edlg = new ErrorReportDialog("Error while executing userdic update:", ex);
                edlg.ShowDialog();
            }
        }

        // Col 3 を単一チェック動作にする
        // Col 3がチェックされたらCol 2 (ReadOnly)のチェックをはずす.
        private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            dataGridView1.EndEdit(); // CheckBoxの状態を確定させる.

            if (e.ColumnIndex == C_USERDIC)
            {
                m_Table.AcceptChanges();
                MakeUserDicRow(e.RowIndex);
            }
        }

        private void MakeUserDicRow(int row)
        {
            for (int r = 0; r < m_Table.Rows.Count; r++)
            {
                m_Table.Rows[r][C_USERDIC] = (r == row);
            }

            m_Table.Columns[C_READONLY].ReadOnly = false;
            for (int r = 0; r < m_Table.Rows.Count; r++)
            {
                var rdata = m_Table.Rows[r];
                rdata[C_READONLY] = !(bool)rdata[C_USERDIC];
            }
            m_Table.Columns[C_READONLY].ReadOnly = true;
        }

        // ユーザー辞書新規追加コマンド
        private void button6_Click(object sender, EventArgs e)
        {
            try
            {
                OpenFileDialog dlg = new OpenFileDialog();
                dlg.Title = "Enter Dictionary DB to add";
                dlg.CheckFileExists = false;
                dlg.DefaultExt = ".ddb";

                if (dlg.ShowDialog() == DialogResult.OK)
                {
                    var filename = dlg.FileName;
                    var dict = Dictionary.CreateFromFile(filename);
                    var svc = DBService.Create(dict.DBParam);
                    if (svc.DatabaseExists())
                    {
                        MessageBox.Show("Database already exists.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }
                    svc.CreateDatabase();
                    svc.CreateDictionaryTables();
                    svc.CreateDictionaryIndices();

                    // Tableに追加
                    DataRow row = m_Table.NewRow();
                    row[0] = Path.GetFileNameWithoutExtension(filename);
                    row[1] = dlg.FileName;
                    row[2] = true;
                    row[3] = false;
                    m_Table.Rows.Add(row);
                    m_Table.AcceptChanges();
                    MakeUserDicRow(m_Table.Rows.Count - 1);
                }

            }
            catch (Exception ex)
            {
                ErrorReportDialog edlg = new ErrorReportDialog("Error while executing userdic creation:", ex);
                edlg.ShowDialog();
            }
        }
    }
}