//------------------------------------------------------------------------------
// <copyright file=”*.cs” company=”EhLib Team”>
//     Copyright (c) 2017 Dmitry V. Bolshakov   
// </copyright>
//------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;

namespace EhLib
{

//  [System.ComponentModel.DesignerCategory("Code")]
  public partial class FilterDropDownForm : DropDownForm
  {
    internal int MenuItemHeight;
    internal int LeftMargin;
    private bool internalSelection;
    internal DataGridFilterFormListRecord SelectAllRow = new DataGridFilterFormListRecord(null, null);
    internal new Size DefaultSize;

    public DataGridEh ValuesDataGrid
    {
      get
      {
        return valuesDataGrid;
      }
    }

    public FilterDropDownForm()
    {
      InitializeComponent();
      MenuItemHeight = SystemInformation.MenuBarButtonSize.Height + 2;
      LeftMargin = MenuItemHeight;

      Size cbSize = CheckBoxRenderer.GetGlyphSize(EhLibUtils.DisplayGraphicsCash, CheckBoxState.CheckedNormal);

      dataGridCheckBoxColumn1.MaxWidth = cbSize.Width + 8;
      dataGridCheckBoxColumn1.MinWidth = cbSize.Width + 8;
      dataGridCheckBoxColumn1.ReadOnly = true;

      DefaultSize = Size;
    }

    protected override void CloseNomodal(DialogResult dialogResult)
    {
      searchTextBox.Text = "";

      if (dialogResult == DialogResult.OK)
      {
        foreach (DataGridRow row in ValuesDataGrid.Rows)
        {
          if (row.Selected == true)
            ((DataGridFilterFormListRecord)row.SourceItem).RowSelected = true;
          else
            ((DataGridFilterFormListRecord)row.SourceItem).RowSelected = false;
        }
      }
      base.CloseNomodal(dialogResult);
    }

    public override void DrawFormBorder(Graphics g, Rectangle bounds)
    {
//      if (!Application.RenderWithVisualStyles)
      {
        bounds.Width -= 1;
        bounds.Height -= 1;
        using (var pen = new Pen(SystemColors.ControlDark, 1))
        {
          g.DrawRectangle(pen, bounds);
        }

        bounds.Inflate(-1, -1);
        using (var pen = new Pen(SystemColors.Menu, 1))
        {
          g.DrawRectangle(pen, bounds);
        }

        bounds.Inflate(-1, -1);
        using (var pen = new Pen(SystemColors.Menu, 1))
        {
          g.DrawRectangle(pen, bounds);
        }
      }
      //else
      //{
      //  VisualStyleElement element;
      //  VisualStyleRenderer render;

      //  element = VisualStyleElement.Menu.BarDropDown.Normal;
      //  render = new VisualStyleRenderer(element);
      //  render.DrawBackground(g, bounds);
      //}
    }

    private void BOk_Click(object sender, EventArgs e)
    {
      Close(DialogResult.OK);
    }

    private void BCancel_Click(object sender, EventArgs e)
    {
      Close(DialogResult.Cancel);
    }

    private void DataGridCheckBoxColumn1_GetCheckState(object sender, DataGridCheckBoxColumnQueryCheckStateEventArgs e)
    {
      DataGridFilterFormListRecord listRecord = (DataGridFilterFormListRecord)e.DataRow.SourceItem;
      if (listRecord.RowType == 1)
      {
        if (listRecord.SelectedCountState == 0)
          e.CheckState = CheckState.Unchecked;
        else if (listRecord.SelectedCountState == 1)
          e.CheckState = CheckState.Indeterminate;
        else
          e.CheckState = CheckState.Checked;
      }
      else
      {
        if (e.DataRow.Selected)
          e.CheckState = CheckState.Checked;
        else
          e.CheckState = CheckState.Unchecked;
      }
      e.Handled = true;
    }

    protected virtual void DataGrid1_RowIsSelectable(object sender, DataGridRowIsSelectableEventArgs e)
    {
      if ((int)RowTypeColumn.GetRowValue(e.DataRow) == 1)
      {
        e.RowIsSelectable = false;
      }
    }

    private void DataGrid1_DataCellMouseDown(object sender, DataGridDataCellMouseEventArgs e)
    {
      DataGridFilterFormListRecord listRecord = (DataGridFilterFormListRecord)e.Row.SourceItem;
      if (listRecord.RowType == 1)
      {
        if (listRecord.SelectedCountState != 0)
          ClearSelection();
        else
          SelectAll();
      }
    }

    private void SelectAll()
    {
      internalSelection = true;
      try
      {
        foreach (DataGridRow row in ValuesDataGrid.VisibleRows)
        {
          if (((DataGridFilterFormListRecord)row.SourceItem).RowType == 0)
            row.Selected = true;
        }
      }
      finally
      {
        internalSelection = false;
      }
      UpdateSelectAllRowState();
    }

    private void ClearSelection()
    {
      internalSelection = true;
      try
      {
        foreach (DataGridRow row in ValuesDataGrid.VisibleRows)
        {
          if (((DataGridFilterFormListRecord)row.SourceItem).RowType == 0)
            row.Selected = false;
        }
      }
      finally
      {
        internalSelection = false;
      }
      UpdateSelectAllRowState();
    }

    private void DataGrid1_SelectionChanged(object sender, EventArgs e)
    {
      if (!internalSelection)
        UpdateSelectAllRowState();
    }

    protected void UpdateSelectAllRowState()
    {
      bool hasRowSelected = false;
      bool hasRowNoselected = false;

      foreach (DataGridRow row in ValuesDataGrid.Rows)
      {
        if (((DataGridFilterFormListRecord)row.SourceItem).RowType == 0)
        {
          if (row.Selected)
            hasRowSelected = true;
          else
            hasRowNoselected = true;
        }
      }

      if (hasRowSelected && hasRowNoselected)
        SelectAllRow.SelectedCountState = 1;
      else if (hasRowSelected)
        SelectAllRow.SelectedCountState = 2;
      else
        SelectAllRow.SelectedCountState = 0;
    }

    private void DataGrid1_KeyDown(object sender, KeyEventArgs e)
    {
      if (e.KeyCode == Keys.Space)
      {
        DataGridRow row = ValuesDataGrid.CurrentRow;

        if (((DataGridFilterFormListRecord)row.SourceItem).RowType == 0)
          ValuesDataGrid.CurrentRow.Selected = !ValuesDataGrid.CurrentRow.Selected;
        else
        {
          if (SelectAllRow.SelectedCountState != 0)
            ClearSelection();
          else
            SelectAll();
        }
      }
    }

    private void TextBox1_TextChanged(object sender, EventArgs e)
    {
      ValuesDataGrid.SearchBox.SearchingText = searchTextBox.Text;
      ValuesDataGrid.SearchBox.ApplyFilter(searchTextBox.Text);
    }

    private void TextBox1_Enter(object sender, EventArgs e)
    {
      ValuesDataGrid.SearchBox.HighlightSearchingText = true;
    }

    private void TextBox1_Leave(object sender, EventArgs e)
    {
      ValuesDataGrid.SearchBox.HighlightSearchingText = false;
    }

    private void Button1_Click(object sender, EventArgs e)
    {
      searchTextBox.Text = "";
      valuesDataGrid.Focus();
    }

    //private void dataGrid1_SearchBox_KeyDown(object sender, KeyEventArgs e)
    //{

    //}

    private void DataGrid1_SearchBox_CheckRowHitSearch(object sender, DataGridSearchBoxCheckRowHitSearchEventArgs e)
    {
      if (((DataGridFilterFormListRecord)e.DataRow.SourceItem).RowType == 1)
      {
        e.RowIsHitSearch = true;
      }
    }
  }

  public class DataGridFilterFormListRecord
  {

    public DataGridFilterFormListRecord(object keyValue, string displayValue)
    {
      this.DisplayValue = displayValue;
      this.KeyValue = keyValue;
    }

    public string DisplayValue { get; set; }

    public object KeyValue { get; set; }

    public bool RowSelected { get; set; }

    public int RowType { get; set; } //0-Data row, 1-Command row

    public int SelectedCountState { get; set; }

    public static Collection<DataGridFilterFormListRecord> GetListFromStringList(Collection<KeyDisplayValue> filterStrings)
    {
      Collection<DataGridFilterFormListRecord> result = new Collection<DataGridFilterFormListRecord>();

      foreach (KeyDisplayValue s in filterStrings)
      {
        result.Add(new DataGridFilterFormListRecord(s.KeyValue, s.DisplayValue));
      }

      return result;
    }
  }

}
