using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace Volpe.Cafe.UI
{
    sealed class ToolbarButton : Label
    {
        #region 
        public new event EventHandler Click;
        #endregion
        #region 
        public ToolbarButton()
            : base()
        {
            this.ImageAlign = ContentAlignment.MiddleCenter;
            this.Size = new Size(24, 24);
            this.Text = string.Empty;
        }
        #endregion
        #region 
        public override void Refresh()
        {
            this.ProcessMouseLeave();
            base.Refresh();
        }
        protected override void WndProc(ref Message m)
        {
            IntPtr lParam = m.LParam;
            int x = Win32.LoWord(lParam.ToInt32());
            int y = Win32.HiWord(lParam.ToInt32());
            switch ((Win32.Messages)m.Msg)
            {
                case Win32.Messages.WM_MOUSEMOVE:
                    this.ProcessMouseMove(x, y);
                    break;
                case Win32.Messages.WM_MOUSELEAVE:
                    this.ProcessMouseLeave();
                    break;
                case Win32.Messages.WM_LBUTTONDOWN:
                    this.ProcessLMouseDown(x, y);
                    break;
                case Win32.Messages.WM_LBUTTONUP:
                    this.ProcessLMouseUp(x, y);
                    break;
            }
            try
            {
                base.WndProc(ref m);
            } catch (Exception ex) { Console.WriteLine(ex.ToString()); }
        }
        void ProcessMouseMove(int x, int y)
        {
            if (this.IsOutOfBounds(x, y))
            {   
                this.ProcessMouseLeave();
            }
            else if (!this._mouseHover)
            {
                this.SuspendLayout();
                this._mouseHover = true;
                this.BorderStyle = BorderStyle.FixedSingle;
                this.BackColor =  Color.Lavender;
                this.SetBounds(this.Left - 4, this.Top - 4, this.Width + 8, this.Height + 8);
                this.Image = this._bigImage;
                this.BringToFront();
                this.ResumeLayout(true);
            }
        }
        void ProcessMouseLeave()
        {
            if (this._mouseHover)
            {
                this.SuspendLayout();
                this._mouseHover = false;
                this._mouseDown  = false;
                this.BorderStyle = BorderStyle.None;
                this.BackColor   = Color.Empty;
                this.SetBounds(this.Left + 4, this.Top + 4, this.Width - 8, this.Height - 8, BoundsSpecified.All);
                this.Image = this._smallImage;
                this.ResumeLayout(true);
            }
        }
        void ProcessLMouseDown(int x, int y)
        {
            if (!this._mouseDown)
            {
                this._mouseDown = true;
                this.BorderStyle = BorderStyle.Fixed3D;
            }
        }
        void ProcessLMouseUp(int x, int y)
        {
            if (this._mouseDown)
            {
                this._mouseDown = false;
                this.BorderStyle = BorderStyle.FixedSingle;
                this.ProcessMouseLeave();
                if (this.Click != null)
                {   
                    this.Click(this, new MouseEventArgs(MouseButtons.Left, 1, x, y, 0));
                }
            }
        }
        bool IsOutOfBounds(Point pt)
        {
            return this.IsOutOfBounds(pt.X, pt.Y);
        }
        bool IsOutOfBounds(int x, int y)
        {
            int xl = 0, yl = 0, xr = this.Width, yr = this.Height;
            if      (this.BorderStyle == BorderStyle.FixedSingle) { xl--; yl--; xr+=2; yr+=2; }
            else if (this.BorderStyle == BorderStyle.Fixed3D    ) { xl--; yl--; }
            return (x < xl || y < yl || x > xr || y > yr);
        }
        #endregion
        #region 
        public new bool Enabled
        {
            get { return base.Enabled; }
            set
            {
                if (value != base.Enabled)
                {
                    if (value == false) { this.ProcessMouseLeave(); }
                    base.Enabled = value;
                }
            }
        }
        [Category("Appearance")]
        [DefaultValue(typeof(Image), "none")]
        [Description("Indicates the default image that will be displayed on the control.")]
        public Image SmallImage { get { return this._smallImage; } set { base.Image = this._smallImage = value; } }
        [Category("Appearance")]
        [DefaultValue(typeof(Image), "none")]
        [Description("Indicates the image that will be displayed when a mouse is hovered over the control.")]
        public Image BigImage { get { return this._bigImage; } set { this._bigImage = value; } }
        public override string Text { get { return string.Empty; } set { base.Text = string.Empty; } }
        #endregion
        #region 
        Image _smallImage;
        Image _bigImage;
        bool _mouseDown  = false;
        bool _mouseHover = false;
        #endregion
    }
}

