context: //
  // ToolStripItem.cs
  //
  // Permission is hereby granted, free of charge, to any person obtaining
  // a copy of this software and associated documentation files (the
  // "Software"), to deal in the Software without restriction, including
  // without limitation the rights to use, copy, modify, merge, publish,
  // distribute, sublicense, and/or sell copies of the Software, and to
  // permit persons to whom the Software is furnished to do so, subject to
  // the following conditions:
  // 
  // The above copyright notice and this permission notice shall be
  // included in all copies or substantial portions of the Software.
  // 
  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  //
  // Copyright (c) 2006 Jonathan Pobst
  //
  // Authors:
  //	Jonathan Pobst (monkey@jpobst.com)
  //
  
  
  using System;
  using System.Drawing;
  using System.ComponentModel;
  using System.Runtime.InteropServices;
  
  namespace System.Windows.Forms
  {
  	[DefaultEvent ("Click")]
  	[DefaultProperty ("Text")]
  	[DesignTimeVisible (false)]
  	[ToolboxItem (false)]
  	[Designer ("System.Windows.Forms.Design.ToolStripItemDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
  	public abstract class ToolStripItem : Component, IDropTarget, IComponent, IDisposable
  	{
  		#region Private Variables
  		private AccessibleObject accessibility_object;
  		private string accessible_default_action_description;
  		private bool allow_drop;
  		private ToolStripItemAlignment alignment;
  		private AnchorStyles anchor;
  		private bool available;
  		private bool auto_size;
  		private bool auto_tool_tip;
  		private Color back_color;
  		private Image background_image;
  		private ImageLayout background_image_layout;
  		private Rectangle bounds;
  		private bool can_select;
  		private ToolStripItemDisplayStyle display_style;
  		private DockStyle dock;
  		private bool double_click_enabled;
  		private bool enabled;
  		private Size explicit_size;
  		private Font font;
  		private Color fore_color;
  		private Image image;
  		private ContentAlignment image_align;
  		private int image_index;
  		private string image_key;
  		private ToolStripItemImageScaling image_scaling;
  		private Color image_transparent_color;
  		private bool is_disposed;
  		internal bool is_pressed;
  		private bool is_selected;
  		private Padding margin;
  		private MergeAction merge_action;
  		private int merge_index;
  		private string name;
  		private ToolStripItemOverflow overflow;
  		private ToolStrip owner;
  		internal ToolStripItem owner_item;
  		private Padding padding;
  		private ToolStripItemPlacement placement;
  		private RightToLeft right_to_left;
  		private bool right_to_left_auto_mirror_image;
  		private Object tag;
  		private string text;
  		private ContentAlignment text_align;
  		private ToolStripTextDirection text_direction;
  		private TextImageRelation text_image_relation;
  		private string tool_tip_text;
  		private bool visible;
  
  		private EventHandler frame_handler;	// For animating images
  		private ToolStrip parent;
  		private Size text_size;
  		#endregion
  
  		#region Public Constructors
  		protected ToolStripItem ()
  			: this (String.Empty, null, null, String.Empty)
  		{
  		}
  
  		protected ToolStripItem (string text, Image image, EventHandler onClick)
  			: this (text, image, onClick, String.Empty)
  		{
  		}
  
  		protected ToolStripItem (string text, Image image, EventHandler onClick, string name)
  		{
  			this.alignment = ToolStripItemAlignment.Left;
  			this.anchor = AnchorStyles.Left | AnchorStyles.Top;
  			this.auto_size = true;
  			this.auto_tool_tip = this.DefaultAutoToolTip;
  			this.available = true;
  			this.back_color = Color.Empty;
  			this.background_image_layout = ImageLayout.Tile;
  			this.can_select = true;
  			this.display_style = this.DefaultDisplayStyle;
  			this.dock = DockStyle.None;
  			this.enabled = true;
  			this.fore_color = Color.Empty;
  			this.image = image;
  			this.image_align = ContentAlignment.MiddleCenter;
  			this.image_index = -1;
  			this.image_key = string.Empty;
  			this.image_scaling = ToolStripItemImageScaling.SizeToFit;
  			this.image_transparent_color = Color.Empty;
  			this.margin = this.DefaultMargin;
  			this.merge_action = MergeAction.Append;
  			this.merge_index = -1;
  			this.name = name;
  			this.overflow = ToolStripItemOverflow.AsNeeded;
  			this.padding = this.DefaultPadding;
  			this.placement = ToolStripItemPlacement.None;
  			this.right_to_left = RightToLeft.Inherit;
  			this.bounds.Size = this.DefaultSize;
  			this.text = text;
  			this.text_align = ContentAlignment.MiddleCenter;
  			this.text_direction = DefaultTextDirection;
  			this.text_image_relation = TextImageRelation.ImageBeforeText;
  			this.visible = true;
  
  			this.Click += onClick;
  			OnLayout (new LayoutEventArgs (null, string.Empty));
  		}
  		#endregion
  
  		#region Public Properties
  		[Browsable (false)]
  		[EditorBrowsable (EditorBrowsableState.Advanced)]
  		[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  		public AccessibleObject AccessibilityObject {
  			get { 
  				if (this.accessibility_object == null)
  					this.accessibility_object = CreateAccessibilityInstance ();
  					
  				return this.accessibility_object;
  			}
  		}
  
  		[Browsable (false)]
  		[EditorBrowsable (EditorBrowsableState.Advanced)]
  		[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  		public string AccessibleDefaultActionDescription {
  			get {
  				if (this.accessibility_object == null)
  					return null;
  				
  				return this.accessible_default_action_description;
  			}
  			set { this.accessible_default_action_description = value; }
  		}
  
  		[Localizable (true)]
  		[DefaultValue (null)]
  		public string AccessibleDescription {
  			get {
  				if (this.accessibility_object == null)
  					return null;
  				
  				return this.AccessibilityObject.Description;
  			}
  			set { this.AccessibilityObject.description = value; }
  		}
  
  		[Localizable (true)]
  		[DefaultValue (null)]
  		public string AccessibleName {
  			get { 
  				if (this.accessibility_object == null)
  					return null;
  					
  				return this.AccessibilityObject.Name; 
  			}
  			set { this.AccessibilityObject.Name = value; }
  		}
  		
  		[DefaultValue (AccessibleRole.Default)]
  		public AccessibleRole AccessibleRole {
  			get
  			{
  				if (this.accessibility_object == null)
  					return AccessibleRole.Default;
  				
  				return this.AccessibilityObject.Role;
  			}
  			set { this.AccessibilityObject.role = value; }
  		}
  		
  		[DefaultValue (ToolStripItemAlignment.Left)]
  		public ToolStripItemAlignment Alignment {
  			get { return this.alignment; }
  			set {
  				if (!Enum.IsDefined (typeof (ToolStripItemAlignment), value))
  					throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripItemAlignment", value));
  
  				if (this.alignment != value) {
  					this.alignment = value;
  					this.CalculateAutoSize (); 
  				}
  			}
  		}
  
  		[MonoTODO ("Stub, does nothing")]
  		[Browsable (false)]
  		[DefaultValue (false)]
  		[EditorBrowsable (EditorBrowsableState.Advanced)]
  		public virtual bool AllowDrop {
  			get { return this.allow_drop; }
  			set { this.allow_drop = value; }
  		}
  		
  		[Browsable (false)]
  		[DefaultValue (AnchorStyles.Top | AnchorStyles.Left)]
  		[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  		public AnchorStyles Anchor {
  			get { return this.anchor; }
  			set { this.anchor = value; }
  		}
  			
  		[Localizable (true)]
  		[DefaultValue (true)]
  		[DesignerSerializationVisibility (DesignerSerializationVisibility.Visible)]
  		[RefreshProperties (RefreshProperties.All)]
  		public bool AutoSize {
  			get { return this.auto_size; }
  			set { 
  				this.auto_size = value; 
  				this.CalculateAutoSize (); 
  			}
  		}
  
  		[DefaultValue (false)]
  		public bool AutoToolTip {
  			get { return this.auto_tool_tip; }
  			set { this.auto_tool_tip = value; }
  		}
  
  		[Browsable (false)]
  		[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  		public bool Available {
  			get { return this.available; }
  			set {
  				if (this.available != value) {
  					available = value;
  					visible = value;
  
  					if (this.parent != null)
  						parent.PerformLayout (); 
  						
  					OnAvailableChanged (EventArgs.Empty); 
  					OnVisibleChanged (EventArgs.Empty);
  				}
  			}
  		}
  
  		public virtual Color BackColor {
  			get {
  				if (back_color != Color.Empty)
  					return back_color;
  
  				if (Parent != null)
  					return parent.BackColor;
  
  				return Control.DefaultBackColor;
  			}
  			set {
  				if (this.back_color != value) {
  					back_color = value;
  					OnBackColorChanged (EventArgs.Empty);
  					this.Invalidate ();
  				}
  			}
  		}
  
  		[Localizable (true)]
  		[DefaultValue (null)]
  		public virtual Image BackgroundImage {
  			get { return this.background_image; }
  			set { 
  				if (this.background_image != value) {
  					this.background_image = value;
  					this.Invalidate ();
  				}
  			}
  		}
  
  		[Localizable (true)]
  		[DefaultValue (ImageLayout.Tile)]
  		public virtual ImageLayout BackgroundImageLayout {
  			get { return this.background_image_layout; }
  			set { 
  				if (this.background_image_layout != value) {
  					this.background_image_layout = value;
  					this.Invalidate (); 
  				}
  			}
  		}
  
  		[Browsable (false)]
  		public virtual Rectangle Bounds {
  			get { return this.bounds; }
  		}
  
  		[Browsable (false)]
  		public virtual bool CanSelect {
  			get { return this.can_select; }
  		}
  
  		[Browsable (false)]
  		public Rectangle ContentRectangle {
  			get {
  				// ToolStripLabels don't have a border
  				if (this is ToolStripLabel || this is ToolStripStatusLabel)
  					return new Rectangle (0, 0, this.bounds.Width, this.bounds.Height);
  
  				if (this is ToolStripDropDownButton && (this as ToolStripDropDownButton).ShowDropDownArrow)
  					return new Rectangle (2, 2, this.bounds.Width - 13, this.bounds.Height - 4);
  
  				return new Rectangle (2, 2, this.bounds.Width - 4, this.bounds.Height - 4);
  			}
  		}
  
  		public virtual ToolStripItemDisplayStyle DisplayStyle {
  			get { return this.display_style; }
  			set {
  				if (this.display_style != value) {
  					this.display_style = value; 
  					this.CalculateAutoSize (); 
  					OnDisplayStyleChanged (EventArgs.Empty);
  				}
  			}
  		}
  
  		[Browsable (false)]
  		public bool IsDisposed {
  			get { return this.is_disposed; }
  		}
  		
  		[Browsable (false)]
  		[DefaultValue (DockStyle.None)]
  		public DockStyle Dock {
  			get { return this.dock; }
  			set {
  				if (this.dock != value) {
  					if (!Enum.IsDefined (typeof (DockStyle), value))
  						throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for DockStyle", value));
  
  					this.dock = value;
  					this.CalculateAutoSize ();
  				}
  			}
  		}
  
  		[DefaultValue (false)]
  		public bool DoubleClickEnabled {
  			get { return this.double_click_enabled; }
  			set { this.double_click_enabled = value; }
  		}
  
  		[Localizable (true)]
  		[DefaultValue (true)]
  		public virtual bool Enabled {
  			get { 
  				if (Parent != null)
  					if (!Parent.Enabled)
  						return false;
  
  				if (Owner != null)
  					if (!Owner.Enabled)
  						return false;
  						
  				return enabled;
  			}
  			set { 
  				if (this.enabled != value) {
  					this.enabled = value; 
  					OnEnabledChanged (EventArgs.Empty); 
  					this.Invalidate ();
  				}
  			}
  		}
  
  		[Localizable (true)]
  		public virtual Font Font {
  			get { 
  				if (font != null)
  					return font;
  					
  				if (Parent != null)
  					return Parent.Font;
  					
  				return DefaultFont;
  			}
  			set { 
  				if (this.font != value) {
  					this.font = value; 
  					this.CalculateAutoSize (); 
  					this.OnFontChanged (EventArgs.Empty); 
  					this.Invalidate ();
  				}
  			}
  		}
  
  		public virtual Color ForeColor {
  			get { 
  				if (fore_color != Color.Empty)
  					return fore_color;
  					
  				if (Parent != null)
  					return parent.ForeColor;
  					
  				return Control.DefaultForeColor;
  			}
  			set { 
  				if (this.fore_color != value) {
  					this.fore_color = value; 
  					this.OnForeColorChanged (EventArgs.Empty); 
  					this.Invalidate ();
  				}
  			}
  		}
  
  		[Browsable (false)]
  		[EditorBrowsable (EditorBrowsableState.Always)]
  		[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  		public int Height {
  			get { return this.Size.Height; }
  			set { 
  				this.Size = new Size (this.Size.Width, value); 
  				this.explicit_size.Height = value;
  				
  				if (this.Visible) {
  					this.CalculateAutoSize ();
  					this.OnBoundsChanged ();
  					this.Invalidate (); 
  				} 
  			}
  		}
  
  		[Localizable (true)]
  		public virtual Image Image {
  			get { 
  				if (this.image != null)
  					return this.image;
  					
  				if (this.image_index >= 0)
  					if (this.owner != null && this.owner.ImageList != null && this.owner.ImageList.Images.Count > this.image_index)
  						return this.owner.ImageList.Images[this.image_index];
  
  
  				if (!string.IsNullOrEmpty (this.image_key))
  					if (this.owner != null && this.owner.ImageList != null && this.owner.ImageList.Images.Count > this.image_index)
  						return this.owner.ImageList.Images[this.image_key];
  						
  				return null;
  			}
  			set {
  				if (this.image != value) {
  					StopAnimation ();
  					
  					this.image = value; 
  					this.image_index = -1;
  					this.image_key = string.Empty;
  					this.CalculateAutoSize (); 
  					this.Invalidate ();
  					
  					BeginAnimation ();
  				}
  			}
  		}
  
  		[Localizable (true)]
  		[DefaultValue (ContentAlignment.MiddleCenter)]
  		public ContentAlignment ImageAlign {
  			get { return this.image_align; }
  			set {
  				if (!Enum.IsDefined (typeof (ContentAlignment), value))
  					throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ContentAlignment", value));
  
  				if (image_align != value) {
  					this.image_align = value;
  					this.CalculateAutoSize (); 
  				}
  			}
  		}
  
  		[Localizable (true)]
  		[Browsable (false)]
  		[RelatedImageList ("Owner.ImageList")]
  		[TypeConverter (typeof (NoneExcludedImageIndexConverter))]
  		[RefreshProperties (RefreshProperties.Repaint)]
  		[Editor ("System.Windows.Forms.Design.ToolStripImageIndexEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
  		public int ImageIndex {
  			get { return this.image_index; }
  			set {
  				if (this.image_index != value) {
  					// Lamespec: MSDN says ArgumentException, tests say otherwise
  					if (value < -1)
  						throw new ArgumentOutOfRangeException ("ImageIndex cannot be less than -1");
  
  					this.image_index = value;
  					this.image = null;
  					this.image_key = string.Empty;
  					this.CalculateAutoSize ();
  					this.Invalidate ();
  				}
  			}
  		}
  
  		[Localizable (true)]
  		[Browsable (false)]
  		[RelatedImageList ("Owner.ImageList")]
  		[TypeConverter (typeof (ImageKeyConverter))]
  		[RefreshProperties (RefreshProperties.Repaint)]
  		[Editor ("System.Windows.Forms.Design.ToolStripImageIndexEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
  		public string ImageKey {
  			get { return this.image_key; }
  			set { 
  				if (this.image_key != value) {
  					this.image = null;
  					this.image_index = -1;
  					this.image_key = value;
  					this.CalculateAutoSize ();
  					this.Invalidate ();
  				}
  			}
  		}
  		
  		[Localizable (true)]
  		[DefaultValue (ToolStripItemImageScaling.SizeToFit)]
  		public ToolStripItemImageScaling ImageScaling {
  			get { return this.image_scaling; }
  			set { 
  				if (image_scaling != value) {
  					this.image_scaling = value; 
  					this.CalculateAutoSize (); 
  				}
  			}
  		}
  
  		[Localizable (true)]
  		public Color ImageTransparentColor {
  			get { return this.image_transparent_color; }
  			set { this.image_transparent_color = value; }
  		}
  		
  		[Browsable (false)]
  		public bool IsOnDropDown {
  			get {
  				if (this.parent != null && this.parent is ToolStripDropDown)
  					return true;
  
  				return false;
  			}
  		}
  
  		[Browsable (false)]
  		public bool IsOnOverflow {
  			get { return this.placement == ToolStripItemPlacement.Overflow; }
  		}
  		
  		public Padding Margin {
  			get { return this.margin; }
  			set {
  				this.margin = value; 
  				this.CalculateAutoSize ();
  			}
  		}
  
  		[DefaultValue (MergeAction.Append)]
  		public MergeAction MergeAction {
  			get { return this.merge_action; }
  			set {
  				if (!Enum.IsDefined (typeof (MergeAction), value))
  					throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for MergeAction", value));
  					
  				this.merge_action = value;
  			}
  		}
  
  		[DefaultValue (-1)]
  		public int MergeIndex {
  			get { return this.merge_index; }
  			set { this.merge_index = value; }
  		}
  
  		[DefaultValue (null)]
  		[Browsable (false)]
  		public string Name {
  			get { return this.name; }
  			set { this.name = value; }
  		}
  
  		[DefaultValue (ToolStripItemOverflow.AsNeeded)]
  		public ToolStripItemOverflow Overflow {
  			get { return this.overflow; }
  			set { 
  				if (this.overflow != value) {
  					if (!Enum.IsDefined (typeof (ToolStripItemOverflow), value))
  						throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripItemOverflow", value));
  				
  					this.overflow = value;
  					
  					if (owner != null)
  						owner.PerformLayout ();
  				}
  			}
  		}
  			
  		[Browsable (false)]
  		[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  		public ToolStrip Owner {
  			get { return this.owner; }
  			set { 
  				if (this.owner != value) {
  					if (this.owner != null)
  						this.owner.Items.Remove (this);
  					
  					if (value != null)	
  						value.Items.Add (this);
  					else
  						this.owner = null;
  				}
  			}
  		}
  
  		[Browsable (false)]
  		[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  		public ToolStripItem OwnerItem {
  			get { return this.owner_item; }
  		}
  
  		public virtual Padding Padding {
  			get { return this.padding; }
  			set { 
  				this.padding = value; 
  				this.CalculateAutoSize (); 
  				this.Invalidate (); 
  			}
  		}
  
  		[Browsable (false)]
  		public ToolStripItemPlacement Placement {
  			get { return this.placement; }
  		}
  		
  		[Browsable (false)]
  		[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  		public virtual bool Pressed { get { return this.is_pressed; } }
  
  		[MonoTODO ("RTL not implemented")]
  		[Localizable (true)]
  		public virtual RightToLeft RightToLeft {
  			get { return this.right_to_left; }
  			set { 
  				if (this.right_to_left != value) {
  					this.right_to_left = value;
  					this.OnRightToLeftChanged (EventArgs.Empty);
  				}
  			}
  		}
  		
  		[Localizable (true)]
  		[DefaultValue (false)]
  		public bool RightToLeftAutoMirrorImage {
  			get { return this.right_to_left_auto_mirror_image; }
  			set { 
  				if (this.right_to_left_auto_mirror_image != value) {
  					this.right_to_left_auto_mirror_image = value;
  					this.Invalidate ();
  				}
  			}
  		}
  		
  		[Browsable (false)]
  		[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  		public virtual bool Selected { get { return this.is_selected; } }
  
  		[Localizable (true)]
  		public virtual Size Size {
  			get { 
  				if (!this.AutoSize && this.explicit_size != Size.Empty) 
  					return this.explicit_size; 
  					
  				return this.bounds.Size; 
  			}
  			set { 
  				this.bounds.Size = value; 
  				this.explicit_size = value;
  				
  				if (this.Visible) {
  					this.CalculateAutoSize ();
  					this.OnBoundsChanged (); 
  				}
  			}
  		}
  
  		[Localizable (false)]
  		[Bindable (true)]
  		[DefaultValue (null)]
  		[TypeConverter (typeof (StringConverter))]
  		public Object Tag {
  			get { return this.tag; }
  			set { this.tag = value; }
  		}
  
  		[Localizable (true)]
  		[DefaultValue ("")]
  		public virtual string Text
  		{
  			get { return this.text; }
  			set { 
  				if (this.text != value) { 
  					this.text = value; 
  					this.Invalidate (); 
  					this.CalculateAutoSize (); 
  					this.Invalidate ();
  					this.OnTextChanged (EventArgs.Empty); 
  				} 
  			}
  		}
  
  		[Localizable (true)]
  		[DefaultValue (ContentAlignment.MiddleCenter)]
  		public virtual ContentAlignment TextAlign {
  			get { return this.text_align; }
  			set {
  				if (!Enum.IsDefined (typeof (ContentAlignment), value))
  					throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ContentAlignment", value));
  
  				if (this.text_align != value) {
  					this.text_align = value;
  					this.CalculateAutoSize (); 
  				}
  			}
  		}
  
  		public virtual ToolStripTextDirection TextDirection {
  			get {
  				if (this.text_direction == ToolStripTextDirection.Inherit) {
  					if (this.Parent != null)
  						return this.Parent.TextDirection;
  					else
  						return ToolStripTextDirection.Horizontal;
  				}
  
  				return this.text_direction;
  			}
  			set {
  				if (!Enum.IsDefined (typeof (ToolStripTextDirection), value))
  					throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripTextDirection", value));
  				
  				if (this.text_direction != value) {
  					this.text_direction = value;
  					this.CalculateAutoSize ();
  					this.Invalidate ();
  				}
  			}	
  		}
  
  		[Localizable (true)]
  		[DefaultValue (TextImageRelation.ImageBeforeText)]
  		public TextImageRelation TextImageRelation {
  			get { return this.text_image_relation; }
  			set { 
  				this.text_image_relation = value; 
  				this.CalculateAutoSize (); 
  				this.Invalidate (); 
  			}
  		}
  
  		[Localizable (true)]
  		[Editor ("System.ComponentModel.Design.MultilineStringEditor, " + Consts.AssemblySystem_Design,
  			 "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
  		public string ToolTipText {
  			get { return this.tool_tip_text; }
  			set { this.tool_tip_text = value; }
  		}
  
  		[Localizable (true)]
  		public bool Visible {
  			get { 
  				if (this.parent == null)
  					return false;
  			
  				return this.visible && this.parent.Visible; 
  			}
  			set { 
  				if (this.visible != value) {
  					this.available = value;
  					this.SetVisibleCore (value);
  					if (this.Owner != null)
  						this.Owner.PerformLayout ();
  				}
  			}
  		}
  
  		[Browsable (false)]
  		[EditorBrowsable (EditorBrowsableState.Always)]
  		[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  		public int Width {
  			get { return this.Size.Width; }
  			set { 
  				this.Size = new Size (value, this.Size.Height); 
  				this.explicit_size.Width = value;
  				
  				if (this.Visible) {
  					this.CalculateAutoSize ();
  					this.OnBoundsChanged ();
  					this.Invalidate ();
  				}
  			}
  		}
  		#endregion
  
  		#region Protected Properties
  		protected virtual bool DefaultAutoToolTip { get { return false; } }
  		protected virtual ToolStripItemDisplayStyle DefaultDisplayStyle { get { return ToolStripItemDisplayStyle.ImageAndText; } }
  		protected internal virtual Padding DefaultMargin { get { return new Padding (0, 1, 0, 2); } }
  		protected virtual Padding DefaultPadding { get { return new Padding (); } }
  		protected virtual Size DefaultSize { get { return new Size (23, 23); } }
  		protected internal virtual bool DismissWhenClicked { get { return true; } }
  		[Browsable (false)]
  		[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  		protected internal ToolStrip Parent {
  			get { return this.parent; }
  			set { 
  				if (this.parent != value) {
  					ToolStrip old_parent = this.parent;
  					this.parent = value; 
  					OnParentChanged(old_parent, this.parent);
  				}
  			}
  		}
  		protected internal virtual bool ShowKeyboardCues { get { return false; } }
  		#endregion
  
  		#region Public Methods
  		[MonoTODO ("Stub, does nothing")]
  		[EditorBrowsable (EditorBrowsableState.Advanced)]
  		public DragDropEffects DoDragDrop (Object data, DragDropEffects allowedEffects)
  		{
  			return allowedEffects;
  		}
  		
  		public ToolStrip GetCurrentParent ()
  		{ 
  			return this.parent; 
  		}
  
  		public virtual Size GetPreferredSize (Size constrainingSize)
  		{
  			return this.CalculatePreferredSize (constrainingSize);
  		}
  
  		public void Invalidate ()
  		{
  			if (parent != null)
  				parent.Invalidate (this.bounds);
  		}
  
  		public void Invalidate (Rectangle r)
  		{
  			if (parent != null)
  				parent.Invalidate (r);
  		}
  
  		public void PerformClick ()
  		{ 
  			this.OnClick (EventArgs.Empty); 
  		}
  
  		[EditorBrowsable (EditorBrowsableState.Never)]
  		public virtual void ResetBackColor () { this.BackColor = Color.Empty; }
  
  		[EditorBrowsable (EditorBrowsableState.Never)]
  		public virtual void ResetDisplayStyle () { this.display_style = this.DefaultDisplayStyle; }
  
  		[EditorBrowsable (EditorBrowsableState.Never)]
  		public virtual void ResetFont () { this.font = null; }
  
  		[EditorBrowsable (EditorBrowsableState.Never)]
  		public virtual void ResetForeColor () { this.ForeColor = Color.Empty; }
  
  		[EditorBrowsable (EditorBrowsableState.Never)]
  		public virtual void ResetImage () { this.image = null; }
  
  		[EditorBrowsable (EditorBrowsableState.Never)]
  		public void ResetMargin () { this.margin = this.DefaultMargin; }
  
  		[EditorBrowsable (EditorBrowsableState.Never)]
  		public void ResetPadding () { this.padding = this.DefaultPadding; }
  
  		[EditorBrowsable (EditorBrowsableState.Never)]
  		public virtual void ResetRightToLeft () { this.right_to_left = RightToLeft.Inherit; }
  		
  		[EditorBrowsable (EditorBrowsableState.Never)]
  		public virtual void ResetTextDirection () { this.TextDirection = this.DefaultTextDirection; }
  
  		public void Select ()
  		{
  			if (!this.is_selected && this.CanSelect) {
  				this.is_selected = true;
  				
  				if (this.Parent != null) {
  					if (this.Visible && this.Parent.Focused && this is ToolStripControlHost)
  						(this as ToolStripControlHost).Focus ();
  						
  					this.Invalidate ();
  					this.Parent.NotifySelectedChanged (this);
  				}
  				OnUIASelectionChanged ();
  			}
  		}
  
  		public override string ToString ()
  		{
  			return this.text;
  		}
  		#endregion
  
  		#region Protected Methods
  		[EditorBrowsable (EditorBrowsableState.Advanced)]
  		protected virtual AccessibleObject CreateAccessibilityInstance ()
  		{
  			return new ToolStripItemAccessibleObject (this);
  		}
  
  		protected override void Dispose (bool disposing)
  		{
  			if (!is_disposed && disposing)
  				is_disposed = true;
  
  			if (image != null) {
  				StopAnimation ();
  				image = null;
  			}
  
  			if (owner != null && disposing)
  				owner.Items.Remove (this);
  			
  			base.Dispose (disposing);
  		}
  		
  		protected internal virtual bool IsInputChar (char charCode)
  		{
  			return false;
  		}
  		
  		protected internal virtual bool IsInputKey (Keys keyData)
  		{
  			return false;
  		}
  		
  		protected virtual void OnAvailableChanged (EventArgs e)
  		{
  			EventHandler eh = (EventHandler)(Events [AvailableChangedEvent]);
  			if (eh != null)
  				eh (this, e);
  		}
  
  		[EditorBrowsable (EditorBrowsableState.Advanced)]
  		protected virtual void OnBackColorChanged (EventArgs e)
  		{
  			EventHandler eh = (EventHandler)(Events [BackColorChangedEvent]);
  			if (eh != null)
  				eh (this, e);
  		}
  
  		protected virtual void OnBoundsChanged ()
  		{
  			OnLayout (new LayoutEventArgs(null, string.Empty));
  		}
  
  		protected virtual void OnClick (EventArgs e)
  		{
  			EventHandler eh = (EventHandler)(Events [ClickEvent]);
  			if (eh != null)
  				eh (this, e);
  		}
  
  		[EditorBrowsable (EditorBrowsableState.Advanced)]
  		protected virtual void OnDisplayStyleChanged (EventArgs e)
  		{
  			EventHandler eh = (EventHandler)(Events [DisplayStyleChangedEvent]);
  			if (eh != null)
  				eh (this, e);
  		}
  
  		protected virtual void OnDoubleClick (EventArgs e)
  		{
  			EventHandler eh = (EventHandler)(Events [DoubleClickEvent]);
  			if (eh != null)
  				eh (this, e);
  		}
  
  		[EditorBrowsable (EditorBrowsableState.Advanced)]
  		protected virtual void OnDragDrop (DragEventArgs dragEvent)
  		{
  			DragEventHandler eh = (DragEventHandler)(Events[DragDropEvent]);
  			if (eh != null)
  				eh (this, dragEvent);
  		}
  
  		[EditorBrowsable (EditorBrowsableState.Advanced)]
  		protected virtual void OnDragEnter (DragEventArgs dragEvent)
  		{
  			DragEventHandler eh = (DragEventHandler)(Events[DragEnterEvent]);
  			if (eh != null)
  				eh (this, dragEvent);
  		}
  
  		[EditorBrowsable (EditorBrowsableState.Advanced)]
  		protected virtual void OnDragLeave (EventArgs e)
  		{
  			EventHandler eh = (EventHandler)(Events[DragLeaveEvent]);
  			if (eh != null)
  				eh (this, e);
  		}
  
  		[EditorBrowsable (EditorBrowsableState.Advanced)]
  		protected virtual void OnDragOver (DragEventArgs dragEvent)
  		{
  			DragEventHandler eh = (DragEventHandler)(Events[DragOverEvent]);
  			if (eh != null)
  				eh (this, dragEvent);
  		}
  
  		protected virtual void OnEnabledChanged (EventArgs e)
  		{
  			EventHandler eh = (EventHandler)(Events [EnabledChangedEvent]);
  			if (eh != null)
  				eh (this, e);
  		}
  
  		[EditorBrowsable (EditorBrowsableState.Advanced)]
  		protected virtual void OnFontChanged (EventArgs e)
  		{
  		}
  
  		[EditorBrowsable (EditorBrowsableState.Advanced)]
  		protected virtual void OnForeColorChanged (EventArgs e)
  		{
  			EventHandler eh = (EventHandler)(Events [ForeColorChangedEvent]);
  			if (eh != null)
  				eh (this, e);
  		}
  
  		[EditorBrowsable (EditorBrowsableState.Advanced)]
  		protected virtual void OnGiveFeedback (GiveFeedbackEventArgs giveFeedbackEvent)
  		{
  			GiveFeedbackEventHandler eh = (GiveFeedbackEventHandler)(Events[GiveFeedbackEvent]);
  			if (eh != null)
  				eh (this, giveFeedbackEvent);
  		}
  
  		protected virtual void OnLayout (LayoutEventArgs e)
  		{
  		}
  
  		protected virtual void OnLocationChanged (EventArgs e)
  		{
  			EventHandler eh = (EventHandler)(Events [LocationChangedEvent]);
  			if (eh != null)
  				eh (this, e);
  		}
  
  		protected virtual void OnMouseDown (MouseEventArgs e)
  		{
  			if (this.Enabled) {
  				this.is_pressed = true;
  				this.Invalidate ();
  
  				MouseEventHandler eh = (MouseEventHandler)(Events [MouseDownEvent]);
  				if (eh != null)
  					eh (this, e);
  			}
  		}
  
  		protected virtual void OnMouseEnter (EventArgs e)
  		{
  			this.Select ();
  
  			EventHandler eh = (EventHandler)(Events [MouseEnterEvent]);
  			if (eh != null)
  				eh (this, e);
  		}
  
  		protected virtual void OnMouseHover (EventArgs e)
  		{
  			if (this.Enabled) {
  				EventHandler eh = (EventHandler)(Events [MouseHoverEvent]);
  				if (eh != null)
  					eh (this, e);
  			}
  		}
  
  		protected virtual void OnMouseLeave (EventArgs e)
  		{
  			if (this.CanSelect) {
  				this.is_selected = false;
  				this.is_pressed = false;
  				this.Invalidate ();
  				OnUIASelectionChanged ();
  			}
  
  			EventHandler eh = (EventHandler)(Events [MouseLeaveEvent]);
  			if (eh != null)
  				eh (this, e);
  		}
  
  		protected virtual void OnMouseMove (MouseEventArgs mea)
  		{
  			if (this.Enabled) {
  				MouseEventHandler eh = (MouseEventHandler)(Events [MouseMoveEvent]);
  				if (eh != null)
  					eh (this, mea);
  			}
  		}
  
  		protected virtual void OnMouseUp (MouseEventArgs e)
  		{
  			if (this.Enabled) {
  				this.is_pressed = false;
  				this.Invalidate ();
  
  				if (this.IsOnDropDown)
  					if (!(this is ToolStripDropDownItem) || !(this as ToolStripDropDownItem).HasDropDownItems || (this as ToolStripDropDownItem).DropDown.Visible == false) {
  						if ((this.Parent as ToolStripDropDown).OwnerItem != null)
  							((this.Parent as ToolStripDropDown).OwnerItem as ToolStripDropDownItem).HideDropDown ();
  						else
  							(this.Parent as ToolStripDropDown).Hide ();
  					}
  						
  				
  				MouseEventHandler eh = (MouseEventHandler)(Events [MouseUpEvent]);
  				if (eh != null)
  					eh (this, e);
  			}
  		}
  
  		protected virtual void OnOwnerChanged (EventArgs e)
  		{
  			EventHandler eh = (EventHandler)(Events [OwnerChangedEvent]);
  			if (eh != null)
  				eh (this, e);
  		}
  
  		[EditorBrowsable (EditorBrowsableState.Advanced)]
  		protected internal virtual void OnOwnerFontChanged (EventArgs e)
  		{
  			this.CalculateAutoSize ();
  			OnFontChanged (EventArgs.Empty);
  		}
  
  		void OnPaintInternal (PaintEventArgs e)
  		{
  			// Have the background rendered independently from OnPaint
  			if (this.parent != null)
  				this.parent.Renderer.DrawItemBackground (new ToolStripItemRenderEventArgs (e.Graphics, this));
  
  			OnPaint (e);
  		}
  
  		protected virtual void OnPaint (PaintEventArgs e)
  		{
  			PaintEventHandler eh = (PaintEventHandler)(Events [PaintEvent]);
  			if (eh != null)
  				eh (this, e);
  		}
  
  		// This is never called.
  		[EditorBrowsable (EditorBrowsableState.Advanced)]
  		protected virtual void OnParentBackColorChanged (EventArgs e)
  		{
  		}
  		
  		protected virtual void OnParentChanged (ToolStrip oldParent, ToolStrip newParent)
  		{
  			this.text_size = TextRenderer.MeasureText (this.Text == null ? string.Empty : this.text, this.Font, Size.Empty, TextFormatFlags.HidePrefix);
  			
  			if (oldParent != null)
  				oldParent.PerformLayout ();
  				
  			if (newParent != null)
  				newParent.PerformLayout ();
  		}
  
  		protected internal virtual void OnParentEnabledChanged (EventArgs e)
  		{
  			this.OnEnabledChanged (e);
  		}
  
  		// This is never called.
  		[EditorBrowsable (EditorBrowsableState.Advanced)]
  		protected virtual void OnParentForeColorChanged (EventArgs e)
  		{
  		}
  
  		[EditorBrowsable (EditorBrowsableState.Advanced)]
  		protected internal virtual void OnParentRightToLeftChanged (EventArgs e)
  		{
  			this.OnRightToLeftChanged (e);
  		}
  
  		[EditorBrowsable (EditorBrowsableState.Advanced)]
  		protected virtual void OnQueryContinueDrag (QueryContinueDragEventArgs queryContinueDragEvent)
  		{
  			QueryContinueDragEventHandler eh = (QueryContinueDragEventHandler)(Events[QueryContinueDragEvent]);
  			if (eh != null)
  				eh (this, queryContinueDragEvent);
  		}
  		
  		protected virtual void OnRightToLeftChanged (EventArgs e)
  		{
  			EventHandler eh = (EventHandler)(Events[RightToLeftChangedEvent]);
  			if (eh != null)
  				eh (this, e);
  		}
  		
  		[EditorBrowsable (EditorBrowsableState.Advanced)]
  		protected virtual void OnTextChanged (EventArgs e)
  		{
  			EventHandler eh = (EventHandler)(Events [TextChangedEvent]);
  			if (eh != null)
  				eh (this, e);
  		}
  
  		protected virtual void OnVisibleChanged (EventArgs e)
  		{
  			EventHandler eh = (EventHandler)(Events [VisibleChangedEvent]);
  			if (eh != null)
  				eh (this, e);
  		}
  
  		protected internal virtual bool ProcessCmdKey (ref Message m, Keys keyData)
  		{
  			return false;
  		}
  		
  		protected internal virtual bool ProcessDialogKey (Keys keyData)
  		{
  			if (this.Selected && keyData == Keys.Enter) {
  				this.FireEvent (EventArgs.Empty, ToolStripItemEventType.Click);
  				return true;
  			}
  				
  			return false;
  		}
  		
  		// ProcessMnemonic will only be called if we are supposed to handle
  		// it.  None of that fancy "thinking" needed!
  		protected internal virtual bool ProcessMnemonic (char charCode)
  		{
  			ToolStripManager.SetActiveToolStrip (this.Parent, true);
  			this.PerformClick ();
  			return true;
  		}
  		
  		protected internal virtual void SetBounds (Rectangle bounds)
  		{
  			if (this.bounds != bounds) {
  				this.bounds = bounds;
  				OnBoundsChanged ();
  			}
  		}
  		
  		protected virtual void SetVisibleCore (bool visible)
  		{
  			this.visible = visible;
  			this.OnVisibleChanged (EventArgs.Empty);
  			
  			if (this.visible)
  				BeginAnimation ();
  			else
  				StopAnimation ();
  			this.Invalidate ();
  		}
  		#endregion
  
  		#region Public Events
  		static object AvailableChangedEvent = new object ();
  		static object BackColorChangedEvent = new object ();
  		static object ClickEvent = new object ();
  		static object DisplayStyleChangedEvent = new object ();
  		static object DoubleClickEvent = new object ();
  		static object DragDropEvent = new object ();
  		static object DragEnterEvent = new object ();
  		static object DragLeaveEvent = new object ();
  		static object DragOverEvent = new object ();
  		static object EnabledChangedEvent = new object ();
  		static object ForeColorChangedEvent = new object ();
  		static object GiveFeedbackEvent = new object ();
  		static object LocationChangedEvent = new object ();
  		static object MouseDownEvent = new object ();
  		static object MouseEnterEvent = new object ();
  		static object MouseHoverEvent = new object ();
  		static object MouseLeaveEvent = new object ();
  		static object MouseMoveEvent = new object ();
  		static object MouseUpEvent = new object ();
  		static object OwnerChangedEvent = new object ();
  		static object PaintEvent = new object ();
  		static object QueryAccessibilityHelpEvent = new object ();
  		static object QueryContinueDragEvent = new object ();
  		static object RightToLeftChangedEvent = new object ();
  		static object TextChangedEvent = new object ();
  		static object VisibleChangedEvent = new object ();
  
  		[Browsable (false)]
  		public event EventHandler AvailableChanged {
  			add { Events.AddHandler (AvailableChangedEvent, value); }
  			remove {Events.RemoveHandler (AvailableChangedEvent, value); }
  		}
  
  		public event EventHandler BackColorChanged {
  			add { Events.AddHandler (BackColorChangedEvent, value); }
  			remove {Events.RemoveHandler (BackColorChangedEvent, value); }
  		}
  
  		public event EventHandler Click {
  			add { Events.AddHandler (ClickEvent, value); }
  			remove {Events.RemoveHandler (ClickEvent, value); }
  		}
  
  		public event EventHandler DisplayStyleChanged {
  			add { Events.AddHandler (DisplayStyleChangedEvent, value); }
  			remove {Events.RemoveHandler (DisplayStyleChangedEvent, value); }
  		}
  
  		public event EventHandler DoubleClick {
  			add { Events.AddHandler (DoubleClickEvent, value); }
  			remove {Events.RemoveHandler (DoubleClickEvent, value); }
  		}
  
  		[MonoTODO ("Event never raised")]
  		[Browsable (false)]
  		[EditorBrowsable (EditorBrowsableState.Advanced)]
  		public event DragEventHandler DragDrop {
  
gt: 			add { Events.AddHandler (DragDropEvent, value); }