using System;
using System.Windows.Forms;
using ChaKi.Entity.Corpora;
using ChaKi.Entity.Kwic;
using ChaKi.GUICommon;
using ChaKi.Entity.Search;
using ChaKi.Common;
using ChaKi.Common.Settings;

namespace ChaKi.Views.KwicView
{
    public partial class KwicView : UserControl, IChaKiView
    {
        public static KwicViewSettings Settings;

        public bool TwoLineMode
        {
            get
            {
                return this.kwicViewPanel1.TwoLineMode;
            }
            set
            {
                this.kwicViewPanel1.TwoLineMode = value;
                this.kwicViewPanel1.CalculateLineHeight();
                this.kwicViewPanel1.UpdateKwicList();
            }
        }

        /// <summary>
        /// StringSearch結果(Lexeme tag情報がないKwicItem) を含む
        /// </summary>
        public bool HasSimpleItem
        {
            get
            {
                return this.kwicViewPanel1.HasSimpleItem;
            }
        }

        public bool KwicMode
        {
            get
            {
                return this.kwicViewPanel1.KwicMode;
            }
            set
            {
                this.kwicViewPanel1.SuspendUpdateView = true;
                this.kwicViewPanel1.KwicMode = value;
                this.kwicViewPanel1.WordWrap = !value;
                // Columnヘッダをモードに合わせて変更
                string[] newTexts;
                int[] newWidths = new int[Columns.NColumns];
                if (value) {
                    newTexts = Columns.DefaultHeaderTextKwic;
                    if (Settings.DefaultHeaderWidthKwic == null || Settings.DefaultHeaderWidthKwic.Length < Columns.NColumns)
                    {
                        Settings.DefaultHeaderWidthKwic = new int[Columns.NColumns];
                    }
                    Settings.DefaultHeaderWidthKwic.CopyTo(newWidths, 0);
                } else {
                    newTexts = Columns.DefaultHeaderTextNonKwic;
                    if (Settings.DefaultHeaderWidthKwic == null || Settings.DefaultHeaderWidthKwic.Length < Columns.NColumns)
                    {
                        Settings.DefaultHeaderWidthNonKwic = new int[Columns.NColumns];
                    }
                    Settings.DefaultHeaderWidthNonKwic.CopyTo(newWidths, 0);
                }
                for (int i = 0; i < Columns.NColumns; i++)
                {
                    this.dataGridView1.Columns[i].HeaderText = newTexts[i];
                    this.dataGridView1.Columns[i].Width = newWidths[i];
                    m_Columns.Widths[i] = this.dataGridView1.Columns[i].Width;
                    Invalidate(true);
                }
                this.kwicViewPanel1.SuspendUpdateView = false;
            }
        }

        private Columns m_Columns;

        #region KwicView Events
        /// <summary>
        /// Current行が変化したときの親(MainForm)への通知
        /// （子Panelからの中継）
        /// </summary>
        public event CurrentChangedDelegate CurrentChanged;
        /// <summary>
        /// Context表示指示時の親(MainForm)への通知 
        /// （子Panelからの中継）
        /// </summary>
        public event RequestContextDelegate ContextRequested;
        /// <summary>
        /// DepEdit開始指示時の親(MainForm)への通知 
        /// （子Panelからの中継）
        /// </summary>
        public event RequestDepEditDelegate DepEditRequested;
        /// <summary>
        /// Guide Panelの表示更新通知 
        /// （子Panelからの中継）
        /// </summary>
        public event UpdateGuidePanelDelegate UpdateGuidePanel;
        #endregion

        public KwicView()
        {
            InitializeComponent();

            m_Columns = new Columns();

            // Event Handlerの割り当て
            this.kwicViewPanel1.OnContextRequested += new RequestContextDelegate(kwicViewPanel1_OnContextRequested);
            this.kwicViewPanel1.OnCurrentChanged += new CurrentChangedDelegate(kwicViewPanel1_OnCurrentChanged);
            this.kwicViewPanel1.OnDepEditRequested += new RequestDepEditDelegate(kwicViewPanel1_OnRequestDepEdit);
            this.kwicViewPanel1.OnUpdateGuidePanel += new UpdateGuidePanelDelegate(kwicViewPanel1_OnUpdateGuidePanel);
        }

        public void SetModel(object model)
        {
            if (model != null && !(model is SearchHistory))
            {
                throw new ArgumentException("Assigning invalid model to KwicPanel");
            }
            this.kwicViewPanel1.SetModel((SearchHistory)model);
        }

        public SearchHistory GetModel()
        {
            return this.kwicViewPanel1.GetModel();
        }

        /// <summary>
        /// 与えられたsenidを持つKwicItemが存在する場合、
        /// そのKwicItemの前後offsetの位置にあるKwicItemを返す.
        /// なければnullを返す.
        /// </summary>
        /// <param name="senid"></param>
        /// <param name="offset"></param>
        /// <returns></returns>
        public KwicItem ShiftCurrent(int offset)
        {
            if (!this.kwicViewPanel1.ShiftSelection(offset))
            {
                return null;
            }
            return this.kwicViewPanel1.GetSelection();
        }

        //TODO: MainForm.LoadAnnotations()を改良したら削除するべきメソッド
        public void UpdateSegments()
        {
            this.kwicViewPanel1.UpdateAnnotations();
        }

        public void SetVisible(bool f)
        {
            this.Visible = f;
        }

        public void RecalcLayout()
        {
            this.kwicViewPanel1.RecalcLayout();
        }

        public int GetCurrentCenterWordID()
        {
            return 0;
        }

        public void DeleteAll()
        {
            this.kwicViewPanel1.DeleteAll();
        }

        public void CheckAll()
        {
            this.kwicViewPanel1.CheckAll();
        }

        public void CheckSelected()
        {
            this.kwicViewPanel1.CheckSelected();
        }

        public void UncheckAll()
        {
            this.kwicViewPanel1.UncheckAll();
        }

        public void SelectAll()
        {
            this.kwicViewPanel1.SelectAll();
        }

        public void UnselectAll()
        {
            this.kwicViewPanel1.UnselectAll();
        }

        public void SelectChecked()
        {
            this.kwicViewPanel1.SelectChecked();
        }

        public void AutoAdjustColumnWidths()
        {
            m_Columns.AutoAdjust(this.kwicViewPanel1.EffectiveWidth, this.KwicMode);
            if (this.KwicMode)
            {
                this.dataGridView1.Columns[6].Width = Settings.DefaultHeaderWidthKwic[6];
                this.dataGridView1.Columns[8].Width = Settings.DefaultHeaderWidthKwic[8];
            }
            else
            {
                this.dataGridView1.Columns[8].Width = Settings.DefaultHeaderWidthNonKwic[8];
            }
            Invalidate(true);
        }

        public void LeftAdjustColumnWidths()
        {
        }

        public void ShiftPivot(int shift)
        {
            this.kwicViewPanel1.ResetUpdateStatus();
            this.kwicViewPanel1.UpdateKwicList();
        }

        public void CutToClipboard()
        {
            // intentionally left blank
        }

        public void CopyToClipboard()
        {
            //TODO
        }

        public void PasteFromClipboard()
        {
            // intentionally left blank
        }

        public bool CanCut { get { return false; } }    // always false

        public bool CanCopy
        {
            get
            {
                return true;    //TODO
            }
        }

        public bool CanPaste { get { return false; } }    // always false

        /// <summary>
        /// 現在のカーソル位置以降に現れるkeyと一致する表層を検索して選択状態にする.
        /// </summary>
        /// <param name="key"></param>
        public void FindNext(string key)
        {
            this.kwicViewPanel1.FindNext(key);
        }

        public void UpdateKwicList()
        {
            this.kwicViewPanel1.ResetUpdateStatus();
            this.kwicViewPanel1.UpdateKwicList();
        }

        /// <summary>
        /// 単一の選択行の取得・設定を行う.
        /// 複数行が選択されている場合・選択がない場合は-1である.
        /// </summary>
        public int SelectedLine
        {
            get
            {
                return this.kwicViewPanel1.SingleSelection;
            }
            set
            {
                this.kwicViewPanel1.SingleSelection = value;
            }
        }

        /// <summary>
        /// 単一の行を選択状態にし、その行が表示されるように自動的にスクロールする.
        /// </summary>
        /// <param name="index"></param>
        /// <returns>実際に選択できた行番号(0-base), -1 if cannot select.</returns>
        public int SetCurSel(int index)
        {
            return this.kwicViewPanel1.SetCurSel(index);
        }

        /// <summary>
        /// 現在のRecordから該当するsenidを持つ行を選択状態にし、その行が表示されるように自動的にスクロールする.
        /// </summary>
        /// <param name="docid"></param>
        /// <param name="senid"></param>
        /// <returns>該当行がなければfalse</returns>
        public bool SetCurSelBySentenceID(int senid)
        {
            return this.kwicViewPanel1.SetCurSelBySentenceID(senid);
        }

        private void dataGridView1_ColumnWidthChanged(object sender, DataGridViewColumnEventArgs e)
        {
            if (m_Columns == null)
            {
                return;
            }
            for (int i = 0; i < Columns.NColumns; i++)
            {
                m_Columns.Widths[i] = this.dataGridView1.Columns[i].Width;
                if (this.KwicMode)
                {
                    KwicView.Settings.DefaultHeaderWidthKwic[i] = m_Columns.Widths[i];
                }
                else
                {
                    KwicView.Settings.DefaultHeaderWidthNonKwic[i] = m_Columns.Widths[i];
                }
            }
            this.kwicViewPanel1.OnWidthChanged(m_Columns);
        }

        void kwicViewPanel1_OnUpdateGuidePanel(Corpus corpus, Lexeme lex)
        {
            if (this.UpdateGuidePanel != null)
            {
                UpdateGuidePanel(corpus, lex);
            }
        }

        void kwicViewPanel1_OnContextRequested(KwicList list, int row)
        {
            if (this.ContextRequested != null)
            {
                ContextRequested(list, row);
            }
        }

        void kwicViewPanel1_OnCurrentChanged(Corpus cps, int senid)
        {
            if (this.CurrentChanged != null)
            {
                CurrentChanged(cps, senid);
            }
        }

        void kwicViewPanel1_OnRequestDepEdit(KwicItem ki)
        {
            if (this.DepEditRequested != null)
            {
                DepEditRequested(ki);
            }
        }

        private void dataGridView1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            int colno = e.ColumnIndex;
            SortOrder order = this.dataGridView1.Columns[colno].HeaderCell.SortGlyphDirection;
            this.kwicViewPanel1.Sort(colno, order);
        }
    }
}
