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

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

namespace EhLib
{

  public class ToolStripItemReturnData
  {
    public ToolStripItem ToolStripItem;
    public ContextMenuStrip ContextMenuStrip;

    public ToolStripItemReturnData(ToolStripItem ToolStripItem, ContextMenuStrip ContextMenuStrip)
    {
      this.ToolStripItem = ToolStripItem;
      this.ContextMenuStrip = ContextMenuStrip;
    }
  }
  
  [ToolboxItem(false)]
  [System.ComponentModel.DesignerCategory("Code")]
  public class ToolStripDropDownMenuEh : ToolStripDropDownMenu
  {
    protected override void OnItemClicked(ToolStripItemClickedEventArgs e)
    {
      ToolStripMenuItemEh tsmi = e.ClickedItem as ToolStripMenuItemEh;
      if (tsmi == null || tsmi.CloseMenuOnClick == true)
      {
        base.OnItemClicked(e);
      }
    }
  }

  public class DataGridManager : object, IDisposable
  {

    #region static fields
    private static DataGridManager _defaultManager;
    #endregion static fields

    #region privates
    ContextMenuStrip indicatorTitlePopupMenu;
    ContextMenuStrip gridContextMenu;

    ToolStripMenuItem indicatorTitleVisibleColumnsMenuItem;
    ToolStripMenuItem indicatorTitleCustomizeColumnsMenuItem;
    ToolStripMenuItem indicatorTitleCutMenuItem;
    ToolStripMenuItem indicatorTitleCopyMenuItem;
    ToolStripMenuItem indicatorTitlePasteMenuItem;
    ToolStripMenuItem indicatorTitleDeleteMenuItem;
    ToolStripMenuItem indicatorTitleAllMenuItem;

    ToolStripSeparator menuBeforeAllSeparator;
    ToolStripSeparator menuSeparator;
    ToolStripSeparator menuSortItemsSeparator;
    ToolStripMenuItem indicatorTitlePrintMenuItem;
    ToolStripMenuItem indicatorTitlePrintSetupMenuItem;

    ToolStripMenuItem clearColumnFilterMenuItem;
    ToolStripMenuItem сolumnFilterEqualMenuItem;
    ToolStripMenuItem сolumnFilterNotEqualMenuItem;
    ToolStripMenuItem sortAscendingMenuItem;
    ToolStripMenuItem sortDescendingMenuItem;
    //ToolStripMenuItem сolumnFilterContainsMenuItem;
    //ToolStripMenuItem сolumnFilterNotContainsMenuItem;

    ContextMenuStrip searchBoxToolPopupMenu;

    ToolStripMenuItemEh searchBoxOptionsScopeMenuItem;
    ToolStripMenuItemEh searchBoxScopeCurrentColumnMenuItem;
    ToolStripMenuItemEh searchBoxScopeAllTheGridMenuItem;
    ToolStripMenuItemEh searchBoxCaseSensitiveMenuItem;
    ToolStripMenuItemEh searchBoxWholeWordsMenuItem;
    ToolStripMenuItemEh searchBoxBeginsWithMenuItem;

    //bool closeMenuOnClick;
    private bool disposed;
    private DataGridPrintService printService;
    #endregion

    #region constructor
    public DataGridManager()
    {
      TitleStartColumnMovingAnimationTime = 120;
      TitleFinishColumnMovingAnimationTime = 150;
    }

    ~DataGridManager()
    {
      Dispose(false);
    }

    public void Dispose()
    {
      Dispose(true);
      GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
      if (disposed)
        return;
      if (disposing)
      {
        if (indicatorTitlePopupMenu != null) indicatorTitlePopupMenu.Dispose();
        if (indicatorTitleVisibleColumnsMenuItem != null) indicatorTitleVisibleColumnsMenuItem.Dispose();
        if (indicatorTitleCutMenuItem != null) indicatorTitleCutMenuItem.Dispose();
        if (indicatorTitleCopyMenuItem != null) indicatorTitleCopyMenuItem.Dispose();
        if (indicatorTitlePasteMenuItem != null) indicatorTitlePasteMenuItem.Dispose();
        if (indicatorTitleDeleteMenuItem != null) indicatorTitleDeleteMenuItem.Dispose();
        if (indicatorTitleAllMenuItem != null) indicatorTitleAllMenuItem.Dispose();

        if (searchBoxToolPopupMenu != null) searchBoxToolPopupMenu.Dispose();

        if (searchBoxOptionsScopeMenuItem != null) searchBoxOptionsScopeMenuItem.Dispose();
        if (searchBoxScopeCurrentColumnMenuItem != null) searchBoxScopeCurrentColumnMenuItem.Dispose();
        if (searchBoxScopeAllTheGridMenuItem != null) searchBoxScopeAllTheGridMenuItem.Dispose();
        if (searchBoxCaseSensitiveMenuItem != null) searchBoxCaseSensitiveMenuItem.Dispose();
        if (searchBoxWholeWordsMenuItem != null) searchBoxWholeWordsMenuItem.Dispose();
        if (searchBoxBeginsWithMenuItem != null) searchBoxBeginsWithMenuItem.Dispose();
        if (menuSeparator != null) menuSeparator.Dispose();
        if (indicatorTitlePrintMenuItem != null) indicatorTitlePrintMenuItem.Dispose();

        if (clearColumnFilterMenuItem != null) clearColumnFilterMenuItem.Dispose();
      }
      disposed = true;
    }
    #endregion

    #region static properties
    public static DataGridManager DefaultManager
    {
      get
      {
        if (_defaultManager == null)
          _defaultManager = new DataGridManager();
        return _defaultManager;
      }
      set
      {
        _defaultManager = value;
      }
    }
    #endregion

    #region static properties
    public int TitleStartColumnMovingAnimationTime { get; set; }
    public int TitleFinishColumnMovingAnimationTime { get; set; }
    public ContextMenuStrip GridContextMenu
    {
      get
      {
        if (gridContextMenu == null)
        {
          gridContextMenu = new DataGridContextMenuStrip();
        }
        return gridContextMenu;
      }

      set
      {
        gridContextMenu = value;
      }
    }
    public DataGridPrintService PrintService
    {
      get
      {
        if (printService == null)
          printService = CreateDefaultPrintService();
        return printService;
      }
      set
      {
        printService = value;
      }
    }
    #endregion

    public virtual PropertyAxisBar GetDataGridColumnForType(Type type)
    {
      Type colType = GetDataGridColumnTypeForDataType(type);
      if (colType != null)
        return (PropertyAxisBar)Activator.CreateInstance(colType);
      else
        return null;
    }

    public virtual Type GetDataGridColumnTypeForDataType(Type type)
    {
      Type colType;

      TypeConverter imageTypeConverter = TypeDescriptor.GetConverter(typeof(Image));
      if (type == typeof(bool) || type == typeof(CheckState))
      {
        //column = new DataGridViewCheckBoxColumn(type.Equals(typeof(CheckState)));
        colType = typeof(DataGridCheckBoxColumn);
      }
      else if (typeof(System.Drawing.Image).IsAssignableFrom(type) || imageTypeConverter.CanConvertFrom(type))
      {
        colType = typeof(DataGridImageColumn);
      }
      else if (typeof(IList).IsAssignableFrom(type))
      {
        colType = null;
      }
      else if (typeof(DateTime).IsAssignableFrom(type))
      {
        colType = typeof(DataGridDateTimeColumn);
      }
      else
      {
        colType = typeof(DataGridTextColumn);
      }
      return colType;
    }

    #region IndicatorTitle
    public virtual void BuildIndicatorTitleMenu(DataGridEh grid, ref ToolStripDropDown popupMenu)
    {

      ToolStripItem mi;
      ToolStripMenuItem cmi;
      bool isAddMenuItem;

      if (popupMenu == null)
      {
        if (indicatorTitlePopupMenu == null)
        {
          indicatorTitlePopupMenu = new DataGridContextMenuStrip();
        }

        indicatorTitlePopupMenu.Items.Clear();

        popupMenu = indicatorTitlePopupMenu;
      }
      else if (popupMenu.Items.Count > 0)
      {

        mi = new ToolStripSeparator();
        popupMenu.Items.Add(mi);
      }

      //closeMenuOnClick = true;

      if (grid.IndicatorTitle.UseGlobalMenu)
      {
        //Columns visibility
        //BuildVisibleColumnsMenuItem(grid, popupMenu);
        BuildCustomizeColumnsMenuItem(grid, popupMenu);

        //Cut
        {
          if (indicatorTitleCutMenuItem == null)
          {
            indicatorTitleCutMenuItem = new ToolStripMenuItem();
            indicatorTitleCutMenuItem.Click += MenuItemCutClick;
          }
          cmi = indicatorTitleCutMenuItem;
          if (cmi.Owner != null)
            cmi.Owner.Items.Remove(cmi);
          cmi.Text = Properties.Resources.DataGridMenu_Cut;
          cmi.Enabled = grid.EditActions.CanCut();
          //DBGridEhCutIndicatorMenuItem.Enabled = grid.CheckCutAction && (geaCutEh in grid.EditActions);
          //DBGridEhCutIndicatorMenuItem.TitleMenu = itmCut;
          //DBGridEhCutIndicatorMenuItem.ShortCut = ShortCut(Word("X"), [ssCtrl]);
          cmi.Tag = grid;
          popupMenu.Items.Add(cmi);
        }

        //Copy
        {
          if (indicatorTitleCopyMenuItem == null)
          {
            indicatorTitleCopyMenuItem = new ToolStripMenuItem();
            indicatorTitleCopyMenuItem.Click += IndicatorTitleMenuCopyClick;
          }
          cmi = indicatorTitleCopyMenuItem;
          if (cmi.Owner != null)
            cmi.Owner.Items.Remove(cmi);
          cmi.Text = Properties.Resources.DataGridMenu_Copy;
          cmi.Enabled = grid.EditActions.CanCopy();
          //DBGridEhCopyIndicatorMenuItem.Enabled = grid.CheckCopyAction && (geaCopyEh in grid.EditActions);
          //DBGridEhCopyIndicatorMenuItem.TitleMenu = itmCopy;
          //DBGridEhCopyIndicatorMenuItem.ShortCopy = ShortCopy(Word("X"), [ssCtrl]);
          cmi.Tag = grid;
          popupMenu.Items.Add(cmi);
        }

        //Paste
        {
          if (indicatorTitlePasteMenuItem == null)
          {
            indicatorTitlePasteMenuItem = new ToolStripMenuItem();
            indicatorTitlePasteMenuItem.Click += IndicatorTitleMenuPasteClick;
          }
          cmi = indicatorTitlePasteMenuItem;
          if (cmi.Owner != null)
            cmi.Owner.Items.Remove(cmi);
          cmi.Text = Properties.Resources.DataGridMenu_Paste;
          cmi.Enabled = grid.EditActions.CanPaste();
          //DBGridEhPasteIndicatorMenuItem.Enabled = grid.CheckPasteAction && (geaPasteEh in grid.EditActions);
          //DBGridEhPasteIndicatorMenuItem.TitleMenu = itmPaste;
          //DBGridEhPasteIndicatorMenuItem.ShortPaste = ShortPaste(Word("X"), [ssCtrl]);
          cmi.Tag = grid;
          popupMenu.Items.Add(cmi);
        }

        //Delete
        {
          if (indicatorTitleDeleteMenuItem == null)
          {
            indicatorTitleDeleteMenuItem = new ToolStripMenuItem();
            indicatorTitleDeleteMenuItem.Click += IndicatorTitleMenuDeleteClick;
          }
          cmi = indicatorTitleDeleteMenuItem;
          if (cmi.Owner != null)
            cmi.Owner.Items.Remove(cmi);
          cmi.Text = Properties.Resources.DataGridMenu_Delete;
          cmi.Enabled = grid.EditActions.CanDelete();
          //DBGridEhDeleteIndicatorMenuItem.Enabled = grid.CheckDeleteAction && (geaDeleteEh in grid.EditActions);
          //DBGridEhDeleteIndicatorMenuItem.TitleMenu = itmDelete;
          //DBGridEhDeleteIndicatorMenuItem.ShortDelete = ShortDelete(Word("X"), [ssCtrl]);
          cmi.Tag = grid;
          popupMenu.Items.Add(cmi);
        }

        //Select All
        {
          if (indicatorTitleAllMenuItem == null)
          {
            indicatorTitleAllMenuItem = new ToolStripMenuItem();
            indicatorTitleAllMenuItem.Click += IndicatorTitleMenuSelectAllClick;
          }
          cmi = indicatorTitleAllMenuItem;
          if (cmi.Owner != null)
            cmi.Owner.Items.Remove(cmi);
          cmi.Text = Properties.Resources.DataGridMenu_SelectAll;
          cmi.Enabled = grid.EditActions.CanSelectAll();
          //DBGridEhSelectAllIndicatorMenuItem.Enabled = grid.CheckSelectAllAction && (geaSelectAllEh in grid.EditActions);
          //DBGridEhSelectAllIndicatorMenuItem.TitleMenu = itmSelectAll;
          //DBGridEhSelectAllIndicatorMenuItem.ShortSelectAll = ShortSelectAll(Word("X"), [ssCtrl]);
          cmi.Tag = grid;
          popupMenu.Items.Add(cmi);
        }

        //Separator
        {
          if (menuSeparator == null)
          {
            menuSeparator = new ToolStripSeparator();
          }
          if (menuSeparator.Owner != null)
            menuSeparator.Owner.Items.Remove(menuSeparator);
          popupMenu.Items.Add(menuSeparator);
        }

        //Print
        {
          if (indicatorTitlePrintMenuItem == null)
          {
            indicatorTitlePrintMenuItem = new ToolStripMenuItem();
            indicatorTitlePrintMenuItem.Click += IndicatorTitleMenuPrintClick;
          }
          cmi = indicatorTitlePrintMenuItem;
          if (cmi.Owner != null)
            cmi.Owner.Items.Remove(cmi);

          InitPrintIndicatorTitleMenuItem(grid, popupMenu, cmi, out isAddMenuItem);

          if (isAddMenuItem)
            popupMenu.Items.Add(cmi);
        }

        //Print Setup
        {
          if (indicatorTitlePrintSetupMenuItem == null)
          {
            indicatorTitlePrintSetupMenuItem = new ToolStripMenuItem();
            indicatorTitlePrintSetupMenuItem.Click += IndicatorTitleMenuPrintSetupClick;
          }
          cmi = indicatorTitlePrintSetupMenuItem;
          if (cmi.Owner != null)
            cmi.Owner.Items.Remove(cmi);

          InitPrintSetupIndicatorTitleMenuItem(grid, popupMenu, cmi, out isAddMenuItem);
          if (isAddMenuItem)
            popupMenu.Items.Add(cmi);
        }

      }
    }

    protected virtual void BuildVisibleColumnsMenuItem(DataGridEh grid, ToolStripDropDown popupMenu)
    {
      if (indicatorTitleVisibleColumnsMenuItem == null)
      {
        indicatorTitleVisibleColumnsMenuItem = new ToolStripMenuItemEh();
        //indicatorTitleVisibleColumnsMenuItem.DropDown.Closing += ContextMenuClosing;
        //indicatorTitleVisibleColumnsMenuItem.DropDownItemClicked += ContextMenuItemClicked;
      }
      if (indicatorTitleVisibleColumnsMenuItem.Owner != null)
        indicatorTitleVisibleColumnsMenuItem.Owner.Items.Remove(indicatorTitleVisibleColumnsMenuItem);
      indicatorTitleVisibleColumnsMenuItem.DropDownItems.Clear();
      indicatorTitleVisibleColumnsMenuItem.Text = Properties.Resources.DataGridMenu_VisibleColumns;
      popupMenu.Items.Add(indicatorTitleVisibleColumnsMenuItem);


      if (grid.Title.MultiTitle.Active)
        AddVisibleMultiTitlesMenu(grid, grid.Title.MultiTitle.Root, indicatorTitleVisibleColumnsMenuItem);
      else
        AddVisibleColumnsMenu(grid, indicatorTitleVisibleColumnsMenuItem);
    }

    protected virtual void BuildCustomizeColumnsMenuItem(DataGridEh grid, ToolStripDropDown popupMenu)
    {
      ToolStripMenuItem cmi;
      bool isAddMenuItem;

      if (indicatorTitleCustomizeColumnsMenuItem == null)
      {
        indicatorTitleCustomizeColumnsMenuItem = new ToolStripMenuItem();
        indicatorTitleCustomizeColumnsMenuItem.Click += CustomizeColumnsMenuItemClick;
      }
      cmi = indicatorTitleCustomizeColumnsMenuItem;
      if (cmi.Owner != null)
        cmi.Owner.Items.Remove(cmi);

      InitCustomizeColumnsMenuItem(grid, popupMenu, cmi, out isAddMenuItem);

      if (isAddMenuItem)
        popupMenu.Items.Add(cmi);
    }

    protected virtual void CustomizeColumnsMenuItemClick(object sender, EventArgs e)
    {
      ToolStripMenuItem tsi = (ToolStripMenuItem)sender;
      DataGridEh grid = (DataGridEh)tsi.Tag;

      //BaseCustomizePropBarsDialog.ShowCustomizePropBarsDialog(grid);
      CustomizeDataGridColumnsDialog.ShowCustomizeColumnsDialog(grid);
    }

    protected virtual void InitCustomizeColumnsMenuItem(DataGridEh grid, ToolStripDropDown popupMenu, ToolStripMenuItem cmi, out bool isAddMenuItem)
    {
      isAddMenuItem = true;
      cmi.Text = @"Customize columns ...";// EhLib.Properties.Resources.DataGridMenu_SelectAll;
      cmi.Enabled = true;
      cmi.Tag = grid;
    }

    protected virtual void InitPrintIndicatorTitleMenuItem(DataGridEh grid, ToolStripDropDown popupMenu, ToolStripMenuItem cmi, out bool isAddMenuItem)
    {
      isAddMenuItem = true;
      cmi.Text = @"Print";// EhLib.Properties.Resources.DataGridMenu_SelectAll;
      cmi.Enabled = true;
      cmi.Tag = grid;
    }

    protected virtual void InitPrintSetupIndicatorTitleMenuItem(DataGridEh grid, ToolStripDropDown popupMenu, ToolStripMenuItem menuItem, out bool isAddMenuItem)
    {
      menuItem.Tag = grid;

      menuItem.Text = @"Print Setup";// EhLib.Properties.Resources.DataGridMenu_SelectAll;
      menuItem.Enabled = true;

      if (grid.PrintService != null)
        isAddMenuItem = true;
      else
        isAddMenuItem = false;
    }

    private void AddVisibleColumnsMenu(DataGridEh grid, ToolStripMenuItem menuItem)
    {
      ToolStripMenuItemEh cmi;

      foreach (DataGridColumn col in grid.ViewOrderedColumns)
      //for (int i = 0; i <= grid.ViewOrderedColumns.Count - 1; i++)
      {

        if (!String.IsNullOrEmpty(col.Title.Text))
        {
          cmi = new ToolStripMenuItemEh();
          cmi.Tag = col;
          cmi.Text = col.Title.Text;
          //if (Grid.TitleParams.MultiTitle)
          //  cmi.Caption = stringReplace(cmi.Caption, "|", ' - ', [rfReplaceAll]);
          cmi.Checked = col.Visible;
          //cmi.CheckOnClick = true;
          cmi.CloseMenuOnClick = false;
          cmi.Click += MenuVisibleColumnClick;
          //cmi.CloseMenuOnClick = false;
          menuItem.DropDownItems.Add(cmi);
        }
      }
    }

    protected virtual void AddVisibleMultiTitlesMenu(DataGridEh grid, DataGridTitleNode node, ToolStripMenuItem menuItem)
    {
      ToolStripMenuItemEh cmi;

      foreach (DataGridTitleNode chNode in node.Items)
      {

        if (chNode.NodeType == DataGridTitleNodeType.ColumnTitle)
        {
          if (!String.IsNullOrEmpty(chNode.ColumnTitle.Text))
          {
            cmi = new ToolStripMenuItemEh();
            cmi.Tag = chNode;
            cmi.Text = chNode.ColumnTitle.Text;
            cmi.Checked = chNode.ColumnTitle.Column.Visible;
            //cmi.CheckOnClick = true;
            cmi.CloseMenuOnClick = false;
            cmi.Click += MenuVisibleColumnClick;
            //cmi.CloseMenuOnClick = false;
            menuItem.DropDownItems.Add(cmi);
          }
        }
        else if (chNode.SuperTitle != null)
        {
          cmi = new ToolStripMenuItemEh();
          cmi.Tag = chNode;
          cmi.Text = chNode.SuperTitle.Text;
          cmi.Checked = chNode.SuperTitle.Visible;
          //cmi.CheckOnClick = true;
          cmi.CloseMenuOnClick = false;
          cmi.Click += MenuVisibleColumnClick;
          //cmi.CloseMenuOnClick = false;
          menuItem.DropDownItems.Add(cmi);

          //menuItem.DropDown.Closing += ContextMenuClosing;
          //menuItem.DropDownItemClicked += ContextMenuItemClicked;

          AddVisibleMultiTitlesMenu(grid, chNode, cmi);
        }
      }
    }

    protected virtual void MenuVisibleColumnClick(object sender, EventArgs e)
    {
      //Debug.WriteLine(sender.GetType().ToString());
      ToolStripMenuItem tsi = (ToolStripMenuItem)sender;
      DataGridColumn col = tsi.Tag as DataGridColumn;
      DataGridTitleNode titleNode = tsi.Tag as DataGridTitleNode;
      //closeMenuOnClick = true;
      if (col != null)
      {
        col.Visible = !col.Visible;
        tsi.Checked = col.Visible;
      }
      else if (titleNode != null)
      {
        if (titleNode.NodeType == DataGridTitleNodeType.ColumnTitle)
        {
          titleNode.ColumnTitle.Column.Visible = !titleNode.ColumnTitle.Column.Visible;
          tsi.Checked = titleNode.ColumnTitle.Column.Visible;
        }
        else
        {
          titleNode.SuperTitle.Visible = !titleNode.SuperTitle.Visible;
          tsi.Checked = titleNode.SuperTitle.Visible;
        }
      }
    }

    public virtual Bitmap GetEditRecordIndicatorRightImage()
    {
      //return Properties.Resources.EditRecordIndicatorRight;
      return Properties.Resources.Pencil_Left_10x10;
    }

    //private void ContextMenuClosing(object sender, ToolStripDropDownClosingEventArgs e)
    //{
    //  if ((closeMenuOnClick) &&
    //      (e.CloseReason == ToolStripDropDownCloseReason.ItemClicked))
    //    e.Cancel = true;
    //  closeMenuOnClick = false;
    //}

    //private void ContextMenuItemClicked(object sender, ToolStripItemClickedEventArgs e)
    //{
    //  var clickedItem = e.ClickedItem as ToolStripMenuItem;
    //  if (clickedItem != null && clickedItem.CheckOnClick == true)
    //    closeMenuOnClick = true;
    //  else
    //    closeMenuOnClick = false;
    //}

    protected virtual void IndicatorTitleMenuEditClick(object sender, EventArgs e)
    {

    }

    protected virtual void MenuItemCutClick(object sender, EventArgs e)
    {
      ToolStripMenuItem tsi = (ToolStripMenuItem)sender;
      DataGridEh grid = (DataGridEh)tsi.Tag;
      grid.EditActions.Cut();
    }

    protected virtual void IndicatorTitleMenuCopyClick(object sender, EventArgs e)
    {
      ToolStripMenuItem tsi = (ToolStripMenuItem)sender;
      DataGridEh grid = (DataGridEh)tsi.Tag;
      grid.EditActions.Copy();
    }

    protected virtual void IndicatorTitleMenuPasteClick(object sender, EventArgs e)
    {
      ToolStripMenuItem tsi = (ToolStripMenuItem)sender;
      DataGridEh grid = (DataGridEh)tsi.Tag;
      grid.EditActions.Paste();
    }

    protected virtual void IndicatorTitleMenuDeleteClick(object sender, EventArgs e)
    {
      ToolStripMenuItem tsi = (ToolStripMenuItem)sender;
      DataGridEh grid = (DataGridEh)tsi.Tag;
      grid.EditActions.Delete();
    }

    protected virtual void IndicatorTitleMenuSelectAllClick(object sender, EventArgs e)
    {
      ToolStripMenuItem tsi = (ToolStripMenuItem)sender;
      DataGridEh grid = (DataGridEh)tsi.Tag;
      grid.EditActions.SelectAll();
    }

    protected virtual void IndicatorTitleMenuPrintClick(object sender, EventArgs e)
    {
      ToolStripMenuItem tsi = (ToolStripMenuItem)sender;
      DataGridEh grid = (DataGridEh)tsi.Tag;

      DataGridPrintService ps = grid.PrintService;
      if (ps == null)
        ps = this.PrintService;

      ps.PrintPreview(grid);
    }

    protected virtual void IndicatorTitleMenuPrintSetupClick(object sender, EventArgs e)
    {
      ToolStripMenuItem tsi = (ToolStripMenuItem)sender;
      DataGridEh grid = (DataGridEh)tsi.Tag;

      DataGridPrintService ps = grid.PrintService;
      if (ps == null)
        ps = this.PrintService;

      PageSetupDialog psd = new PageSetupDialog();
      psd.Execute(ps);
    }

    protected virtual void ClearColumnFilterMenuItemClick(object sender, EventArgs e)
    {
      ToolStripMenuItem tsi = (ToolStripMenuItem)sender;
      DataGridColumn column = tsi.Tag as DataGridColumn;
      column.Title.Filter.Expression.Clear();
      column.Grid.Title.Filter.ApplyFilter();
    }

    protected virtual void ColumnFilterEqualMenuItemClick(object sender, EventArgs e)
    {
      ToolStripMenuItem tsi = (ToolStripMenuItem)sender;
      DataAxisGridDataCellContextMenuStripNeededEventArgs cmse = tsi.Tag as DataAxisGridDataCellContextMenuStripNeededEventArgs;
      DataGridColumn column = cmse.PropAxisBar as DataGridColumn;
      object value = column.GetValue(cmse.ListItemBar);

      column.Title.Filter.Expression.Clear();
      column.Title.Filter.Expression.Operator1 = DataGridColumnTitleFilterExpressionOperator.Equal;
      column.Title.Filter.Expression.Operand1 = value;
      column.Grid.Title.Filter.ApplyFilter();
    }

    protected virtual void ColumnFilterNotEqualMenuItemClick(object sender, EventArgs e)
    {
      ToolStripMenuItem tsi = (ToolStripMenuItem)sender;
      DataAxisGridDataCellContextMenuStripNeededEventArgs cmse = tsi.Tag as DataAxisGridDataCellContextMenuStripNeededEventArgs;
      DataGridColumn column = cmse.PropAxisBar as DataGridColumn;
      object value = column.GetValue(cmse.ListItemBar);

      column.Title.Filter.Expression.Clear();
      column.Title.Filter.Expression.Operator1 = DataGridColumnTitleFilterExpressionOperator.NotEqual;
      column.Title.Filter.Expression.Operand1 = value;
      column.Grid.Title.Filter.ApplyFilter();
    }

    protected virtual void SortAscendingMenuItemClick(object sender, EventArgs e)
    {
      ToolStripMenuItem tsi = (ToolStripMenuItem)sender;
      DataGridColumn column = tsi.Tag as DataGridColumn;
      DataGridSortCollection sortMarkers = column.Grid.SortMarkers;

      sortMarkers.SetSortState(column, ListSortDirection.Ascending);
      sortMarkers.CommitChanges();
    }

    protected virtual void SortDescendingMenuItemClick(object sender, EventArgs e)
    {
      ToolStripMenuItem tsi = (ToolStripMenuItem)sender;
      DataGridColumn column = tsi.Tag as DataGridColumn;
      DataGridSortCollection sortMarkers = column.Grid.SortMarkers;

      sortMarkers.SetSortState(column, ListSortDirection.Descending);
      sortMarkers.CommitChanges();
    }

    protected virtual DataGridPrintService CreateDefaultPrintService()
    {
      DataGridPrintService result = new DataGridPrintService();
      result.PageFooter.CenterText = "Page &[Page] of &[Pages]";
      result.PageHeader.RightText = "&[Date]";
      return result;
    }
    #endregion IndicatorTitle

    #region SearchBoxToolMenu
    public virtual void BuildSearchBoxToolMenu(DataGridEh grid, ref ToolStripDropDown popupMenu)
    {

      if (popupMenu == null)
      {
        if (searchBoxToolPopupMenu == null)
        {
          searchBoxToolPopupMenu = new DataGridContextMenuStrip();
        }

        searchBoxToolPopupMenu.Items.Clear();

        popupMenu = searchBoxToolPopupMenu;
      }

      var menu = popupMenu as DataGridContextMenuStrip;
      if (menu != null)
        menu.Grid = grid;

      //closeMenuOnClick = true;

      if (grid.SearchBox.OptionsPopupMenuItems.SearchScopes == true)
      {
        //Options Scope
        if (searchBoxOptionsScopeMenuItem == null)
        {
          searchBoxOptionsScopeMenuItem = new ToolStripMenuItemEh();
        }
        if (searchBoxOptionsScopeMenuItem.Owner != null)
          searchBoxOptionsScopeMenuItem.Owner.Items.Remove(searchBoxOptionsScopeMenuItem);
        searchBoxOptionsScopeMenuItem.DropDownItems.Clear();
        //searchBoxOptionsScopeMenuItem.Text = EhLib.Properties.Resources.DataGridMenu_VisibleColumns;
        searchBoxOptionsScopeMenuItem.Text = @"Search Scope";
        popupMenu.Items.Add(searchBoxOptionsScopeMenuItem);

        {
          //Options Scope -> Current Column
          if (searchBoxScopeCurrentColumnMenuItem == null)
          {
            searchBoxScopeCurrentColumnMenuItem = new ToolStripMenuItemEh();
            searchBoxScopeCurrentColumnMenuItem.Click += SearchBoxScopeItemClick;
          }
          searchBoxScopeCurrentColumnMenuItem.Text = @"Current Column";
          searchBoxScopeCurrentColumnMenuItem.Checked = (grid.SearchBox.SearchScope == DataGridSearchBoxScope.CurrentColumn);
          searchBoxScopeCurrentColumnMenuItem.CloseMenuOnClick = false;
          popupMenu.Items.Add(searchBoxScopeCurrentColumnMenuItem);
          searchBoxOptionsScopeMenuItem.DropDownItems.Add(searchBoxScopeCurrentColumnMenuItem);

          //Options Scope -> All The Grid
          if (searchBoxScopeAllTheGridMenuItem == null)
          {
            searchBoxScopeAllTheGridMenuItem = new ToolStripMenuItemEh();
            searchBoxScopeAllTheGridMenuItem.Click += SearchBoxScopeItemClick;
          }
          searchBoxScopeAllTheGridMenuItem.Text = @"All The Grid";
          searchBoxScopeAllTheGridMenuItem.Checked = (grid.SearchBox.SearchScope == DataGridSearchBoxScope.EntireGrid);
          searchBoxScopeAllTheGridMenuItem.CloseMenuOnClick = false;
          popupMenu.Items.Add(searchBoxScopeAllTheGridMenuItem);
          searchBoxOptionsScopeMenuItem.DropDownItems.Add(searchBoxScopeAllTheGridMenuItem);
        }
      }

      if (grid.SearchBox.OptionsPopupMenuItems.CaseSensitive == true)
      {
        //Case Sensitive
        if (searchBoxCaseSensitiveMenuItem == null)
        {
          searchBoxCaseSensitiveMenuItem = new ToolStripMenuItemEh();
          searchBoxCaseSensitiveMenuItem.Click += SearchBoxCaseSensitiveMenuItemClick;
        }
        searchBoxCaseSensitiveMenuItem.Text = @"Case sensitive";
        searchBoxCaseSensitiveMenuItem.CloseMenuOnClick = false;
        searchBoxCaseSensitiveMenuItem.Checked = grid.SearchBox.CaseSensitive;
        popupMenu.Items.Add(searchBoxCaseSensitiveMenuItem);
      }

      //Whole Words
      if (grid.SearchBox.OptionsPopupMenuItems.WholeWords == true)
      {
        if (searchBoxWholeWordsMenuItem == null)
        {
          searchBoxWholeWordsMenuItem = new ToolStripMenuItemEh();
          searchBoxWholeWordsMenuItem.Click += SearchBoxWholeWordsMenuItemClick;
        }
        searchBoxWholeWordsMenuItem.Text = @"Whole words";
        searchBoxWholeWordsMenuItem.CloseMenuOnClick = false;
        searchBoxWholeWordsMenuItem.Checked = grid.SearchBox.WholeWords;
        popupMenu.Items.Add(searchBoxWholeWordsMenuItem);
      }

      //Begins With
      if (grid.SearchBox.OptionsPopupMenuItems.BeginsWith == true)
      {
        if (searchBoxBeginsWithMenuItem == null)
        {
          searchBoxBeginsWithMenuItem = new ToolStripMenuItemEh();
          searchBoxBeginsWithMenuItem.Click += SearchBoxBeginsWithMenuItemClick;
        }
        searchBoxBeginsWithMenuItem.Text = @"Begins with";
        searchBoxBeginsWithMenuItem.CloseMenuOnClick = false;
        searchBoxBeginsWithMenuItem.Checked = grid.SearchBox.CellBeginsWithMode;
        popupMenu.Items.Add(searchBoxBeginsWithMenuItem);
      }
    }

    private void SearchBoxScopeItemClick(object sender, EventArgs e)
    {
      ToolStripMenuItemEh tsi = (ToolStripMenuItemEh)sender;
      DataGridEh grid = tsi.GetDataGrid() as DataGridEh;
      //ToolStrip ownerMenu = tsi.Owner;
      //Control crl = ownerMenu.Parent;
      //ToolStripItem tsoi = tsi.OwnerItem;
      //ownerMenu = tsoi.Owner;
      //DataGridEh grid = (tsi.Tag as DataGridEh);
      //grid.EditActions.Delete();
      if (tsi == searchBoxScopeCurrentColumnMenuItem)
        grid.SearchBox.SearchScope = DataGridSearchBoxScope.CurrentColumn;
      else if (tsi == searchBoxScopeAllTheGridMenuItem)
        grid.SearchBox.SearchScope = DataGridSearchBoxScope.EntireGrid;

      searchBoxScopeCurrentColumnMenuItem.Checked = (grid.SearchBox.SearchScope == DataGridSearchBoxScope.CurrentColumn);
      searchBoxScopeAllTheGridMenuItem.Checked = (grid.SearchBox.SearchScope == DataGridSearchBoxScope.EntireGrid);
    }

    private void SearchBoxCaseSensitiveMenuItemClick(object sender, EventArgs e)
    {
      ToolStripMenuItemEh tsi = (ToolStripMenuItemEh)sender;
      DataGridEh grid = tsi.GetDataGrid() as DataGridEh;
      grid.SearchBox.CaseSensitive = !grid.SearchBox.CaseSensitive;
      tsi.Checked = grid.SearchBox.CaseSensitive;
    }

    private void SearchBoxWholeWordsMenuItemClick(object sender, EventArgs e)
    {
      ToolStripMenuItemEh tsi = (ToolStripMenuItemEh)sender;
      DataGridEh grid = tsi.GetDataGrid() as DataGridEh;
      grid.SearchBox.WholeWords = !grid.SearchBox.WholeWords;
      tsi.Checked = grid.SearchBox.WholeWords;
    }

    private void SearchBoxBeginsWithMenuItemClick(object sender, EventArgs e)
    {
      ToolStripMenuItemEh tsi = (ToolStripMenuItemEh)sender;
      DataGridEh grid = tsi.GetDataGrid() as DataGridEh;
      grid.SearchBox.CellBeginsWithMode = !grid.SearchBox.CellBeginsWithMode;
      tsi.Checked = grid.SearchBox.CellBeginsWithMode;
    }
    #endregion SearchBoxToolMenu

    //public virtual void WriteGridSettings(DataGridEh grid, DataGridSettingsKeeper gridSettings)
    //{
      
    //}

    public virtual void WriteGridSettings(DataGridEh grid, Dictionary<string, object> gridSettings)
    {

    }

    public virtual void WriteColumnSettings(DataGridEh grid, DataGridColumn column, Dictionary<string, object> columnSettings)
    {
      columnSettings.Add("Visible", column.Visible);
      columnSettings.Add("Width", column.Width);
      columnSettings.Add("DisplayIndex", column.DisplayIndex);
    }

    internal void WriteMultiTitleColumnTitleNode(DataGridEh grid, DataGridTitleNode node, Dictionary<string, object> colTitleSettings)
    {
      colTitleSettings.Add("Visible", node.ColumnTitle.Column.Visible);
      colTitleSettings.Add("Width", node.ColumnTitle.Column.Width);
      colTitleSettings.Add("Index", node.Index);
    }

    internal void WriteMultiTitleSuperTitleNode(DataGridEh grid, DataGridTitleNode node, Dictionary<string, object> superTitleSettings)
    {
      superTitleSettings.Add("Visible", node.SuperTitle.Visible);
      superTitleSettings.Add("Index", node.Index);
    }

    public virtual void ReadGridSettings(DataGridEh grid, Dictionary<string, object> gridSettings)
    {
    }

    public virtual void ReadColumnSettings(DataGridEh grid, DataGridColumn column, Dictionary<string, object> columnSettings)
    {
      object visibleObj;
      if (columnSettings.TryGetValue("Visible", out visibleObj))
      {
        if (visibleObj is bool)
          column.Visible = (bool)visibleObj;
      }

      object widthObj;
      if (columnSettings.TryGetValue("Width", out widthObj))
      {
        if (widthObj is int)
          column.Width = (int)widthObj;
      }

      object displayIndexObj;
      if (columnSettings.TryGetValue("DisplayIndex", out displayIndexObj))
      {
        if (displayIndexObj is int)
          column.DisplayIndex = (int)displayIndexObj;
      }
    }

    public virtual void ReadMultiTitleSuperTitleNodeSettings(DataGridEh grid, DataGridTitleNode node, Dictionary<string, object> superTitleSettings)
    {
      object visibleObj;
      if (superTitleSettings.TryGetValue("Visible", out visibleObj))
      {
        if (visibleObj is bool)
          node.SuperTitle.Visible = (bool)visibleObj;
      }

      object indexObj;
      if (superTitleSettings.TryGetValue("Index", out indexObj))
      {
        if (indexObj is int)
          node.NewIndex = (int)indexObj;
      }
    }

    public virtual void ReadMultiTitleColumnTitleNodeSettings(DataGridEh grid, DataGridTitleNode node, Dictionary<string, object> superTitleSettings)
    {
      object visibleObj;
      if (superTitleSettings.TryGetValue("Visible", out visibleObj))
      {
        if (visibleObj is bool)
          node.ColumnTitle.Column.Visible = (bool)visibleObj;
      }

      object widthObj;
      if (superTitleSettings.TryGetValue("Width", out widthObj))
      {
        if (widthObj is int)
          node.ColumnTitle.Column.Width = (int)widthObj;
      }

      object indexObj;
      if (superTitleSettings.TryGetValue("Index", out indexObj))
      {
        if (indexObj is int)
          node.NewIndex = (int)indexObj;
      }
    }

    public virtual int AutoSizeColumnOptionsMaxAutoWidth()
    {
      return 0;
    }

    //public virtual void BuildGridContextMenu(DataGridEh grid, BaseGridCellContextMenuStripNeededEventArgs e)
    //{

    //  ToolStripItem mi;
    //  ToolStripMenuItem cmi;

    //  if (e.ContextMenuStrip == null)
    //  {
    //    if (indicatorTitlePopupMenu == null)
    //    {
    //      indicatorTitlePopupMenu = new DataGridContextMenuStrip();
    //    }

    //    indicatorTitlePopupMenu.Items.Clear();

    //    e.ContextMenuStrip = indicatorTitlePopupMenu;
    //  }
    //  else if (e.ContextMenuStrip.Items.Count > 0)
    //  {

    //    mi = new ToolStripSeparator();
    //    e.ContextMenuStrip.Items.Add(mi);
    //  }

    //  //closeMenuOnClick = true;

    //  if (grid.IndicatorTitle.UseGlobalMenu)
    //  {
    //    //Columns visibility
    //    if (indicatorTitleVisibleColumnsMenuItem == null)
    //    {
    //      indicatorTitleVisibleColumnsMenuItem = new ToolStripMenuItemEh();
    //      //indicatorTitleVisibleColumnsMenuItem.DropDown.Closing += ContextMenuClosing;
    //      //indicatorTitleVisibleColumnsMenuItem.DropDownItemClicked += ContextMenuItemClicked;
    //    }
    //    if (indicatorTitleVisibleColumnsMenuItem.Owner != null)
    //      indicatorTitleVisibleColumnsMenuItem.Owner.Items.Remove(indicatorTitleVisibleColumnsMenuItem);
    //    indicatorTitleVisibleColumnsMenuItem.DropDownItems.Clear();
    //    indicatorTitleVisibleColumnsMenuItem.Text = Properties.Resources.DataGridMenu_VisibleColumns;
    //    e.ContextMenuStrip.Items.Add(indicatorTitleVisibleColumnsMenuItem);


    //    if (grid.Title.MultiTitle.Active)
    //      AddVisibleMultiTitlesMenu(grid, grid.Title.MultiTitle.Root, indicatorTitleVisibleColumnsMenuItem);
    //    else
    //      AddVisibleColumnsMenu(grid, indicatorTitleVisibleColumnsMenuItem);

    //    //Cut
    //    {
    //      if (indicatorTitleCutMenuItem == null)
    //      {
    //        indicatorTitleCutMenuItem = new ToolStripMenuItem();
    //        indicatorTitleCutMenuItem.Click += MenuItemCutClick;
    //      }
    //      cmi = indicatorTitleCutMenuItem;
    //      if (cmi.Owner != null)
    //        cmi.Owner.Items.Remove(cmi);
    //      cmi.Text = Properties.Resources.DataGridMenu_Cut;
    //      cmi.Enabled = grid.EditActions.CanCut();
    //      //DBGridEhCutIndicatorMenuItem.Enabled = grid.CheckCutAction && (geaCutEh in grid.EditActions);
    //      //DBGridEhCutIndicatorMenuItem.TitleMenu = itmCut;
    //      //DBGridEhCutIndicatorMenuItem.ShortCut = ShortCut(Word("X"), [ssCtrl]);
    //      cmi.Tag = grid;
    //      e.ContextMenuStrip.Items.Add(cmi);
    //    }

    //  }
    //}

    public virtual void BuildDataCellContextMenu(DataGridEh grid, DataAxisGridDataCellContextMenuStripNeededEventArgs e)
    {

      ToolStripItem mi;
      ToolStripMenuItem cmi;

      DataGridColumn column = e.PropAxisBar as DataGridColumn;
      BaseGridCellManager cellMan = column.GetRowCellMan(e.ListItemBar as DataGridRow);
      DataAxisGridDataCellMan dataCellMan = cellMan as DataAxisGridDataCellMan;

      if (grid.ContextMenuBuildingMode == ContextMenuBuildingMode.ContextMenuStripPropertyDefined)
      {
        if (e.CellMan.ContextMenuStrip != null)
          e.ContextMenuStrip = grid.ColumnOptions.ContextMenuStrip;
        else if (grid.ColumnOptions.ContextMenuStrip != null)
          e.ContextMenuStrip = grid.ColumnOptions.ContextMenuStrip;
        else
          e.ContextMenuStrip = grid.ContextMenuStrip;
        return;
      }

      if (e.ContextMenuStrip == null)
      {
        if (gridContextMenu == null)
        {
          gridContextMenu = new DataGridContextMenuStrip();
        }

        gridContextMenu.Items.Clear();

        e.ContextMenuStrip = gridContextMenu;
      }

      if (grid.ContextMenuBuildingMode == ContextMenuBuildingMode.LocalMenuCompound ||
          grid.ContextMenuBuildingMode == ContextMenuBuildingMode.LocalAndGlobalMenuCompound)
      {
        // dataCellMan Menus
        {
          if (dataCellMan != null && dataCellMan.ContextMenuStrip != null && e.ContextMenuStrip is DataGridContextMenuStrip)
          {
            if (e.ContextMenuStrip.Items.Count > 0)
            {
              mi = new ToolStripSeparator();
              e.ContextMenuStrip.Items.Add(mi);
            }

            AddItemsFromContextMenuStrip(dataCellMan.ContextMenuStrip, e.ContextMenuStrip as DataGridContextMenuStrip);
          }
        }

        // Grid.ColumnOptions.Menus
        {
          if (column.Grid.ColumnOptions.ContextMenuStrip != null && e.ContextMenuStrip is DataGridContextMenuStrip)
          {
            if (e.ContextMenuStrip.Items.Count > 0)
            {
              mi = new ToolStripSeparator();
              e.ContextMenuStrip.Items.Add(mi);
            }

            AddItemsFromContextMenuStrip(column.Grid.ColumnOptions.ContextMenuStrip, e.ContextMenuStrip as DataGridContextMenuStrip);
          }
        }

        // Grid.Menus
        {
          if (column.Grid.ContextMenuStrip != null && e.ContextMenuStrip is DataGridContextMenuStrip)
          {
            if (e.ContextMenuStrip.Items.Count > 0)
            {
              mi = new ToolStripSeparator();
              e.ContextMenuStrip.Items.Add(mi);
            }

            AddItemsFromContextMenuStrip(column.Grid.ContextMenuStrip, e.ContextMenuStrip as DataGridContextMenuStrip);
          }
        }
      }

      if (grid.ContextMenuBuildingMode == ContextMenuBuildingMode.LocalAndGlobalMenuCompound)
      {
        if (e.ContextMenuStrip.Items.Count > 0)
        {
          mi = new ToolStripSeparator();
          e.ContextMenuStrip.Items.Add(mi);
        }

        //Cut
        if (indicatorTitleCutMenuItem == null)
        {
          indicatorTitleCutMenuItem = new ToolStripMenuItem();
          indicatorTitleCutMenuItem.Click += MenuItemCutClick;
        }
        cmi = indicatorTitleCutMenuItem;
        if (cmi.Owner != null)
          cmi.Owner.Items.Remove(cmi);
        cmi.Text = Properties.Resources.DataGridMenu_Cut;
        cmi.Enabled = grid.EditActions.CanCut();
        cmi.Tag = grid;
        e.ContextMenuStrip.Items.Add(cmi);

        //Copy
        {
          if (indicatorTitleCopyMenuItem == null)
          {
            indicatorTitleCopyMenuItem = new ToolStripMenuItem();
            indicatorTitleCopyMenuItem.Click += IndicatorTitleMenuCopyClick;
          }
          cmi = indicatorTitleCopyMenuItem;
          if (cmi.Owner != null)
            cmi.Owner.Items.Remove(cmi);
          cmi.Text = Properties.Resources.DataGridMenu_Copy;
          cmi.Enabled = grid.EditActions.CanCopy();
          cmi.Tag = grid;
          e.ContextMenuStrip.Items.Add(cmi);
        }

        //Paste
        {
          if (indicatorTitlePasteMenuItem == null)
          {
            indicatorTitlePasteMenuItem = new ToolStripMenuItem();
            indicatorTitlePasteMenuItem.Click += IndicatorTitleMenuPasteClick;
          }
          cmi = indicatorTitlePasteMenuItem;
          if (cmi.Owner != null)
            cmi.Owner.Items.Remove(cmi);
          cmi.Text = Properties.Resources.DataGridMenu_Paste;
          cmi.Enabled = grid.EditActions.CanPaste();
          cmi.Tag = grid;
          e.ContextMenuStrip.Items.Add(cmi);
        }

        //Delete
        {
          if (indicatorTitleDeleteMenuItem == null)
          {
            indicatorTitleDeleteMenuItem = new ToolStripMenuItem();
            indicatorTitleDeleteMenuItem.Click += IndicatorTitleMenuDeleteClick;
          }
          cmi = indicatorTitleDeleteMenuItem;
          if (cmi.Owner != null)
            cmi.Owner.Items.Remove(cmi);
          cmi.Text = Properties.Resources.DataGridMenu_Delete;
          cmi.Enabled = grid.EditActions.CanDelete();
          cmi.Tag = grid;
          e.ContextMenuStrip.Items.Add(cmi);
        }

        //Separator
        {
          if (menuBeforeAllSeparator == null)
          {
            menuBeforeAllSeparator = new ToolStripSeparator();
          }
          if (menuBeforeAllSeparator.Owner != null)
            menuBeforeAllSeparator.Owner.Items.Remove(menuBeforeAllSeparator);
          e.ContextMenuStrip.Items.Add(menuBeforeAllSeparator);
        }

        //Select All
        {
          if (indicatorTitleAllMenuItem == null)
          {
            indicatorTitleAllMenuItem = new ToolStripMenuItem();
            indicatorTitleAllMenuItem.Click += IndicatorTitleMenuSelectAllClick;
          }
          cmi = indicatorTitleAllMenuItem;
          if (cmi.Owner != null)
            cmi.Owner.Items.Remove(cmi);
          cmi.Text = Properties.Resources.DataGridMenu_SelectAll;
          cmi.Enabled = grid.EditActions.CanSelectAll();
          cmi.Tag = grid;
          e.ContextMenuStrip.Items.Add(cmi);
        }

        if (grid.Title.AutoSortMarking)
        {
          AddSortingMenuItems(e.ContextMenuStrip, e.PropAxisBar as DataGridColumn);
        }

        if (grid.Title.Filter.Active)
        {
          //Separator
          {
            if (menuSeparator == null)
            {
              menuSeparator = new ToolStripSeparator();
            }
            if (menuSeparator.Owner != null)
              menuSeparator.Owner.Items.Remove(menuSeparator);
            e.ContextMenuStrip.Items.Add(menuSeparator);
          }

          //Clear Filter In Column
          {
            if (clearColumnFilterMenuItem == null)
            {
              clearColumnFilterMenuItem = new ToolStripMenuItem();
              clearColumnFilterMenuItem.Click += ClearColumnFilterMenuItemClick;
            }
            cmi = clearColumnFilterMenuItem;
            if (cmi.Owner != null)
              cmi.Owner.Items.Remove(cmi);
            cmi.Text = String.Format(Properties.Resources.DataGridMenu_ClearColumnFilter, column.Title.Text);
            cmi.Enabled = !column.Title.Filter.Expression.IsEmpty();
            cmi.Tag = e.PropAxisBar as DataGridColumn;
            e.ContextMenuStrip.Items.Add(cmi);
          }

          //Column Filter Equal
          {
            string displayValue = column.GetDisplayText(e.ListItemBar as DataGridRow);
            displayValue = EhLibUtils.TruncString(displayValue, 40);

            if (сolumnFilterEqualMenuItem == null)
            {
              сolumnFilterEqualMenuItem = new ToolStripMenuItem();
              сolumnFilterEqualMenuItem.Click += ColumnFilterEqualMenuItemClick;
            }
            cmi = сolumnFilterEqualMenuItem;
            if (cmi.Owner != null)
              cmi.Owner.Items.Remove(cmi);
            cmi.Text = String.Format(Properties.Resources.DataGridMenu_ColumnFilterEqual, displayValue);
            cmi.Enabled = column.Grid.Title.Filter.Active;
            cmi.Tag = e;
            e.ContextMenuStrip.Items.Add(cmi);
          }

          //Column Filter Not Equal
          {
            string displayValue = column.GetDisplayText(e.ListItemBar as DataGridRow);
            displayValue = EhLibUtils.TruncString(displayValue, 40);

            if (сolumnFilterNotEqualMenuItem == null)
            {
              сolumnFilterNotEqualMenuItem = new ToolStripMenuItem();
              сolumnFilterNotEqualMenuItem.Click += ColumnFilterNotEqualMenuItemClick;
            }
            cmi = сolumnFilterNotEqualMenuItem;
            if (cmi.Owner != null)
              cmi.Owner.Items.Remove(cmi);
            cmi.Text = String.Format(Properties.Resources.DataGridMenu_ColumnFilterNotEqual, displayValue);
            cmi.Enabled = column.Grid.Title.Filter.Active;
            cmi.Tag = e;
            e.ContextMenuStrip.Items.Add(cmi);
          }
        }
      }

      ////Column Filter Contains
      //сolumnFilterContainsMenuItem;

      ////Column Filter Not Contains
      //сolumnFilterNotContainsMenuItem;
    }

    public virtual void BuildTitleCellContextMenu(DataGridEh grid, DataGridTitleCellContextMenuStripNeededEventArgs e)
    {
      //ToolStripItem mi;
      //ToolStripMenuItem cmi;

      if (grid.ContextMenuBuildingMode == ContextMenuBuildingMode.ContextMenuStripPropertyDefined)
      {
        if (e.Column.Title.ContextMenuStrip != null)
          e.ContextMenuStrip = e.Column.Title.ContextMenuStrip;
        else if (grid.Title.ContextMenuStrip != null)
          e.ContextMenuStrip = grid.Title.ContextMenuStrip;
        else if (grid.ContextMenuStrip != null)
          e.ContextMenuStrip = grid.ContextMenuStrip;

        return;
      }

      if (e.ContextMenuStrip == null)
      {
        if (gridContextMenu == null)
        {
          gridContextMenu = new DataGridContextMenuStrip();
        }

        gridContextMenu.Items.Clear();

        e.ContextMenuStrip = gridContextMenu;
      }

      if (grid.ContextMenuBuildingMode == ContextMenuBuildingMode.LocalMenuCompound ||
          grid.ContextMenuBuildingMode == ContextMenuBuildingMode.LocalAndGlobalMenuCompound)
      {
        // Column.Title Menus
        {
          if (e.Column.Title.ContextMenuStrip != null)
          { 
            if (e.ContextMenuStrip.Items.Count > 0)
            {
              var mi = new ToolStripSeparator();
              e.ContextMenuStrip.Items.Add(mi);
            }

            AddItemsFromContextMenuStrip(e.Column.Title.ContextMenuStrip, e.ContextMenuStrip as DataGridContextMenuStrip);
          }
        }

        // grid.Title Menus
        {
          if (grid.Title.ContextMenuStrip != null && e.ContextMenuStrip is DataGridContextMenuStrip)
          {
            if (e.ContextMenuStrip.Items.Count > 0)
            {
              var mi = new ToolStripSeparator();
              e.ContextMenuStrip.Items.Add(mi);
            }

            AddItemsFromContextMenuStrip(grid.Title.ContextMenuStrip, e.ContextMenuStrip as DataGridContextMenuStrip);
          }
        }

        // Grid.Menus
        {
          if (grid.ContextMenuStrip != null && e.ContextMenuStrip is DataGridContextMenuStrip)
          {
            if (e.ContextMenuStrip.Items.Count > 0)
            {
              var mi = new ToolStripSeparator();
              e.ContextMenuStrip.Items.Add(mi);
            }

            AddItemsFromContextMenuStrip(grid.ContextMenuStrip, e.ContextMenuStrip as DataGridContextMenuStrip);
          }
        }
      }

      if (grid.ContextMenuBuildingMode == ContextMenuBuildingMode.LocalAndGlobalMenuCompound)
      {

        if (grid.Title.AutoSortMarking)
        {
          AddSortingMenuItems(e.ContextMenuStrip, e.Column);
        }
      }

    }

    private void AddItemsFromContextMenuStrip(ContextMenuStrip source, DataGridContextMenuStrip target)
    {
      ToolStripItem[] itemsArr = new ToolStripItem[source.Items.Count];
      source.Items.CopyTo(itemsArr, 0);
      source.Items.Clear();

      foreach (ToolStripItem dmi in itemsArr)
      {
        target.Items.Add(dmi);
        target.ReturnItems.Add(new ToolStripItemReturnData(dmi, source));
      }
    }

    public virtual void AddSortingMenuItems(ContextMenuStrip contextMenuStrip, DataGridColumn column)
    {
      //Separator
      {
        if (contextMenuStrip.Items.Count > 0)
        {
          if (menuSortItemsSeparator == null)
          {
            menuSortItemsSeparator = new ToolStripSeparator();
          }
          if (menuSortItemsSeparator.Owner != null)
            menuSortItemsSeparator.Owner.Items.Remove(menuSortItemsSeparator);
          contextMenuStrip.Items.Add(menuSortItemsSeparator);
        }
      }

      //Sort Ascending
      {
        if (sortAscendingMenuItem == null)
        {
          sortAscendingMenuItem = new ToolStripMenuItem();
          sortAscendingMenuItem.Click += SortAscendingMenuItemClick;
        }
        var cmi = sortAscendingMenuItem;
        if (cmi.Owner != null)
          cmi.Owner.Items.Remove(cmi);
        cmi.Text = Properties.Resources.STFilterListItem_SortingByAscend;
        cmi.Enabled = true;
        cmi.Tag = column;
        cmi.Image = Properties.Resources.AscendingSort;
        contextMenuStrip.Items.Add(cmi);
      }

      //Sort Descending
      {
        if (sortDescendingMenuItem == null)
        {
          sortDescendingMenuItem = new ToolStripMenuItem();
          sortDescendingMenuItem.Click += SortDescendingMenuItemClick;
        }
        var cmi = sortDescendingMenuItem;
        if (cmi.Owner != null)
          cmi.Owner.Items.Remove(cmi);
        cmi.Text = Properties.Resources.STFilterListItem_SortingByDescend;
        cmi.Enabled = true;
        cmi.Tag = column;
        cmi.Image = Properties.Resources.DescendingSort;
        contextMenuStrip.Items.Add(cmi);
      }
    }

  }
}
