using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.ComponentModel;

namespace Giants.Launcher
{
	public class ImageButton : PictureBox, IButtonControl
	{

		#region IButtonControl Members

		private DialogResult m_DialogResult;
		public DialogResult DialogResult
		{
			get
			{
				return this.m_DialogResult;
			}
			set
			{
                this.m_DialogResult = value;
			}
		}

		public void NotifyDefault(bool value)
		{
            this.isDefault = value;
		}

		public void PerformClick()
		{
			base.OnClick(EventArgs.Empty);
		}

		#endregion

		#region HoverImage
		private Image m_HoverImage;

		[Category("Appearance")]
		[Description("Image to show when the button is hovered over.")]
		public Image HoverImage
		{
			get { return this.m_HoverImage; }
			set { this.m_HoverImage = value; if (this.hover) this.Image = value; }
		}
		#endregion
		#region DownImage
		private Image m_DownImage;

		[Category("Appearance")]
		[Description("Image to show when the button is depressed.")]
		public Image DownImage
		{
			get { return this.m_DownImage; }
			set { this.m_DownImage = value; if (this.down) this.Image = value; }
		}
		#endregion
		#region NormalImage
		private Image m_NormalImage;

		[Category("Appearance")]
		[Description("Image to show when the button is not in any other state.")]
		public Image NormalImage
		{
			get { return this.m_NormalImage; }
			set { this.m_NormalImage = value; if (!(this.hover || this.down)) this.Image = value; }
		}
		#endregion

		private const int WM_KEYDOWN = 0x0100;
		private const int WM_KEYUP = 0x0101;
		private bool hover = false;
		private bool down = false;
		private bool isDefault = false;

		#region Overrides

		[Browsable(true)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
		[Category("Appearance")]
		[Description("The text associated with the control.")]
		public override string Text
		{
			get
			{
				return base.Text;
			}
			set
			{
				base.Text = value;
			}
		}

		[Browsable(true)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
		[Category("Appearance")]
		[Description("The font used to display text in the control.")]
		public override Font Font
		{
			get
			{
				return base.Font;
			}
			set
			{
				base.Font = value;
			}
		}

		#endregion

		#region Description Changes
		[Description("Controls how the ImageButton will handle image placement and control sizing.")]
		public new PictureBoxSizeMode SizeMode { get { return base.SizeMode; } set { base.SizeMode = value; } }

		[Description("Controls what type of border the ImageButton should have.")]
		public new BorderStyle BorderStyle { get { return base.BorderStyle; } set { base.BorderStyle = value; } }
		#endregion

		#region Hiding

		[Browsable(false)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public new Image Image { get { return base.Image; } set { base.Image = value; } }

		[Browsable(false)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public new ImageLayout BackgroundImageLayout { get { return base.BackgroundImageLayout; } set { base.BackgroundImageLayout = value; } }

		[Browsable(false)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public new Image BackgroundImage { get { return base.BackgroundImage; } set { base.BackgroundImage = value; } }

		[Browsable(false)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public new String ImageLocation { get { return base.ImageLocation; } set { base.ImageLocation = value; } }

		[Browsable(false)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public new Image ErrorImage { get { return base.ErrorImage; } set { base.ErrorImage = value; } }

		[Browsable(false)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public new Image InitialImage { get { return base.InitialImage; } set { base.InitialImage = value; } }

		[Browsable(false)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public new bool WaitOnLoad { get { return base.WaitOnLoad; } set { base.WaitOnLoad = value; } }
		#endregion

		#region Events
		protected override void OnMouseMove(MouseEventArgs e)
		{
            this.hover = true;
			if (this.down)
			{
				if ((this.m_DownImage != null) && (this.Image != this.m_DownImage))
                    this.Image = this.m_DownImage;
			}
			else
				if (this.m_HoverImage != null)
                this.Image = this.m_HoverImage;
				else
                this.Image = this.m_NormalImage;
			base.OnMouseMove(e);
		}

		protected override void OnMouseLeave(EventArgs e)
		{
            this.hover = false;
            this.Image = this.m_NormalImage;
			base.OnMouseLeave(e);
		}

		protected override void OnMouseDown(MouseEventArgs e)
		{
			base.Focus();
            this.OnMouseUp(null);
            this.down = true;
			if (this.m_DownImage != null)
                this.Image = this.m_DownImage;
			base.OnMouseDown(e);
		}

		protected override void OnMouseUp(MouseEventArgs e)
		{
            this.down = false;
			if (this.hover)
			{
				if (this.m_HoverImage != null)
                    this.Image = this.m_HoverImage;
			}
			else
                this.Image = this.m_NormalImage;
			base.OnMouseUp(e);
		}

		protected override void OnLostFocus(EventArgs e)
		{
            this.OnMouseUp(null);
			base.OnLostFocus(e);
		}

		protected override void OnPaint(PaintEventArgs pe)
		{
			base.OnPaint(pe);
			if ((!string.IsNullOrEmpty(this.Text)) && (pe != null) && (base.Font != null))
			{
				SolidBrush drawBrush = new SolidBrush(base.ForeColor);
				SizeF drawStringSize = pe.Graphics.MeasureString(base.Text, base.Font);
				PointF drawPoint;
				if (base.Image != null)
					drawPoint = new PointF(base.Image.Width / 2 - drawStringSize.Width / 2, base.Image.Height / 2 - drawStringSize.Height / 2);
				else
					drawPoint = new PointF(base.Width / 2 - drawStringSize.Width / 2, base.Height / 2 - drawStringSize.Height / 2);
				pe.Graphics.DrawString(base.Text, base.Font, drawBrush, drawPoint);
			}
		}

		protected override void OnTextChanged(EventArgs e)
		{
            this.Refresh();
			base.OnTextChanged(e);
		}
		#endregion
	}
}
