using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace BWP.WinFormControl
{
  public class UComboBox : ComboBox
  {
    ToolTip itemTip = null;
    public UComboBox()
    {
      this.DropDown += (sender, de) =>
      {
        CRefreshItems();
        //if (string.IsNullOrEmpty(this.Text))
        //  return;

        //if (_enableTopItem && Items.Count > 1)
        //  this.SelectedIndex = 1;
        //else if (!_enableTopItem && Items.Count > 0)
        //  this.SelectedIndex = 0;
        SelectionStart = Text.Length;
      };
      this.SelectedIndexChanged += (sender, e) =>
      {
        var item = SelectedItem as WordPair;
        if (item.DisplayName == string.Empty)
          _selectedObj = null;
        else
          _selectedObj = item;
      };

      this.DrawMode = DrawMode.OwnerDrawFixed;
      this.DrawItem += new DrawItemEventHandler(cb_DrawItem);
      this.DropDownClosed += new EventHandler(cb_DropDownClosed);
      itemTip = new ToolTip();
      itemTip.SetToolTip(this, "");
    }

    void cb_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e)
    {
      // 绘制背景
      e.DrawBackground();
      //绘制列表项目
      e.Graphics.DrawString(this.Items[e.Index].ToString(), e.Font, System.Drawing.Brushes.Black, e.Bounds);
      //将高亮的列表项目的文字传递到toolTip1(之前建立ToolTip的一个实例)
      if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
        itemTip.Show(this.Items[e.Index].ToString(), this, e.Bounds.X + e.Bounds.Width, e.Bounds.Y + e.Bounds.Height);
      e.DrawFocusRectangle();
    }
    void cb_DropDownClosed(object sender, EventArgs e)
    {
      itemTip.Hide(this);
    }

    public string DefaultServerPath = "/MainSystem/B3ClientService/Rpcs/";
    public string CodeArgs { get; set; }

    private bool _enableTopItem = true;
    public bool EnableTopItem
    {
      get { return _enableTopItem; }
      set { _enableTopItem = value; }
    }

    private int range = 10;
    public int Range
    {
      get { return range; }
      set { range = value; }
    }

    private string rpcPath;
    public void Init(string _rpcPath)
    {
      rpcPath = _rpcPath;
      if (string.IsNullOrEmpty(rpcPath))
        return;
      rpcPath = string.Format("{0}{1}", DefaultServerPath, rpcPath);
    }

    protected override void OnKeyUp(KeyEventArgs e)
    {
      base.OnKeyUp(e);
      if (e.KeyCode == System.Windows.Forms.Keys.Enter)
      {
        this.FindForm().Cursor = Cursors.Default;
        if (string.IsNullOrEmpty(this.Text) || this.DisplayValue != this.Text || string.IsNullOrEmpty(this.SelectedText))
        {
          if (!this.DroppedDown)
            this.DroppedDown = true;
        }
      }
    }

    void CRefreshItems()
    {
      var inputArgs = string.Empty;
      if (this.SelectedItem == null)
        inputArgs = this.Text;
      var list = ComboBoxHelper.GetList(rpcPath, inputArgs, CodeArgs, Range);
      if (_enableTopItem)
        list.Insert(0, new WordPair(string.Empty));
      this.Items.Clear();
      foreach (var item in list)
        this.Items.Add(item);
      this.DisplayMember = "DisplayName";
      this.ValueMember = "PhyName";
    }

    public void Clear()
    {
      _selectedObj = null;
      this.Text = string.Empty;
    }

    public void Fill(string display, string value)
    {
      if (string.IsNullOrEmpty(display))
      {
        Clear();
        return;
      }
      _selectedObj = new WordPair(display, value);
      this.Text = display == null ? string.Empty : display;
    }

    public bool IsEmpty { get { return _selectedObj == null; } }

    public string DisplayValue { get { if (IsEmpty) return null; return _selectedObj.DisplayName; } }

    public string Value { get { if (IsEmpty) return null; return _selectedObj.PhyName; } }

    public long? LongValue
    {
      get
      {
        if (IsEmpty)
          return null;
        long v;
        if (long.TryParse(_selectedObj.PhyName, out v))
          return v;
        return null;
      }
    }

    private WordPair _selectedObj = null;

    protected override void OnDropDown(EventArgs e)
    {
      base.OnDropDown(e);
      AdjustComboBoxDropDownListWidth();  //调整comboBox的下拉列表的大小
    }

    private void AdjustComboBoxDropDownListWidth()
    {
      Graphics g = null;
      Font font = null;
      try
      {
        int width = this.Width;
        g = this.CreateGraphics();
        font = this.Font;

        //checks if a scrollbar will be displayed.
        //If yes, then get its width to adjust the size of the drop down list.
        int vertScrollBarWidth =
            (this.Items.Count > this.MaxDropDownItems)
            ? SystemInformation.VerticalScrollBarWidth : 0;

        int newWidth;
        foreach (object s in this.Items)  //Loop through list items and check size of each items.
        {
          if (s != null)
          {
            newWidth = (int)g.MeasureString(s.ToString().Trim(), font).Width
                + vertScrollBarWidth;
            if (width < newWidth)
              width = newWidth;   //set the width of the drop down list to the width of the largest item.
          }
        }
        this.DropDownWidth = width;
      }
      catch
      { }
      finally
      {
        if (g != null)
          g.Dispose();
      }
    }
  }
}
