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

using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;

namespace EhLib
{

  public enum InEditButtonStyleKind
  {
    SysDropDown, AltDropDown, EndEllipsis, Push, Custom
  }

  [ToolboxItem(false)]
  public class EditButton : EditItem
  {
    #region fields
    private InEditButtonStyleKind styleKind = InEditButtonStyleKind.SysDropDown;
    #endregion fields

    #region constructor
    public EditButton()
    {
      Shortcut = Shortcut.AltDownArrow;
    }
    #endregion constructor

    #region design-time properties
    [DefaultValue(InEditButtonStyleKind.SysDropDown)]
    public InEditButtonStyleKind StyleKind
    {
      get
      {
        return styleKind;
      }
      set
      {
        if (value != styleKind)
        {
          styleKind = value;
          NotifyEditItemChanged();
        }
      }
    }

    [DefaultValue(Shortcut.AltDownArrow)]
    public Shortcut Shortcut { get; set; }

    #endregion design-time properties

    #region run-time properties
    public override bool SupportInControlBorderMerging
    {
      get
      {
        if ((StyleKind == InEditButtonStyleKind.SysDropDown) &&
            Application.RenderWithVisualStyles &&
            Environment.OSVersion.Version.Major >= 6
           )
          return true;
        else
          return false;
      }
    }
    #endregion run-time properties

    #region methods
    protected override EditItemControl CreateInEditWinControl()
    {
      return new EditButtonControl(this);
    }

    public override bool IntegratedInBorder()
    {
      if ((StyleKind == InEditButtonStyleKind.SysDropDown) &&
          (ComboBoxRenderer.DropDownButtonAlignSupported(DropDownButtonAlign.Right)))
        return true;
      else
        return false;
    }

    public override bool IsDropDown()
    {
      if (StyleKind == InEditButtonStyleKind.SysDropDown ||
          StyleKind == InEditButtonStyleKind.AltDropDown)
        return true;
      else
        return false;
    }

    protected internal override bool ProcessCmdKey(ref Message msg, Keys keyData)
    {
      if (((int)keyData == (int)Shortcut))
      {
        DownEventArgs e = new DownEventArgs(false, 0);
        OnDown(e); 
        if (e.Handled)
          return true; 
        else
          return false;
      }
      else
      {
        return false;
      }
    }

    internal void ConnectToEditor(BaseEditBoxEh editor)
    {
      if (EditControl != null)
        throw (new ArgumentException("Edit item already connected to the EditBox"));

      InEditWinControl.Parent = editor;
      EditControl = editor;
    }

    internal void DisconnectFromEditor()
    {
      InEditWinControl.Parent = null;
      EditControl = null;
    }

    protected internal override void Paint(EditItemContextPaintEventArgs e)
    {
      bool themed = Application.RenderWithVisualStyles;
      Rectangle btnRect = e.ClientRect;
      DropDownButtonAlign buttonAlign;

      if ((themed) && (StyleKind != InEditButtonStyleKind.SysDropDown))
        btnRect.Inflate(1, 1);

      if (StyleKind == InEditButtonStyleKind.SysDropDown)
      {
        //SysDropDown can draw only with Background
        if (!e.PaintBackground) return;

        ComboBoxState state = ComboBoxRenderer.GetButtonState(e.Hot, e.Pressed && e.Hot, e.Disabled);
        if (e.InControlBorderMerging &&
           (ComboBoxRenderer.DropDownButtonAlignSupported(DropDownButtonAlign.Right)))
          buttonAlign = DropDownButtonAlign.Right;
        else
          buttonAlign = DropDownButtonAlign.Neutral;

        ComboBoxRenderer.DrawDropDownButton(e.Graphics, btnRect, state, buttonAlign, null);
      }
      else
      {
        PushButtonState state = EhLibUtils.GetPushButtonState(e.Hot, e.Pressed && e.Hot, e.Disabled);

        if (e.PaintBackground)
        {
          ButtonRenderer.DrawButton(e.Graphics, btnRect, state);
        }

        if (e.PaintForeground)
        {
          if (StyleKind == InEditButtonStyleKind.AltDropDown)
            EhLibDrawStyle.DefaultToolElementsDrawStyle.DrawDropDownButtonSign(e.Graphics, btnRect, state);
          else if (StyleKind == InEditButtonStyleKind.EndEllipsis)
            EhLibDrawStyle.DefaultToolElementsDrawStyle.DrawEllipsisButtonSign(e.Graphics, btnRect, state);
        }
      }
    }

    #endregion methods
  }

  [DesignTimeVisible(false)]
  //[ToolboxItem(false)]
  public class EditButtonControl : EditItemControl
  {
    private bool pushed;
    //private bool captured = false;
    private bool mouseOver;

    #region constructor
    public EditButtonControl(EditItem inEditControl) : base(inEditControl)
    {
      //SetStyle(ControlStyles.Opaque, false);
    }
    #endregion constructor

    #region properties
    protected internal EditButton InEditButton
    {
      get { return (EditButton)InEditControl; }
    }
    #endregion properties

    protected override void OnPaint(PaintEventArgs e)
    {
      bool themed = Application.RenderWithVisualStyles;
      Rectangle btnRect = ClientRectangle;
      DropDownButtonAlign buttonAlign;

      //e.Graphics.FillRectangle(new SolidBrush(Color.Red), ClientRectangle);

      if ((themed) && (InEditButton.StyleKind != InEditButtonStyleKind.SysDropDown))
          btnRect.Inflate(1, 1);

      //ButtonRenderer.DrawButton(e.Graphics, btnRect, PushButtonState.Normal);
      if (InEditButton.StyleKind == InEditButtonStyleKind.SysDropDown)
      {
        ComboBoxState state = ComboBoxRenderer.GetButtonState(mouseOver, pushed && mouseOver, !Enabled);
        if (InControlBorderMerging && 
           (ComboBoxRenderer.DropDownButtonAlignSupported(DropDownButtonAlign.Right)))
          buttonAlign = DropDownButtonAlign.Right;
        else
          buttonAlign = DropDownButtonAlign.Neutral;

        ComboBoxRenderer.DrawDropDownButton(e.Graphics, btnRect, state, buttonAlign, this);
      }
      else
      {
        //AltDropDown, EndElipsis, Push, Custom
        PushButtonState state = EhLibUtils.GetPushButtonState(mouseOver, pushed && mouseOver, !Enabled);
        ButtonRenderer.DrawButton(e.Graphics, btnRect, state);
        if (InEditButton.StyleKind == InEditButtonStyleKind.AltDropDown)
          EhLibDrawStyle.DefaultToolElementsDrawStyle.DrawDropDownButtonSign(e.Graphics, btnRect, state);
        else if (InEditButton.StyleKind == InEditButtonStyleKind.EndEllipsis)
          EhLibDrawStyle.DefaultToolElementsDrawStyle.DrawEllipsisButtonSign(e.Graphics, btnRect, state);
      }
      //e.Graphics.DrawRectangle(new Pen(Color.Red), ClientRectangle);
      if (Focused)
        e.Graphics.DrawString("f", Font, new SolidBrush(ForeColor), btnRect.Location);
    }

    protected override void OnMouseDown(MouseEventArgs e)
    {
      base.OnMouseDown(e);
      if (!InEditButton.EditControl.Focused)
        InEditButton.EditControl.Focus();
      //this.parent.FocusInternal();

      if (/*!parent.ValidationCancelled &&*/ e.Button == MouseButtons.Left)
      {
        pushed = true;
        //captured = true;
        mouseOver = true;
        Capture = true;
        Invalidate();
      }

      InEditButton.OnDown(new DownEventArgs(false, 0));
    }

    protected override void OnMouseMove(MouseEventArgs e)
    {
      base.OnMouseMove(e);
      if (Capture)
      {
        Rectangle bounds = ClientRectangle;
        if (bounds.Contains(e.X, e.Y) && !mouseOver)
        {
          mouseOver = true;
          Invalidate();
        }
        else if (!bounds.Contains(e.X, e.Y) && mouseOver)
        {
          mouseOver = false;
          Invalidate();
        }
      }
    }

    protected override void OnMouseUp(MouseEventArgs e)
    {
      base.OnMouseUp(e);
      if (/*!Parent.ValidationCancelled && */e.Button == MouseButtons.Left)
      {
        pushed = false;
        //captured = false;
        Capture = false;
        Invalidate();
      }
    }

    protected override void OnMouseEnter(EventArgs e)
    {
      base.OnMouseEnter(e);
      if (!Capture)
        mouseOver = true;
      Invalidate();
    }

    protected override void OnMouseLeave(EventArgs e)
    {
      base.OnMouseLeave(e);
      if (!Capture)
        mouseOver = false;
      Invalidate();
    }

    protected override void OnClick(EventArgs e)
    {
      base.OnClick(e);
      InEditButton.OnClick(new ClickEventArgs());
    }

  }

}
