using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using WinFormControl;

namespace ButcherFactory.Controls
{
 public class ColorButton : System.Windows.Forms.Button
  {
    public ColorButton()
    {
      mouseAction = MouseActionType.None;

      this.SetStyle(ControlStyles.AllPaintingInWmPaint |
      ControlStyles.DoubleBuffer |
      ControlStyles.UserPaint, true);
      this.ForeColor = Color.White;
      this.BackColor = Color.FromArgb(77, 135, 245);
    }

    Color selectedColor = Color.FromArgb(15, 215, 107);
    [Browsable(true)]
    public Color SelectedColor
    {
      get { return selectedColor; }
      set { selectedColor = value; }
    }

    [DefaultValue(false)]
    public bool Selected { get; set; }

    [DefaultValue(false)]
    public bool EnableGroup { get; set; }

    [DefaultValue(false)]
    public bool StateHold { get; set; }

    [DefaultValue(false)]
    public bool PlaySound { get; set; }

    [DefaultValue(false)]
    public bool SelfControlEnable { get; set; }

    private int radius=8;
    [DefaultValue(8)]
    public int Radius { get { return radius; } set { radius = value; } }

    private enum MouseActionType
    {
      None,
      Hover,
      Click
    }

    private MouseActionType mouseAction;

    protected override void OnPaint(PaintEventArgs e)
    {
      Graphics g = e.Graphics;
      var cC = Parent.BackColor;
      if (cC == Color.Transparent)
        cC = Color.White;
      g.Clear(cC);

      Color clr = Color.FromArgb(180, this.BackColor);
      if (Selected)
        clr = SelectedColor;
      Color from = Color.FromArgb(200, clr);
      int btnOffset = 0;
      if (Enabled)
      {
        switch (mouseAction)
        {
          case MouseActionType.Click:
            clr = Color.FromArgb(225, clr);
            btnOffset = 2;
            break;
          case MouseActionType.Hover:
            clr = Color.FromArgb(225, clr); ;
            break;
        }
      }
      else
        from = clr = Color.FromArgb(186, 186, 186);
      g.SmoothingMode = SmoothingMode.AntiAlias;

      Rectangle rc = new Rectangle(btnOffset, btnOffset, this.ClientSize.Width - btnOffset, this.ClientSize.Height - btnOffset);
      GraphicsPath path1 = this.GetPath(rc, Radius);
      LinearGradientBrush br1 = new LinearGradientBrush(rc, from, clr, LinearGradientMode.Vertical);
      g.FillPath(br1, path1);

      var textBrush = new SolidBrush(this.ForeColor);

      StringFormat drawFormat = new StringFormat();
      drawFormat.FormatFlags = StringFormatFlags.DisplayFormatControl;
      drawFormat.LineAlignment = StringAlignment.Center;
      drawFormat.Alignment = System.Drawing.StringAlignment.Center;

      g.DrawString(this.Text, this.Font, textBrush, rc, drawFormat);
    }
    private GraphicsPath GetPath(Rectangle rc, int r)
    {
      int x = rc.X, y = rc.Y, w = rc.Width, h = rc.Height;
      GraphicsPath path = new GraphicsPath();
      path.AddArc(x, y, r, r, 180, 90); //Upper   left   corner 
      path.AddArc(x + w - r, y, r, r, 270, 90); //Upper   right   corner 
      path.AddArc(x + w - r, y + h - r, r, r, 0, 90); //Lower   right   corner 
      path.AddArc(x, y + h - r, r, r, 90, 90); //Lower   left   corner 
      path.CloseFigure();
      return path;
    }

    protected override void OnMouseDown(MouseEventArgs e)
    {
      if (e.Button == MouseButtons.Left)
      {
        this.mouseAction = MouseActionType.Click;
        this.Invalidate();
      }
      base.OnMouseDown(e);
    }

    protected override void OnMouseUp(MouseEventArgs mevent)
    {
      this.mouseAction = MouseActionType.None;
      this.Invalidate();
      base.OnMouseUp(mevent);
    }

    protected override void OnMouseEnter(EventArgs e)
    {
      this.mouseAction = MouseActionType.Hover;
      this.Invalidate();
      base.OnMouseEnter(e);
    }

    protected override void OnMouseLeave(EventArgs e)
    {
      this.mouseAction = MouseActionType.None;
      this.Invalidate();
      base.OnMouseLeave(e);
    }

    protected override void OnClick(EventArgs e)
    {
      this.Enabled = false;
      if (PlaySound)
        SoundPalyUtil.PlaySound(SoundType.Click);
      try
      {
        base.OnClick(e);
        if (!SelfControlEnable)
          this.Enabled = true;
      }
      catch
      {
        Application.DoEvents();
        this.Enabled = true;
        this.Focus();
        throw;
      }

      if (EnableGroup)
      {
        foreach (var ctl in Parent.Controls)
        {
          var btn = ctl as ColorButton;
          if (btn == null)
            continue;
          btn.Selected = btn.Text == this.Text;
          btn.Invalidate();
        }
      }
      else if (StateHold)
        Selected = !Selected;
      Application.DoEvents();
      this.Focus();
    }
  }
}
