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

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

namespace EhLib
{
  public partial class DataGridSimpleFilterDialog : Form
  {

    public static DataGridSimpleFilterDialog Dialog { get; set; }

    //public IMemTableDataFieldValueListEh FieldValueList = null;
    public DataGridColumn Column;

    public DataGridSimpleFilterDialog()
    {
      InitializeComponent();
    }

    public void FillDialogFromColumnFilter1(DataGridColumnTitleFilterExpressionOperator __operator,
      object operand, ComboBox operatorComboBox, ComboBox operandComboBox)
    {
      bool startMultyChar;
      bool endMultyChar;
      // -  TextOperand: String;
      startMultyChar = false;
      endMultyChar = false;

      operandComboBox.SelectedValue = __operator;
      switch (__operator)
      {
        case DataGridColumnTitleFilterExpressionOperator.Like:
          if ((CharAtPos(operandComboBox.Text, 1) == '%') && (CharAtPos(operandComboBox.Text, 2) != '%'))
          {
            startMultyChar = true;
          }
          if ((CharAtPos(operandComboBox.Text, operandComboBox.Text.Length) == '%') &&
              (CharAtPos(operandComboBox.Text, operandComboBox.Text.Length - 1) != '%'))
          {
            endMultyChar = true;
          }
          if (startMultyChar && endMultyChar)
          {
            operandComboBox.Text = operandComboBox.Text.Substring(1, operandComboBox.Text.Length - 2);
          }
          else if (startMultyChar)
          {
            operandComboBox.Text = operandComboBox.Text.Substring(1, operandComboBox.Text.Length - 1);
          }
          else if (endMultyChar)
          {
            operandComboBox.Text = operandComboBox.Text.Substring(0, operandComboBox.Text.Length - 1);
          }
          break;
        case DataGridColumnTitleFilterExpressionOperator.NotLike:
          if ((CharAtPos(operandComboBox.Text, 1) == '%') && (CharAtPos(operandComboBox.Text, 2) != '%'))
          {
            startMultyChar = true;
          }
          if ((CharAtPos(operandComboBox.Text, operandComboBox.Text.Length) == '%') &&
              (CharAtPos(operandComboBox.Text, operandComboBox.Text.Length - 1) != '%'))
          {
            endMultyChar = true;
          }
          if (startMultyChar && endMultyChar)
          {
            operandComboBox.Text = operandComboBox.Text.Substring(1, operandComboBox.Text.Length - 2);
          }
          else if (startMultyChar)
          {
            operandComboBox.Text = operandComboBox.Text.Substring(1, operandComboBox.Text.Length - 1);
          }
          else if (endMultyChar)
          {
            operandComboBox.Text = operandComboBox.Text.Substring(0, operandComboBox.Text.Length - 1);
          }
          break;
        case DataGridColumnTitleFilterExpressionOperator.In:
        case DataGridColumnTitleFilterExpressionOperator.NotIn:
          string inS = "";
          List<object> inList;
          operatorComboBox.SelectedItem = GetOperatorComboBoxItemByOperator(__operator, operatorComboBox);

          var list = operand as List<object>;
          if (list != null)
          {
            inList = list;
            foreach (object inListItem in inList)
            {
              if (String.IsNullOrEmpty(inS))
                inS = Column.GetValueDisplayText(inListItem);
              else
                inS = inS + ", " + Column.GetValueDisplayText(inListItem);
            }
          }

          operandComboBox.Text = inS;

          break;
        default:
          operatorComboBox.SelectedItem = GetOperatorComboBoxItemByOperator(__operator, operatorComboBox);

          if (operand != null)
            operandComboBox.Text = operand.ToString();
          break;

      }
    }

    ComboBoxItem GetOperatorComboBoxItemByOperator(DataGridColumnTitleFilterExpressionOperator __Operator,
      ComboBox operatorComboBox)
    {
      foreach (ComboBoxItem item in operatorComboBox.Items)
      {
        if ((DataGridColumnTitleFilterExpressionOperator)item.Value == __Operator)
          return item;
      }
      return null;
    }

    public void FillDialogFromColumnFilter(DataGridColumnTitleFilter stFilter)
    {
      FillDialogFromColumnFilter1(stFilter.Expression.Operator1, stFilter.Expression.Operand1, ComboBox1, DBComboBoxEh1);
      rbOr.Checked = (stFilter.Expression.Relation == DataGridColumnTitleFilterExpressionLogRelation.Or);
      rbAnd.Checked = !rbOr.Checked;
      FillDialogFromColumnFilter1(stFilter.Expression.Operator2, stFilter.Expression.Operand2, ComboBox2, DBComboBoxEh2);
    }

    public void CheckAddListOperator(ComboBox comboBox, DataGridColumnTitleFilterExpressionOperator oper, string text)
    {
      if (Column.Title.Filter.IsFilterOperatorSupported(oper))
        comboBox.Items.Add(new ComboBoxItem(text, oper));
    }

    public void InitSignComboBox(ComboBox comboBox)
    {

      comboBox.Items.Clear();
      comboBox.Items.Add(new ComboBoxItem("", DataGridColumnTitleFilterExpressionOperator.Non));

      CheckAddListOperator(comboBox, DataGridColumnTitleFilterExpressionOperator.Equal, Properties.Resources.SSimpFilter_equals + " (=)");
      CheckAddListOperator(comboBox, DataGridColumnTitleFilterExpressionOperator.NotEqual, Properties.Resources.SSimpFilter_does_not_equal + " (<>)");

      CheckAddListOperator(comboBox, DataGridColumnTitleFilterExpressionOperator.GreaterThan, Properties.Resources.SSimpFilter_is_greate_than + " (>)");
      CheckAddListOperator(comboBox, DataGridColumnTitleFilterExpressionOperator.GreaterOrEqual, Properties.Resources.SSimpFilter_is_greate_than_or_equall_to + " (>=)");
      CheckAddListOperator(comboBox, DataGridColumnTitleFilterExpressionOperator.LessThan, Properties.Resources.SSimpFilter_is_less_than + " (<)");
      CheckAddListOperator(comboBox, DataGridColumnTitleFilterExpressionOperator.LessOrEqual, Properties.Resources.SSimpFilter_is_less_than_or_equall_to + " (<=)");

      CheckAddListOperator(comboBox, DataGridColumnTitleFilterExpressionOperator.BeginWith, Properties.Resources.SSimpFilter_begins_with);
      CheckAddListOperator(comboBox, DataGridColumnTitleFilterExpressionOperator.NotBeginWith, Properties.Resources.SSimpFilter_does_not_begin_with);
      CheckAddListOperator(comboBox, DataGridColumnTitleFilterExpressionOperator.EndWith, Properties.Resources.SSimpFilter_ends_with);
      CheckAddListOperator(comboBox, DataGridColumnTitleFilterExpressionOperator.NotEndWith, Properties.Resources.SSimpFilter_does_not_end_with);
      CheckAddListOperator(comboBox, DataGridColumnTitleFilterExpressionOperator.Contain, Properties.Resources.SSimpFilter_contains);
      CheckAddListOperator(comboBox, DataGridColumnTitleFilterExpressionOperator.NotContain, Properties.Resources.SSimpFilter_does_not_contain);

      //ComboBox.Items.Add(new ComboboxItem(Properties.Resources.SSimpFilter_like, DataGridColumnTitleFitlerExpressionOperator.Like));
      //ComboBox.Items.Add(new ComboboxItem(Properties.Resources.SSimpFilter_not_like, DataGridColumnTitleFitlerExpressionOperator.NotLike));

      CheckAddListOperator(comboBox, DataGridColumnTitleFilterExpressionOperator.In, Properties.Resources.SSimpFilter_in_list);
      CheckAddListOperator(comboBox, DataGridColumnTitleFilterExpressionOperator.NotIn, Properties.Resources.SSimpFilter_not_in_list);

      CheckAddListOperator(comboBox, DataGridColumnTitleFilterExpressionOperator.IsEmpty, Properties.Resources.SSimpFilter_is_blank);
      CheckAddListOperator(comboBox, DataGridColumnTitleFilterExpressionOperator.IsNotEmpty, Properties.Resources.SSimpFilter_is_not_blank);

      comboBox.MaxDropDownItems = comboBox.Items.Count;
      comboBox.DisplayMember = "Text";
      comboBox.ValueMember = "Value";
      //ComboBox.SelectedValue = DataGridColumnTitleFitlerExpressionOperator.Equal;
      comboBox.SelectedItem = comboBox.Items[0];
      //ComboBox.SelectedText = "";
    }

    public void InitValuesComboBox(ComboBox comboBox, Point pos)
    {
      comboBox.Location = pos;
      comboBox.Visible = true;
      comboBox.Items.Clear();

      //List<KeyDisplayValue> listItems = Column.GetUnicalStringListValues();
      Collection<KeyDisplayValue> listItems = Column.GetUniqueStringListValues();
      KeyDisplayValue[] arr = new KeyDisplayValue[listItems.Count];
      listItems.CopyTo(arr, 0);

      if (listItems.Count > 0)
        // ReSharper disable once CoVariantArrayConversion
        comboBox.Items.AddRange(arr);
      comboBox.Text = "";
      comboBox.SelectedIndex = -1;
    }

    public void Init()
    {
      InitSignComboBox(ComboBox1);
      InitSignComboBox(ComboBox2);
      Edit1.Visible = false;
      Edit2.Visible = false;
      InitValuesComboBox(DBComboBoxEh1, DBComboBoxEh1.Location);
      InitValuesComboBox(DBComboBoxEh2, DBComboBoxEh2.Location);
      FillDialogFromColumnFilter(Column.Title.Filter);
    }

    public void SetFilterFromDialog1(ComboBox operatorComboBox, ComboBox operandComboBox,
      out DataGridColumnTitleFilterExpressionOperator __operator, out object operand)
    {

      __operator = (DataGridColumnTitleFilterExpressionOperator)((ComboBoxItem)operatorComboBox.SelectedItem).Value;
      if (__operator == DataGridColumnTitleFilterExpressionOperator.Non)
        operand = null;
      else if ((__operator == DataGridColumnTitleFilterExpressionOperator.In) ||
               (__operator == DataGridColumnTitleFilterExpressionOperator.NotIn))
      {
        List<string> sList = new List<string>(operandComboBox.Text.Split(','));
        List<object> vList = new List<object>();
        
        foreach (var item in sList)
        {
          object v = Column.ParseValue(item);
          vList.Add(v);
        }

        operand = vList;
      }
      else if ((__operator == DataGridColumnTitleFilterExpressionOperator.IsEmpty) ||
               (__operator == DataGridColumnTitleFilterExpressionOperator.IsNotEmpty))
      {
        operand = null;
      }
      else
        operand = operandComboBox.Text;

      //      if (
      ////          ((Column.Title.Filter.Expression.ExpressionType == botString) && 
      //           ((CharAtPos(SValue, 1) == ' ')) || 
      //            (SValue.IndexOf(")") >= 0) || 
      //            (SValue.IndexOf("(") >= 0))
      //      {
      //        SValue = '\'' + SValue + '\'';
      //      }
      //      if (new ArrayList(new int[] { 7, 8, 11, 12 }).Contains(Oper))
      //      {
      //        SValue = SValue + '%';
      //      }
      //      if (new ArrayList(new int[] { 9, 10, 11, 12 }).Contains(Oper))
      //      {
      //        SValue = '%' + SValue;
      //      }
      //      if (new ArrayList(new int[] { 15, 16 }).Contains(Oper))
      //      {
      //        SValue = '(' + SValue + ')';
      //      }
    }

    public void SetFilterFromDialog()
    {
      DataGridColumnTitleFilterExpression expr;

      DataGridColumnTitleFilterExpressionOperator operator1;
      object operand1;
      DataGridColumnTitleFilterExpressionOperator operator2;
      object operand2;
      DataGridColumnTitleFilterExpressionLogRelation relation = DataGridColumnTitleFilterExpressionLogRelation.Non;

      SetFilterFromDialog1(ComboBox1, DBComboBoxEh1, out operator1, out operand1);
      SetFilterFromDialog1(ComboBox2, DBComboBoxEh2, out operator2, out operand2);
      if (operator2 != DataGridColumnTitleFilterExpressionOperator.Non)
      {
        if (rbOr.Checked)
          relation = DataGridColumnTitleFilterExpressionLogRelation.Or;
        else
          relation = DataGridColumnTitleFilterExpressionLogRelation.And;
      }

      expr = Column.Title.Filter.Expression;
      expr.Operator1 = operator1;
      if ((expr.Operator1 == DataGridColumnTitleFilterExpressionOperator.In) ||
          (expr.Operator1 == DataGridColumnTitleFilterExpressionOperator.NotIn))
        expr.Operand1 = operand1;
      else
        expr.Operand1 = Column.ParseValue(operand1);
      expr.Relation = relation;
      expr.Operator2 = operator2;
      if ((expr.Operator2 == DataGridColumnTitleFilterExpressionOperator.In) ||
          (expr.Operator2 == DataGridColumnTitleFilterExpressionOperator.NotIn))
        expr.Operand2 = operand2;
      else
        expr.Operand2 = Column.ParseValue(operand2);
    }

    private void TDBGridEhSimpleFilterDialog_FormClosing(object sender, FormClosingEventArgs e)
    {
      e.Cancel = true;
      if (this.DialogResult == System.Windows.Forms.DialogResult.OK)
      {
        SetFilterFromDialog();
        Column.Grid.Title.Filter.ApplyFilter();
      }
      e.Cancel = false;
    }

    public void DBComboBoxEh1Change(object sender)
    {
      // -  if (DBComboBoxEh1.Text <> '') and (ComboBox1.ItemIndex = 0) then

    }

    #region static methods
    public static char CharAtPos(string s, int pos)
    {
      char result;
      if ((s.Length < pos) || (pos < 1))
      {
        result = '\0';
      }
      else
      {
        result = s[pos];
      }
      return result;
    }

    public static bool StartDBGridEhColumnFilterDialog(DataGridColumn column)
    {
      if (Dialog == null)
      {
        Dialog = new DataGridSimpleFilterDialog();
      }
      Dialog.Column = column;
      Dialog.Init();
      if (Dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
        return true;
      else
        return false;
    }
    #endregion static methods

  }

  public class ComboBoxItem
  {
    public string Text { get; set; }
    public object Value { get; set; }

    public ComboBoxItem(string text, object value)
    {
      this.Text = text;
      this.Value = value;        
    } 

    public override string ToString()
    {
      return Text;
    }
  }

}