using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using DevComponents.DotNetBar.Events;
using System.Collections;
using DevComponents.DotNetBar.Rendering;
namespace DevComponents.DotNetBar
{
    /// 
    /// Defines Radial Menu control.
    /// 
    [ToolboxItem(true), DefaultEvent("ItemClick"), System.Runtime.InteropServices.ComVisible(false), Designer("DevComponents.DotNetBar.Design.RadialMenuDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral,  PublicKeyToken=90f470f34c89ccaf"), ToolboxBitmap(typeof(ToolboxIconResFinder), "RadialMenu.ico")]
    public class RadialMenu : Control, IMessageHandlerClient, IOwner, IOwnerItemEvents
    {
        #region Constructor
        private RadialMenuContainer _MenuContainer = null;
        /// 
        /// Initializes a new instance of the RadialMenu class.
        /// 
        public RadialMenu()
        {
            _MenuContainer = new RadialMenuContainer();
            _MenuContainer.RadialMenu = this;
            _MenuContainer.Opened += new EventHandler(RadialMenuOpened);
            _MenuContainer.Closed += new EventHandler(RadialMenuClosed);
            this.SetStyle(
                ControlStyles.UserPaint |
                ControlStyles.AllPaintingInWmPaint |
                ControlStyles.Opaque |
                ControlStyles.ResizeRedraw |
                DisplayHelp.DoubleBufferFlag |
                ControlStyles.SupportsTransparentBackColor, true);
            _MenuContainer.SetOwner(this);
        }
        protected override void Dispose(bool disposing)
        {
            _MenuContainer.Dispose();
            base.Dispose(disposing);
        }
        private bool _AccessibleObjectCreated = false;
        protected override AccessibleObject CreateAccessibilityInstance()
        {
            _AccessibleObjectCreated = true;
            return new RadialMenuAccessibleObject(this);
        }
        #endregion
        #region Events
        /// 
        /// Occurs before menu is closed and allows you to cancel closing.
        /// 
        [Description("Occurs before menu is closed and allows you to cancel closing.")]
        public event CancelableEventSourceHandler BeforeMenuClose;
        /// 
        /// Raises BeforeMenuClose event.
        /// 
        /// Provides event arguments.
        protected virtual void OnBeforeMenuClose(CancelableEventSourceArgs e)
        {
            CancelableEventSourceHandler handler = BeforeMenuClose;
            if (handler != null)
                handler(this, e);
        }
        /// 
        /// Occurs before menu has been opened and allows you to cancel opening
        /// 
        [Description("Occurs before menu has been opened and allows you to cancel opening.")]
        public event CancelableEventSourceHandler BeforeMenuOpen;
        /// 
        /// Raises BeforeMenuOpen event.
        /// 
        /// Provides event arguments.
        protected virtual void OnBeforeMenuOpen(CancelableEventSourceArgs e)
        {
            CancelableEventSourceHandler handler = BeforeMenuOpen;
            if (handler != null)
                handler(this, e);
        }
        /// 
        /// Occurs after menu has been opened.
        /// 
        [Description("Occurs after menu has been opened.")]
        public event EventHandler MenuOpened;
        /// 
        /// Raises MenuOpened event.
        /// 
        /// Provides event arguments.
        protected virtual void OnMenuOpened(EventArgs e)
        {
            EventHandler handler = MenuOpened;
            if (handler != null)
                handler(this, e);
        }
        /// 
        /// Occurs after menu is closed.Occurs after menu is closed.
        /// 
        [Description("Occurs after menu is closed.")]
        public event EventHandler MenuClosed;
        /// 
        /// Raises MenuClosed event.
        /// 
        /// Provides event arguments.
        protected virtual void OnMenuClosed(EventArgs e)
        {
            EventHandler handler = MenuClosed;
            if (handler != null)
                handler(this, e);
        }
        #endregion
        #region Implementation
        /// 
        /// Specifies the width of the sub-menu edge around the radial menu.
        /// 
        [DefaultValue(18), Category("Appearance"), Description("Specifies the width of the sub-menu edge around the radial menu.")]
        public int SubMenuEdgeWidth
        {
            get { return _MenuContainer.SubMenuEdgeWidth; }
            set { _MenuContainer.SubMenuEdgeWidth = value; }
        }
        /// 
        /// Indicates spacing between sub-menu marking edge and the item.
        /// 
        [DefaultValue(3), Category("Appearance"), Description("Indicates spacing between sub-menu marking edge and the item.")]
        public int SubMenuEdgeItemSpacing
        {
            get { return _MenuContainer.SubMenuEdgeItemSpacing; }
            set { _MenuContainer.SubMenuEdgeItemSpacing = value; }
        }
        /// 
        /// Gets or sets radial menu diameter. Minimum value is 64.
        /// 
        [DefaultValue(180), Category("Appearance"), Description("Radial menu diameter.")]
        public int Diameter
        {
            get { return _MenuContainer.Diameter; }
            set { _MenuContainer.Diameter = value; }
        }
        /// 
        /// Gets reference to colors used by the radial menu.
        /// 
        [Category("Appearance"), Description("Gets reference to colors used by the radial menu."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public RadialMenuColorTable Colors
        {
            get
            {
                return _MenuContainer.Colors;
            }
        }
        /// 
        /// Indicates the size of the back symbol that is displayed on center of radial menu
        /// 
        [DefaultValue(18), Browsable(false), Description("Indicates the size of the back symbol that is displayed on center of radial menu")]
        public int BackButtonSymbolSize
        {
            get { return _MenuContainer.BackButtonSymbolSize; }
            set { _MenuContainer.BackButtonSymbolSize = value; }
        }
        /// 
        /// Specifies the back button symbol.
        /// 
        [DefaultValue("\uf060"), Category("Appearance"), Description("Specifies the back button symbol.")]
        [Editor("DevComponents.DotNetBar.Design.SymbolTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral,  PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor))]
        public string BackButtonSymbol
        {
            get { return _MenuContainer.BackButtonSymbol; }
            set { _MenuContainer.BackButtonSymbol = value; }
        }
        /// 
        /// Gets or sets the symbol set used to represent the Symbol.
        /// 
        [Browsable(false), DefaultValue(eSymbolSet.Awesome)]
        public eSymbolSet BackButtonSymbolSet
        {
            get { return _MenuContainer.BackButtonSymbolSet; }
            set
            {
                _MenuContainer.BackButtonSymbolSet = value;
            }
        }
        /// 
        /// Indicates diameter of center button of radial menu.
        /// 
        [DefaultValue(32), Category("Appearance"), Description("Indicates diameter of center button of radial menu.")]
        public int CenterButtonDiameter
        {
            get { return _MenuContainer.CenterButtonDiameter; }
            set { _MenuContainer.CenterButtonDiameter = value; }
        }
        /// 
        /// Specifies the maximum pie part angle an item will occupy. Maximum is 180, minimum is 1 degree.
        /// 
        [DefaultValue(90), Category("Appearance"), Description("Specifies the maximum pie part angle an item will occupy. Maximum is 180, minimum is 1 degree.")]
        public int MaxItemPieAngle
        {
            get { return _MenuContainer.MaxItemPieAngle; }
            set { _MenuContainer.MaxItemPieAngle = value; }
        }
        /// 
        /// Indicates maximum radial angle single item in menu can consume. By default this property is set to zero which indicates that
        /// radial menu is equally divided between visible menu items.
        /// 
        [DefaultValue(0), Category("Appearance"), Description("Indicates maximum radial angle single item in menu can consume. Max value is 180.")]
        public int MaxItemRadialAngle
        {
            get { return _MenuContainer.MaxItemRadialAngle; }
            set { _MenuContainer.MaxItemRadialAngle = value; }
        }
        /// 
        /// Indicates the position of top-left corner of radial menu when shown in screen coordinates
        /// 
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Category("Behavior"), Description("Indicates the position of top-left corner of radial menu when shown in screen coordinates")]
        public Point MenuLocation
        {
            get { return _MenuContainer.MenuLocation; }
            set { _MenuContainer.MenuLocation = value; }
        }
        /// 
        /// Gets or sets whether radial menu is open.
        /// 
        //[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        //public bool IsMenuOpen
        //{
        //    get
        //    {
        //        return _MenuContainer.Expanded;
        //    }
        //    set
        //    {
        //        if (_MenuContainer.Expanded != value)
        //            _MenuContainer.Expanded = value;
        //    }
        //}
        private Image _Image = null;
        /// 
        /// Indicates image displayed in center of the radial menu.
        /// 
        [DefaultValue(null), Description("Indicates image displayed in center of the radial menu."), Category("Appearance")]
        public Image Image
        {
            get { return _Image; }
            set
            {
                if (value != _Image)
                {
                    Image oldValue = _Image;
                    _Image = value;
                    OnImageChanged(oldValue, value);
                }
            }
        }
        /// 
        /// Called when Image property has changed.
        /// 
        /// Old property value
        /// New property value
        protected virtual void OnImageChanged(Image oldValue, Image newValue)
        {
            //OnPropertyChanged(new PropertyChangedEventArgs("Image"));
            this.Invalidate();
        }
        /// 
        /// Indicates symbol displayed in center of the radial menu. When set, it overrides any Image settings.
        /// 
        [DefaultValue(""), Description("Indicates image displayed in center of the radial menu.  When set, it overrides any Image settings."), Category("Appearance")]
        [Editor("DevComponents.DotNetBar.Design.SymbolTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral,  PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor))]
        public string Symbol
        {
            get { return _MenuContainer.Symbol; }
            set { _MenuContainer.Symbol = value; _SymbolTextSize = Size.Empty; this.Invalidate(); }
        }
        /// 
        /// Gets or sets the symbol set used to represent the Symbol.
        /// 
        [Browsable(false), DefaultValue(eSymbolSet.Awesome)]
        public eSymbolSet SymbolSet
        {
            get { return _MenuContainer.SymbolSet; }
            set
            {
                _MenuContainer.SymbolSet = value;
            }
        }
        /// 
        /// Indicates the size of the symbol in points.
        /// 
        [DefaultValue(0f), Category("Appearance"), Description("Indicates the size of the symbol in points.")]
        public float SymbolSize
        {
            get { return _MenuContainer.SymbolSize; }
            set { _MenuContainer.SymbolSize = value; _SymbolTextSize = Size.Empty; this.Invalidate(); }
        }
        private bool _IsOpen;
        /// 
        /// Gets or sets whether radial menu is open.
        /// 
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public bool IsOpen
        {
            get { return _IsOpen; }
            set
            {
                if (value != _IsOpen)
                {
                    SetIsOpen(value, eEventSource.Code);
                }
            }
        }
        /// 
        /// Called when IsOpen property has changed.
        /// 
        /// Old property value
        /// New property value
        protected virtual void OnIsOpenChanged(bool oldValue, bool newValue)
        {
            //OnPropertyChanged(new PropertyChangedEventArgs("IsOpen"));
        }
        /// 
        /// Sets whether radial menu is open and provides the source of the action.
        /// 
        /// true to open menu, false to close it.
        /// Source of the action.
        public void SetIsOpen(bool isOpen, eEventSource source)
        {
            if (isOpen == _IsOpen) return;
            if (isOpen)
            {
                CancelableEventSourceArgs cancel = new CancelableEventSourceArgs(source);
                OnBeforeMenuOpen(cancel);
                if (cancel.Cancel) return;
            }
            else
            {
                CancelableEventSourceArgs cancel = new CancelableEventSourceArgs(source);
                OnBeforeMenuClose(cancel);
                if (cancel.Cancel) return;
            }
            bool oldValue = _IsOpen;
            _IsOpen = isOpen;
            _MenuContainer.Expanded = isOpen;
            OnIsOpenChanged(oldValue, isOpen);
        }
        /// 
        /// Returns collection of items on a bar.
        /// 
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Browsable(false)]
        public SubItemsCollection Items
        {
            get
            {
                return _MenuContainer.SubItems;
            }
        }
        protected override void OnClick(EventArgs e)
        {
            SetIsOpen(!this.IsOpen, eEventSource.Mouse);
            base.OnClick(e);
        }
        private Size _SymbolTextSize = Size.Empty;
        private bool _Painting = false;
        protected override void OnPaint(PaintEventArgs e)
        {
            if (_Painting) return; // Stops painting when using transparent backgrounds since paint on parent paints this control too
            _Painting = true;
            try
            {
                RadialMenuColorTable renderTable = RadialMenuContainer.GetColorTable();
                RadialMenuColorTable localTable = _MenuContainer.Colors;
                Color symbolColor = ColorScheme.GetColor(0x2B579A);
                Color backColor = Color.White;
                if (!localTable.RadialMenuButtonBorder.IsEmpty)
                    symbolColor = localTable.RadialMenuButtonBorder;
                else if (renderTable != null && !renderTable.RadialMenuButtonBorder.IsEmpty)
                    symbolColor = renderTable.RadialMenuButtonBorder;
                if (!localTable.RadialMenuButtonBackground.IsEmpty)
                    backColor = localTable.RadialMenuButtonBackground;
                else if (renderTable != null && !renderTable.RadialMenuButtonBackground.IsEmpty)
                    backColor = renderTable.RadialMenuButtonBackground;
                SolidBrush backBrush = new SolidBrush(backColor);
                Graphics g = e.Graphics;
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
                g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                Rectangle r = this.ClientRectangle;
                r.Inflate(1, 1);
                if (!this.BackColor.IsEmpty && this.BackColor != Color.Transparent)
                {
                    using (SolidBrush brush = new SolidBrush(this.BackColor))
                        g.FillRectangle(brush, r);
                }
                else if (this.BackColor == Color.Transparent)
                    PaintParentControlOnBackground(e.Graphics);
                r = this.ClientRectangle;
                r.Width--;
                r.Height--;
                Rectangle fill = r;
                fill.Inflate(-1, -1);
                g.FillEllipse(backBrush, fill);
                if (_SymbolBorderEnabled)
                {
                    using (GraphicsPath path = new GraphicsPath())
                    {
                        path.AddEllipse(r);
                        r.Inflate(-2, -2);
                        path.AddEllipse(r);
                        using (SolidBrush brush = new SolidBrush(symbolColor))
                            g.FillPath(brush, path);
                    }
                }
                if (!string.IsNullOrEmpty(_MenuContainer.SymbolRealized))
                {
                    float symbolSize = _MenuContainer.SymbolSize;
                    Font symFont = Symbols.GetFont(symbolSize, _MenuContainer.SymbolSet);
                    if (_SymbolTextSize.IsEmpty)
                    {
                        _SymbolTextSize = TextDrawing.MeasureStringLegacy(g, _MenuContainer.SymbolRealized, Symbols.GetFont(symbolSize, _MenuContainer.SymbolSet), Size.Empty, eTextFormat.Default);
                        int descent = (int)Math.Ceiling((symFont.FontFamily.GetCellDescent(symFont.Style) *
                        symFont.Size / symFont.FontFamily.GetEmHeight(symFont.Style)));
                        _SymbolTextSize.Height -= descent;
                    }
                    TextDrawing.DrawStringLegacy(g, _MenuContainer.SymbolRealized, Symbols.GetFont(symbolSize, _MenuContainer.SymbolSet),
                        symbolColor, new Rectangle(this.ClientRectangle.Width / 2, r.Y + (r.Height - _SymbolTextSize.Height) / 2, 0, 0),
                        eTextFormat.HorizontalCenter);
                }
                else if (_Image != null)
                {
                    r = this.ClientRectangle;
                    ImageHelper.DrawImageCenteredDpiAware(g, _Image, r);
                }
                backBrush.Dispose(); backBrush = null;
            }
            finally
            {
                _Painting = false;
            }
            base.OnPaint(e);
        }
        private void PaintParentControlOnBackground(Graphics g)
        {
            Control parent = this.Parent;
            if (parent != null)
            {
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
                g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                using (Bitmap bmp = new Bitmap(parent.Width, parent.Height, g))
                {
                    parent.DrawToBitmap(bmp, parent.ClientRectangle);
                    g.TranslateTransform(-Left, -Top);
                    g.DrawImage(bmp, Point.Empty);
                    g.TranslateTransform(Left, Top);
                }
            }
        }
        private bool _SymbolBorderEnabled = true;
        /// 
        /// Indicates whether border, a circle is rendered around the selected symbol which represents radial menu. Default value is true.
        /// 
        [DefaultValue(true), Category("Appearance"), Description("Indicates whether border, a circle is rendered around the selected symbol which represents radial menu.")]
        public bool SymbolBorderEnabled
        {
            get { return _SymbolBorderEnabled; }
            set { _SymbolBorderEnabled = value; this.Invalidate();}
        }
        protected override Size DefaultSize
        {
            get
            {
                return new Size(28, 28);
            }
        }
        public override System.Drawing.Size GetPreferredSize(System.Drawing.Size proposedSize)
        {
            if (proposedSize.Width <= 0) return new System.Drawing.Size(26, 26);
            return new System.Drawing.Size(proposedSize.Width, proposedSize.Height);
        }
        void RadialMenuClosed(object sender, EventArgs e)
        {
            _IsOpen = false;
            RaiseAccessibilityEvent(AccessibleEvents.SystemMenuPopupEnd);
            RaiseAccessibilityEvent(AccessibleEvents.SystemMenuEnd);
            OnMenuClosed(EventArgs.Empty);
        }
        private void RadialMenuOpened(object sender, EventArgs e)
        {
            RaiseAccessibilityEvent(AccessibleEvents.SystemMenuStart);
            RaiseAccessibilityEvent(AccessibleEvents.SystemMenuPopupStart);
            OnMenuOpened(EventArgs.Empty);
        }
        private void RaiseAccessibilityEvent(AccessibleEvents e)
        {
            if (!_AccessibleObjectCreated) return;
            RadialMenuAccessibleObject acc = (RadialMenuAccessibleObject)this.AccessibilityObject;
            acc.GenerateEvent(e);
        }
        private bool _ShortcutsEnabled = true;
        /// 
        /// Gets or sets whether shortcut processing for the items hosted by this control is enabled. Default value is true.
        /// 
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public bool ShortcutsEnabled
        {
            get { return _ShortcutsEnabled; }
            set { _ShortcutsEnabled = value; }
        }
        private bool _CloseMenuOnAppDeactivate = true;
        /// 
        /// Indicates whether radial menu is closed automatically when app is deactivated. Default value is true, if set to false
        /// you are responsible for closing the menu.
        /// 
        [DefaultValue(true), Category("Behavior"), Description("Indicates whether radial menu is closed automatically when app is deactivated"), Browsable(false)]
        public bool CloseMenuOnAppDeactivate
        {
            get { return _CloseMenuOnAppDeactivate; }
            set
            {
                _CloseMenuOnAppDeactivate = value;
            }
        }
        private bool _UseHook = false;
        /// 
        /// Gets or sets whether hooks are used for internal DotNetBar system functionality. Using hooks is recommended only if DotNetBar is used in hybrid environments like Visual Studio designers or IE.
        /// 
        [Browsable(false), DefaultValue(false), Category("Behavior"), Description("Gets or sets whether hooks are used for internal DotNetBar system functionality. Using hooks is recommended only if DotNetBar is used in hybrid environments like Visual Studio designers or IE.")]
        public bool UseHook
        {
            get
            {
                return _UseHook;
            }
            set
            {
                _UseHook = value;
            }
        }
        private bool _MenuEventSupport = false;
        private Hook _Hook = null;
        private bool _FilterInstalled = false;
        protected override void OnHandleCreated(EventArgs e)
        {
            if (!_FilterInstalled && !this.DesignMode)
            {
                MessageHandler.RegisterMessageClient(this);
                _FilterInstalled = true;
            }
            if (!this.GetDesignMode() && !_UseHook)
            {
                if (!_MenuEventSupport)
                    MenuEventSupportHook();
            }
            else
            {
                if (_Hook == null)
                {
                    _Hook = new Hook(this);
                }
            }
            UpdateScaleFactor();
            base.OnHandleCreated(e);
        }
        protected override void OnHandleDestroyed(EventArgs e)
        {
            MenuEventSupportUnhook();
            base.OnHandleDestroyed(e);
            if (_FilterInstalled)
            {
                MessageHandler.UnregisterMessageClient(this);
                _FilterInstalled = false;
            }
            if (_Hook != null)
            {
                _Hook.Dispose();
                _Hook = null;
            }
        }
        private void MenuEventSupportUnhook()
        {
            if (!_MenuEventSupport)
                return;
            _MenuEventSupport = false;
            Form parentForm = this.FindForm();
            if (parentForm == null)
                return;
            if (parentForm.IsMdiChild && parentForm.MdiParent != null)
                parentForm = parentForm.MdiParent;
            DotNetBarManager.UnRegisterParentMsgHandler(this, parentForm);
            parentForm.Resize -= new EventHandler(this.ParentResize);
            parentForm.Deactivate -= new EventHandler(this.ParentDeactivate);
        }
        /// 
        /// Indicates the radial menu type. eRadialMenuType.Segment menu type allows for display of image, text and any sub-menu items.
        /// eRadialMenuType.Circular allows only for display of Symbol or Image and it does not display either text or sub-menu items. 
        /// eRadialMenuType.Circular is designed to be used for single level menus only that don't need text.
        /// 
        [DefaultValue(eRadialMenuType.Segment), Category("Appearance"), Description("Indicates the radial menu type.")]
        public eRadialMenuType MenuType
        {
            get { return _MenuContainer.MenuType; }
            set { _MenuContainer.MenuType = value; }
        }
        private bool _AutoScale = true;
        /// 
        /// Indicates whether control automatically scales the items if the parent Form performs scaling due to AutoScale settings.
        /// 
        [DefaultValue(true), Category("Behavior"), Description("Indicates whether control automatically scales the items if the parent Form performs scaling due to AutoScale settings.")]
        public bool AutoScale
        {
            get { return _AutoScale; }
            set
            {
                _AutoScale = value;
                UpdateScaleFactor();
            }
        }
        private void UpdateScaleFactor()
        {
            if (!this.IsHandleCreated)
                return;
            if (_AutoScale)
            {
                using (Graphics g = this.CreateGraphics())
                {
                    SizeF factor = new SizeF(g.DpiX / 96, g.DpiY / 96);
                    if (factor.Width != 1f)
                        _MenuContainer.ScaleFactor = factor;
                }
            }
            else
                _MenuContainer.ScaleFactor = new SizeF(1, 1);
        }
        protected override void WndProc(ref Message m)
        {
            if (m.Msg == (int)WinApi.WindowsMessages.WM_DPICHANGED)
                UpdateScaleFactor();
            base.WndProc(ref m);
        }
        private string _AccessibleHelp = "";
        /// 
        /// Indicates accessibility help string
        /// 
        [DefaultValue(""), Category("Accessibility"), Description("Indicates accessibility help string")]
        public string AccessibleHelp
        {
            get { return _AccessibleHelp; }
            set
            {
                _AccessibleHelp = value;
            }
        }
        
        #endregion
        #region IMessageHandlerClient Implementation
        bool IMessageHandlerClient.IsModal
        {
            get
            {
                Form form = this.FindForm();
                if (form != null)
                    return form.Modal;
                return false;
            }
        }
        bool IMessageHandlerClient.OnMouseWheel(IntPtr hWnd, IntPtr wParam, IntPtr lParam)
        {
            return OnMouseWheel(hWnd, wParam, lParam);
        }
        protected virtual bool OnMouseWheel(IntPtr hWnd, IntPtr wParam, IntPtr lParam)
        {
            return false;
        }
        bool IMessageHandlerClient.OnKeyDown(IntPtr hWnd, IntPtr wParam, IntPtr lParam)
        {
            return OnKeyDown(hWnd, wParam, lParam);
        }
        /// 
        /// Returns whether control has any popups registered.
        /// 
        [EditorBrowsable(EditorBrowsableState.Never), Browsable(false)]
        public bool HasRegisteredPopups
        {
            get
            {
                return _MenuContainer.Expanded;
            }
        }
        #region OnKeyDown
        private bool _DesignModeInternal = false;
        protected bool GetDesignMode()
        {
            if (!_DesignModeInternal)
                return this.DesignMode;
            return _DesignModeInternal;
        }
        [EditorBrowsable(EditorBrowsableState.Never), Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public void SetDesignMode(bool mode)
        {
            _DesignModeInternal = mode;
            _MenuContainer.SetDesignMode(mode);
        }
        protected virtual bool OnKeyDown(IntPtr hWnd, IntPtr wParam, IntPtr lParam)
        {
            bool designMode = this.GetDesignMode();
            int wParamInt = WinApi.ToInt(wParam);
            if (_MenuContainer.Expanded && wParamInt == 27) // Escape
            {
                this.SetIsOpen(false, eEventSource.Keyboard);
                return true;
            }
            if (_MenuContainer.Expanded && _MenuContainer.Popup != null && _MenuContainer.Popup.Handle == hWnd)
            {
                Keys key = (Keys)NativeFunctions.MapVirtualKey((uint)wParam, 2);
                if (key == Keys.None)
                    key = (Keys)wParamInt;
                _MenuContainer.InternalKeyDown(new KeyEventArgs(key));
                return false;
            }
            if (!this.IsParentFormActive)
                return false;
            if (wParamInt >= 0x70 || ModifierKeys != Keys.None || (WinApi.ToInt(lParam) & 0x1000000000) != 0 || wParamInt == 0x2E || wParamInt == 0x2D) // 2E=VK_DELETE, 2D=VK_INSERT
            {
                int i = (int)ModifierKeys | wParamInt;
                return ProcessShortcut((eShortcut)i) && !designMode;
            }
            return false;
        }
        #endregion
        private bool _DispatchShortcuts = false;
        /// 
        /// Indicates whether shortcuts handled by items are dispatched to the next handler or control.
        /// 
        [Browsable(false), DefaultValue(false), Category("Behavior"), Description("Indicates whether shortucts handled by items are dispatched to the next handler or control.")]
        public bool DispatchShortcuts
        {
            get { return _DispatchShortcuts; }
            set { _DispatchShortcuts = value; }
        }
        private bool ProcessShortcut(eShortcut key)
        {
            if (!_ShortcutsEnabled || !this.Enabled) return false;
            Form form = this.FindForm();
            if (form == null || (form != Form.ActiveForm && form.MdiParent == null ||
                form.MdiParent != null && form.MdiParent.ActiveMdiChild != form) && !form.IsMdiContainer || Form.ActiveForm != null && Form.ActiveForm.Modal && Form.ActiveForm != form)
                return false;
            bool eat = BarFunctions.ProcessItemsShortcuts(key, _ShortcutTable);
            return !_DispatchShortcuts && eat;
        }
        protected bool IsParentFormActive
        {
            get
            {
                // Process only if parent form is active
                Form form = this.FindForm();
                if (form == null)
                    return false;
                if (form.IsMdiChild)
                {
                    if (form.MdiParent == null)
                        return false;
                    if (form.MdiParent.ActiveMdiChild != form)
                        return false;
                }
                else if (form != Form.ActiveForm)
                    return false;
                return true;
            }
        }
        private PopupDelayedClose m_DelayClose = null;
        private PopupDelayedClose GetDelayClose()
        {
            if (m_DelayClose == null)
                m_DelayClose = new PopupDelayedClose();
            return m_DelayClose;
        }
        [EditorBrowsable(EditorBrowsableState.Never)]
        public void DesignerNewItemAdded()
        {
            this.GetDelayClose().EraseDelayClose();
        }
        private ArrayList _RegisteredPopups = new ArrayList();
        protected virtual bool OnSysMouseDown(IntPtr hWnd, IntPtr wParam, IntPtr lParam)
        {
            if (!_IsOpen || this.GetDesignMode() || _MenuContainer.Popup == null)
                return false;
            if (!_MenuContainer.Popup.Bounds.Contains(MousePosition))
            {
                SetIsOpen(false, eEventSource.Mouse);
            }
            return false;
        }
        bool IMessageHandlerClient.OnMouseDown(IntPtr hWnd, IntPtr wParam, IntPtr lParam)
        {
            return OnSysMouseDown(hWnd, wParam, lParam);
        }
        bool IMessageHandlerClient.OnMouseMove(IntPtr hWnd, IntPtr wParam, IntPtr lParam)
        {
            if (_IsOpen && _MenuContainer.Popup != null && _MenuContainer.Popup.Handle != hWnd) return true; // Eat mouse messages for other windows while popup is open
            return false;
        }
        bool IMessageHandlerClient.OnSysKeyDown(IntPtr hWnd, IntPtr wParam, IntPtr lParam)
        {
            return OnSysKeyDown(hWnd, wParam, lParam);
        }
        protected virtual bool OnSysKeyDown(IntPtr hWnd, IntPtr wParam, IntPtr lParam)
        {
            if (!this.GetDesignMode())
            {
                int wParamInt = WinApi.ToInt(wParam);
                if (wParamInt == 18 && System.Windows.Forms.Control.ModifierKeys == System.Windows.Forms.Keys.Alt)
                    this.SetIsOpen(false, eEventSource.Keyboard);
                // Check Shortcuts
                if (ModifierKeys != Keys.None || wParamInt >= (int)eShortcut.F1 && wParamInt <= (int)eShortcut.F12)
                {
                    int i = (int)ModifierKeys | wParamInt;
                    if (ProcessShortcut((eShortcut)i))
                        return true;
                }
            }
            return false;
        }
        bool IMessageHandlerClient.OnSysKeyUp(IntPtr hWnd, IntPtr wParam, IntPtr lParam)
        {
            return OnSysKeyUp(hWnd, wParam, lParam);
        }
        protected virtual bool OnSysKeyUp(IntPtr hWnd, IntPtr wParam, IntPtr lParam)
        {
            return false;
        }
        private void MenuEventSupportHook()
        {
            if (_MenuEventSupport)
                return;
            _MenuEventSupport = true;
            Form parentForm = this.FindForm();
            if (parentForm == null)
            {
                _MenuEventSupport = false;
                return;
            }
            if (parentForm.IsMdiChild && parentForm.MdiParent != null)
                parentForm = parentForm.MdiParent;
            parentForm.Resize += new EventHandler(this.ParentResize);
            parentForm.Deactivate += new EventHandler(this.ParentDeactivate);
            DotNetBarManager.RegisterParentMsgHandler(this, parentForm);
        }
        private void ParentResize(object sender, EventArgs e)
        {
            Form parentForm = this.FindForm();
            if (parentForm != null && parentForm.WindowState == FormWindowState.Minimized)
                ((IOwner)this).OnApplicationDeactivate();
        }
        private void ParentDeactivate(object sender, EventArgs e)
        {
            Form parentForm = this.FindForm();
            if (parentForm != null && parentForm.WindowState == FormWindowState.Minimized)
                ((IOwner)this).OnApplicationDeactivate();
        }
        #endregion
        #region IOwner Members
        Form IOwner.ParentForm
        {
            get
            {
                return base.FindForm();
            }
            set { }
        }
        /// 
        /// Returns the collection of items with the specified name.
        /// 
        /// Item name to look for.
        /// 
        System.Collections.ArrayList IOwner.GetItems(string ItemName)
        {
            ArrayList list = new ArrayList(15);
            BarFunctions.GetSubItemsByName(_MenuContainer, ItemName, list);
            return list;
        }
        /// 
        /// Returns the collection of items with the specified name and type.
        /// 
        /// Item name to look for.
        /// Item type to look for.
        /// 
        System.Collections.ArrayList IOwner.GetItems(string ItemName, Type itemType)
        {
            ArrayList list = new ArrayList(15);
            BarFunctions.GetSubItemsByNameAndType(_MenuContainer, ItemName, list, itemType);
            return list;
        }
        /// 
        /// Returns the collection of items with the specified name and type.
        /// 
        /// Item name to look for.
        /// Item type to look for.
        /// Indicates whether GlobalName property is used for searching.
        /// 
        System.Collections.ArrayList IOwner.GetItems(string ItemName, Type itemType, bool useGlobalName)
        {
            ArrayList list = new ArrayList(15);
            BarFunctions.GetSubItemsByNameAndType(_MenuContainer, ItemName, list, itemType, useGlobalName);
            return list;
        }
        /// 
        /// Returns the first item that matches specified name.
        /// 
        /// Item name to look for.
        /// 
        BaseItem IOwner.GetItem(string ItemName)
        {
            BaseItem item = BarFunctions.GetSubItemByName(_MenuContainer, ItemName);
            if (item != null)
                return item;
            return null;
        }
        private BaseItem _ExpandedItem = null;
        void IOwner.SetExpandedItem(BaseItem objItem)
        {
            if (objItem != null && (objItem.Parent is RadialMenuContainer || objItem.Parent is RadialMenu))
                return;
            if (_ExpandedItem != null)
            {
                if (_ExpandedItem.Expanded)
                    _ExpandedItem.Expanded = false;
                _ExpandedItem = null;
            }
            _ExpandedItem = objItem;
        }
        BaseItem IOwner.GetExpandedItem()
        {
            return _ExpandedItem;
        }
        private BaseItem _FocusItem = null;
        // Currently we are using this to communicate "focus" when control is in
        // design mode. This can be used later if we decide to add focus
        // handling to our BaseItem class.
        void IOwner.SetFocusItem(BaseItem objFocusItem)
        {
            if (_FocusItem != null && _FocusItem != objFocusItem)
            {
                _FocusItem.OnLostFocus();
            }
            OnSetFocusItem(objFocusItem);
            _FocusItem = objFocusItem;
            if (_FocusItem != null)
                _FocusItem.OnGotFocus();
        }
        protected virtual void OnSetFocusItem(BaseItem objFocusItem)
        {
        }
        BaseItem IOwner.GetFocusItem()
        {
            return _FocusItem;
        }
        void IOwner.DesignTimeContextMenu(BaseItem objItem) { }
        private Hashtable _ShortcutTable = new Hashtable();
        void IOwner.RemoveShortcutsFromItem(BaseItem objItem)
        {
            ShortcutTableEntry objEntry = null;
            if (objItem.ShortcutString != "")
            {
                foreach (eShortcut key in objItem.Shortcuts)
                {
                    if (_ShortcutTable.ContainsKey(key))
                    {
                        objEntry = (ShortcutTableEntry)_ShortcutTable[key];
                        try
                        {
                            objEntry.Items.Remove(objItem.Id);
                            if (objEntry.Items.Count == 0)
                                _ShortcutTable.Remove(objEntry.Shortcut);
                        }
                        catch (ArgumentException) { }
                    }
                }
            }
            IOwner owner = this as IOwner;
            foreach (BaseItem objTmp in objItem.SubItems)
                owner.RemoveShortcutsFromItem(objTmp);
        }
        void IOwner.AddShortcutsFromItem(BaseItem objItem)
        {
            ShortcutTableEntry objEntry = null;
            if (objItem.ShortcutString != "")
            {
                foreach (eShortcut key in objItem.Shortcuts)
                {
                    if (_ShortcutTable.ContainsKey(key))
                        objEntry = (ShortcutTableEntry)_ShortcutTable[objItem.Shortcuts[0]];
                    else
                    {
                        objEntry = new ShortcutTableEntry(key);
                        _ShortcutTable.Add(objEntry.Shortcut, objEntry);
                    }
                    try
                    {
                        objEntry.Items.Add(objItem.Id, objItem);
                    }
                    catch (ArgumentException) { }
                }
            }
            IOwner owner = this as IOwner;
            foreach (BaseItem objTmp in objItem.SubItems)
                owner.AddShortcutsFromItem(objTmp);
        }
        ImageList IOwner.Images
        {
            get { return null; }
            set { }
        }
        ImageList IOwner.ImagesMedium
        {
            get { return null; }
            set { }
        }
        ImageList IOwner.ImagesLarge
        {
            get { return null; }
            set { }
        }
        void IOwner.StartItemDrag(BaseItem objItem)
        {
            throw new Exception("The method or operation is not implemented.");
        }
        BaseItem IOwner.DragItem
        {
            get { throw new Exception("The method or operation is not implemented."); }
        }
        bool IOwner.DragInProgress
        {
            get { throw new Exception("The method or operation is not implemented."); }
        }
        private bool _ShowToolTips = true;
        /// 
        /// Indicates whether items show tooltips.
        /// 
        [DefaultValue(true), Category("Behavior"), Description("Indicates whether items show tooltips.")]
        public bool ShowToolTips
        {
            get
            {
                return _ShowToolTips;
            }
            set
            {
                _ShowToolTips = value;
            }
        }
        private bool _ShowShortcutKeysInToolTips = false;
        /// 
        /// Indicates whether item shortcut is displayed in Tooltips.
        /// 
        [Browsable(true), DefaultValue(false), Category("Behavior"), Description("Indicates whether item shortcut is displayed in Tooltips.")]
        public virtual bool ShowShortcutKeysInToolTips
        {
            get
            {
                return _ShowShortcutKeysInToolTips;
            }
            set
            {
                _ShowShortcutKeysInToolTips = value;
            }
        }
        private bool _AlwaysDisplayKeyAccelerators = false;
        /// 
        /// Gets or sets whether accelerator letters on buttons are underlined. Default value is false which indicates that system setting is used
        /// to determine whether accelerator letters are underlined. Setting this property to true
        /// will always display accelerator letter underlined.
        /// 
        [Browsable(true), DefaultValue(false), Category("Behavior"), Description("Indicates whether accelerator letters for buttons are underlined regardless of current Windows settings.")]
        public bool AlwaysDisplayKeyAccelerators
        {
            get { return _AlwaysDisplayKeyAccelerators; }
            set
            {
                if (_AlwaysDisplayKeyAccelerators != value)
                {
                    _AlwaysDisplayKeyAccelerators = value;
                    this.Invalidate();
                }
            }
        }
        Form IOwner.ActiveMdiChild
        {
            get
            {
                Form form = base.FindForm();
                if (form == null)
                    return null;
                if (form.IsMdiContainer)
                {
                    return form.ActiveMdiChild;
                }
                return null;
            }
        }
        MdiClient IOwner.GetMdiClient(Form MdiForm)
        {
            return BarFunctions.GetMdiClient(MdiForm);
        }
        void IOwner.Customize()
        {
            throw new Exception("The method or operation is not implemented.");
        }
        void IOwner.InvokeResetDefinition(BaseItem item, EventArgs e)
        {
        }
        bool IOwner.ShowResetButton
        {
            get
            {
                return false;
            }
            set
            {
                throw new Exception("The method or operation is not implemented.");
            }
        }
        void IOwner.InvokeDefinitionLoaded(object sender, EventArgs e)
        {
        }
        void IOwner.InvokeUserCustomize(object sender, EventArgs e)
        {
        }
        void IOwner.InvokeEndUserCustomize(object sender, EndUserCustomizeEventArgs e)
        {
        }
        void IOwner.OnApplicationActivate()
        {
        }
        void IOwner.OnApplicationDeactivate()
        {
            if (this.IsOpen && _CloseMenuOnAppDeactivate) this.IsOpen = false;
        }
        void IOwner.OnParentPositionChanging()
        {
            if (this.IsOpen) this.IsOpen = false;
        }
        bool IOwner.DesignMode
        {
            get { return this.DesignMode; }
        }
        private bool _DisabledImagesGrayScale = true;
        /// 
        /// Gets or sets whether gray-scale algorithm is used to create automatic gray-scale images. Default is true.
        /// 
        [Browsable(true), DefaultValue(true), Category("Appearance"), Description("Gets or sets whether gray-scale algorithm is used to create automatic gray-scale images.")]
        public bool DisabledImagesGrayScale
        {
            get
            {
                return _DisabledImagesGrayScale;
            }
            set
            {
                _DisabledImagesGrayScale = value;
            }
        }
        #endregion
        #region IOwnerItemEvents Members
        /// 
        /// Occurs after an item has been added to items collection.
        /// 
        [Description("Occurs after an item has been added to items collection.")]
        public event EventHandler ItemAdded;
        /// 
        /// Raises ItemAdded event.
        /// 
        /// Reference to item.
        /// Provides event arguments.
        protected virtual void OnItemAdded(BaseItem source, EventArgs e)
        {
            EventHandler handler = ItemAdded;
            if (handler != null)
                handler(source, e);
        }
        void IOwnerItemEvents.InvokeItemAdded(BaseItem item, EventArgs e)
        {
            OnItemAdded(item, e);
        }
        /// 
        /// Occurs after an item has been removed from items collection.
        /// 
        [Description("Occurs after an item has been removed from items collection.")]
        public event DevComponents.DotNetBar.ItemControl.ItemRemovedEventHandler ItemRemoved;
        /// 
        /// Raises ItemRemoved event.
        /// 
        /// Reference to item.
        /// Provides event arguments.
        protected virtual void OnItemRemoved(BaseItem source, ItemRemovedEventArgs e)
        {
            DevComponents.DotNetBar.ItemControl.ItemRemovedEventHandler handler = ItemRemoved;
            if (handler != null)
                handler(source, e);
        }
        void IOwnerItemEvents.InvokeItemRemoved(BaseItem item, BaseItem parent, int itemIndex)
        {
            OnItemRemoved(item, new ItemRemovedEventArgs(parent, itemIndex));
        }
        /// 
        /// Occurs when mouse pointer enters boundaries of an item.
        /// 
        [Description("Occurs when mouse pointer enters boundaries of an item.")]
        public event EventHandler ItemMouseEnter;
        /// 
        /// Raises ItemMouseEnter event.
        /// 
        /// Reference to item.
        /// Provides event arguments.
        protected virtual void OnItemMouseEnter(BaseItem source, EventArgs e)
        {
            EventHandler handler = ItemMouseEnter;
            if (handler != null)
                handler(source, e);
        }
        void IOwnerItemEvents.InvokeMouseEnter(BaseItem item, EventArgs e)
        {
            OnItemMouseEnter(item, e);
        }
        /// 
        /// Occurs when mouse pointer hovers over an item.
        /// 
        [Description("Occurs when mouse pointer hovers over an item.")]
        public event EventHandler ItemMouseHover;
        /// 
        /// Raises ItemMouseHover event.
        /// 
        /// Reference to item.
        /// Provides event arguments.
        protected virtual void OnItemMouseHover(BaseItem source, EventArgs e)
        {
            EventHandler handler = ItemMouseHover;
            if (handler != null)
                handler(source, e);
        }
        void IOwnerItemEvents.InvokeMouseHover(BaseItem item, EventArgs e)
        {
            OnItemMouseHover(item, e);
        }
        /// 
        /// Occurs when mouse pointer leaves boundaries of an item.
        /// 
        [Description("Occurs when mouse pointer leaves boundaries of an item.")]
        public event EventHandler ItemMouseLeave;
        /// 
        /// Raises ItemMouseLeave event.
        /// 
        /// Reference to item.
        /// Provides event arguments.
        protected virtual void OnItemMouseLeave(BaseItem source, EventArgs e)
        {
            EventHandler handler = ItemMouseLeave;
            if (handler != null)
                handler(source, e);
        }
        void IOwnerItemEvents.InvokeMouseLeave(BaseItem item, EventArgs e)
        {
            OnItemMouseLeave(item, e);
        }
        /// 
        /// Occurs when mouse button is pressed on item.
        /// 
        [Description("Occurs when mouse button is pressed on item.")]
        public event MouseEventHandler ItemMouseDown;
        /// 
        /// Raises ItemMouseDown event.
        /// 
        /// Reference to item.
        /// Provides event arguments.
        protected virtual void OnItemMouseDown(BaseItem source, MouseEventArgs e)
        {
            MouseEventHandler handler = ItemMouseDown;
            if (handler != null)
                handler(source, e);
        }
        void IOwnerItemEvents.InvokeMouseDown(BaseItem item, MouseEventArgs e)
        {
            OnItemMouseDown(item, e);
        }
        /// 
        /// Occurs when mouse button is released on item.
        /// 
        [Description("Occurs when mouse button is released on item.")]
        public event MouseEventHandler ItemMouseUp;
        /// 
        /// Raises ItemMouseUp event.
        /// 
        /// Reference to item.
        /// Provides event arguments.
        protected virtual void OnItemMouseUp(BaseItem source, MouseEventArgs e)
        {
            MouseEventHandler handler = ItemMouseUp;
            if (handler != null)
                handler(source, e);
        }
        void IOwnerItemEvents.InvokeMouseUp(BaseItem item, MouseEventArgs e)
        {
            OnItemMouseUp(item, e);
        }
        /// 
        /// Occurs when mouse moves over an item.
        /// 
        [Description("Occurs when mouse moves over an item.")]
        public event MouseEventHandler ItemMouseMove;
        /// 
        /// Raises ItemMouseMove event.
        /// 
        /// Reference to item.
        /// Provides event arguments.
        protected virtual void OnItemMouseMove(BaseItem source, MouseEventArgs e)
        {
            MouseEventHandler handler = ItemMouseMove;
            if (handler != null)
                handler(source, e);
        }
        void IOwnerItemEvents.InvokeMouseMove(BaseItem item, MouseEventArgs e)
        {
            OnItemMouseMove(item, e);
        }
        /// 
        /// Occurs when an item is clicked.
        /// 
        [Description("Occurs when an item is clicked.")]
        public event EventHandler ItemClick;
        /// 
        /// Raises ItemClick event.
        /// 
        /// Reference to item.
        /// Provides event arguments.
        protected virtual void OnItemClick(BaseItem source, EventArgs e)
        {
            EventHandler handler = ItemClick;
            if (handler != null)
                handler(source, e);
        }
        void IOwnerItemEvents.InvokeItemClick(BaseItem objItem)
        {
            OnItemClick(objItem, EventArgs.Empty);
        }
        /// 
        /// Occurs when an item is double-clicked.
        /// 
        [Description("Occurs when an item is double-clicked.")]
        public event MouseEventHandler ItemDoubleClick;
        /// 
        /// Raises ItemDoubleClick event.
        /// 
        /// Reference to item.
        /// Provides event arguments.
        protected virtual void OnItemDoubleClick(BaseItem source, MouseEventArgs e)
        {
            MouseEventHandler handler = ItemDoubleClick;
            if (handler != null)
                handler(source, e);
        }
        void IOwnerItemEvents.InvokeItemDoubleClick(BaseItem objItem, MouseEventArgs e)
        {
            OnItemDoubleClick(objItem, e);
        }
        void IOwnerItemEvents.InvokeGotFocus(BaseItem item, EventArgs e)
        {
        }
        void IOwnerItemEvents.InvokeLostFocus(BaseItem item, EventArgs e)
        {
        }
        /// 
        /// Occurs when an item Expanded property value has changed.
        /// 
        [Description("Occurs when an item Expanded property value has changed.")]
        public event EventHandler ItemExpandedChanged;
        /// 
        /// Raises ItemExpandedChanged event.
        /// 
        /// Reference to item.
        /// Provides event arguments.
        protected virtual void OnItemExpandedChanged(BaseItem source, EventArgs e)
        {
            EventHandler handler = ItemExpandedChanged;
            if (handler != null)
                handler(source, e);
        }
        void IOwnerItemEvents.InvokeExpandedChange(BaseItem item, EventArgs e)
        {
            OnItemExpandedChanged(item, e);
        }
        /// 
        /// Occurs when an item Text property value has changed.
        /// 
        [Description("Occurs when an item Text property value has changed.")]
        public event EventHandler ItemTextChanged;
        /// 
        /// Raises ItemTextChanged event.
        /// 
        /// Provides event arguments.
        protected virtual void OnItemTextChanged(BaseItem source, EventArgs e)
        {
            EventHandler handler = ItemTextChanged;
            if (handler != null)
                handler(source, e);
        }
        void IOwnerItemEvents.InvokeItemTextChanged(BaseItem item, EventArgs e)
        {
            OnItemTextChanged(item, e);
        }
        void IOwnerItemEvents.InvokeContainerControlDeserialize(BaseItem item, ControlContainerSerializationEventArgs e)
        {
        }
        void IOwnerItemEvents.InvokeContainerControlSerialize(BaseItem item, ControlContainerSerializationEventArgs e)
        {
        }
        void IOwnerItemEvents.InvokeContainerLoadControl(BaseItem item, EventArgs e)
        {
        }
        void IOwnerItemEvents.InvokeOptionGroupChanging(BaseItem item, OptionGroupChangingEventArgs e)
        {
        }
        /// 
        /// Occurs when tooltip for an item is about to be displayed.
        /// 
        [Description("Occurs when tooltip for an item is about to be displayed.")]
        public event EventHandler ItemTooltipShowing;
        /// 
        /// Raises ItemTooltipShowing event.
        /// 
        /// Provides event arguments.
        protected virtual void OnItemTooltipShowing(object source, EventArgs e)
        {
            EventHandler handler = ItemTooltipShowing;
            if (handler != null)
                handler(source, e);
        }
        void IOwnerItemEvents.InvokeToolTipShowing(object item, EventArgs e)
        {
            OnItemTooltipShowing(item, e);
        }
        void IOwnerItemEvents.InvokeCheckedChanged(ButtonItem item, EventArgs e)
        {
        }
        #endregion
        #region RadialMenuAccessibleObject
        public class RadialMenuAccessibleObject : System.Windows.Forms.Control.ControlAccessibleObject
        {
            RadialMenu _Owner = null;
            public RadialMenuAccessibleObject(RadialMenu owner)
                : base(owner)
            {
                _Owner = owner;
            }
            internal void GenerateEvent(BaseItem sender, System.Windows.Forms.AccessibleEvents e)
            {
                int iChild = _Owner.Items.IndexOf(sender);
                if (iChild >= 0)
                {
                    if (_Owner != null && !_Owner.IsDisposed)
                        _Owner.AccessibilityNotifyClients(e, iChild);
                }
            }
            internal void GenerateEvent(System.Windows.Forms.AccessibleEvents e)
            {
                if (_Owner == null)
                    return;
                _Owner.AccessibilityNotifyClients(e, -1);
            }
            public override AccessibleRole Role
            {
                get
                {
                    if (_Owner != null && !_Owner.IsDisposed)
                        return _Owner.AccessibleRole;
                    return System.Windows.Forms.AccessibleRole.None;
                }
            }
            public override AccessibleObject Parent
            {
                get
                {
                    if (_Owner != null && !_Owner.IsDisposed)
                        return _Owner.Parent.AccessibilityObject;
                    return null;
                }
            }
            public override Rectangle Bounds
            {
                get
                {
                    if (_Owner != null && !_Owner.IsDisposed && _Owner.Parent != null)
                    {
                        return this._Owner.Parent.RectangleToScreen(_Owner.Bounds);
                    }
                    return Rectangle.Empty;
                }
            }
            public override int GetChildCount()
            {
                if (_Owner != null && !_Owner.IsDisposed && _Owner.Items != null)
                    return _Owner.Items.Count;
                return 0;
            }
            public override System.Windows.Forms.AccessibleObject GetChild(int iIndex)
            {
                if (_Owner != null && !_Owner.IsDisposed && _Owner.Items != null)
                    return _Owner.Items[iIndex].AccessibleObject;
                return null;
            }
            public override AccessibleStates State
            {
                get
                {
                    AccessibleStates state = AccessibleStates.Default;
                    if (_Owner == null || _Owner.IsDisposed)
                        return AccessibleStates.None;
                    if (_Owner.Focused)
                        state = AccessibleStates.Focused;
                    if (_Owner.IsOpen)
                        state = AccessibleStates.Expanded;
                    return state;
                }
            }
            public override string DefaultAction
            {
                get
                {
                    if (!string.IsNullOrEmpty(_Owner.AccessibleDefaultActionDescription))
                        return _Owner.AccessibleDefaultActionDescription;
                    return "Open";
                }
            }
            public override string Description
            {
                get
                {
                    if (!string.IsNullOrEmpty(_Owner.AccessibleDescription))
                        return _Owner.AccessibleDescription;
                    return "Radial Menu";
                }
            }
            public override void DoDefaultAction() 
            {
                if (_Owner != null && !_Owner.IsDisposed)
                    _Owner.IsOpen = !_Owner.IsOpen;
            }
            public override string Help
            {
                get
                {
                    if (!string.IsNullOrEmpty(_Owner.AccessibleHelp))
                        return _Owner.AccessibleHelp;
                    return "";
                }
            }
            public override string Name
            {
                get
                {
                    return _Owner.Name;
                }
                set
                {
                    _Owner.Name = value;
                }
            }
            public override string Value
            {
                get
                {
                    return _Owner.Text;
                }
                set
                {
                    _Owner.Text = value;
                }
            }
            public override string KeyboardShortcut
            {
                get
                {
                    return "";
                }
            }
        }
        #endregion
    }
}