using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
namespace DevComponents.DotNetBar.Layout
{
    /// 
    /// Represents the base item for layout control.
    /// 
    [ToolboxItem(false), DesignTimeVisible(false)]
    [Designer("DevComponents.DotNetBar.Layout.Design.LayoutItemBaseDesigner, DevComponents.DotNetBar.Layout.Design, Version=14.1.0.37, Culture=neutral,  PublicKeyToken=7eb7c3a35b91de04")]
    public class LayoutItemBase : IComponent, IDisposable, INotifyPropertyChanged
    {
        #region Constructor
        /// 
        /// Initializes a new instance of the LayoutItemBase class.
        /// 
        public LayoutItemBase()
        {
            _Style = new SimpleStyle();
            _Style.PropertyChanged += StylePropertyChanged;
        }
        #endregion
        #region Implementation
        /// 
        /// Paints the item. Actual code doing painting goes into the OnPaint method which should be overridden.
        /// 
        /// Provides Paint Context.
        internal void Paint(PaintContext context)
        {
            OnPaint(context);
        }
        /// 
        /// Paints the background of the item.
        /// 
        /// 
        protected virtual void OnPaintBackground(PaintContext context)
        {
            Rectangle bounds = _Bounds;
            Graphics g = context.Graphics;
            if (_Style.IsPainted)
            {
                DrawingHelpers.PaintStyle(g, _Style, bounds);
            }
        }
        protected virtual void PaintText(PaintContext context, bool isImageVisible, Color textColor, Rectangle textBounds, Brush textBrush)
        {
            Graphics g = context.Graphics;
            eTextAlignment textAlign = _TextAlignment;
            if (textAlign == eTextAlignment.Default)
                textAlign = context.TextAlignment;
            using (StringFormat format = new StringFormat())
            {
                if (textAlign == eTextAlignment.Right)
                {
                    if (isImageVisible && (_ImagePosition == eLayoutPosition.Right || _ImagePosition == eLayoutPosition.Default))
                        textBounds.Width -= _ActualImageBounds.Width + _ImageTextSpacing;
                    format.Alignment = StringAlignment.Far;
                }
                else if (textAlign == eTextAlignment.Center)
                    format.Alignment = StringAlignment.Center;
                if (_TextLineAlignment == eTextLineAlignment.Middle)
                    format.LineAlignment = StringAlignment.Center;
                else if (_TextLineAlignment == eTextLineAlignment.Bottom)
                    format.LineAlignment = StringAlignment.Far;
                format.HotkeyPrefix = context.HotkeyPrefix;
                Font font = GetTextFont(context.DefaultFont);
                if (_TextMarkup == null)
                    g.DrawString(_Text, font, textBrush, textBounds, format);
                else
                {
                    TextMarkup.MarkupDrawContext d = new TextMarkup.MarkupDrawContext(g, font, textColor, false);
                    d.HotKeyPrefixVisible = (context.HotkeyPrefix == System.Drawing.Text.HotkeyPrefix.Show);
                    Rectangle mr = new Rectangle(textBounds.X, textBounds.Y, _TextMarkup.Bounds.Width, _TextMarkup.Bounds.Height);
                    _TextMarkup.Bounds = mr;
                    _TextMarkup.Render(d);
                }
            }
        }
        protected virtual void PaintImage(PaintContext context, Color textColor)
        {
            Graphics g = context.Graphics;
            if (!string.IsNullOrEmpty(_Symbol))
            {
                Font font = _SymbolSize > 0 ? Symbols.GetFontAwesome(_SymbolSize) : Symbols.FontAwesome;
                TextDrawing.DrawStringLegacy(g, _Symbol, font,
                    (_SymbolColor.IsEmpty ? textColor : _SymbolColor),
                    new Rectangle(_ActualImageBounds.Location, Size.Empty),
                    eTextFormat.Default);
            }
            else
                g.DrawImage(_Image, _ActualImageBounds);
        }
        /// 
        /// Actual painting implementation.
        /// 
        /// 
        protected virtual void OnPaint(PaintContext context)
        {
            Rectangle bounds = _Bounds;
            Graphics g = context.Graphics;
            OnPaintBackground(context);
            bounds = Helpers.Deflate(bounds, _Padding);
            bool isImageVisible = IsImageVisible;
            Color textColor = context.LabelTextColor;
            if (_TextVisible && !string.IsNullOrEmpty(_Text))
            {
                Rectangle textBounds = _ActualTextBounds;
                if (_StripTextBaseline > 0 && UseStripBaseline)
                    textBounds = new Rectangle(textBounds.X,
                                                textBounds.Y + (_StripTextBaseline - _TextBaseline),
                                                textBounds.Width,
                                                textBounds.Height);
                bool dispose = false;
                Brush textBrush = context.LabelTextBrush;
                if (this.IsKeyboardFocusWithin && context.FocusStyle != null && !context.FocusStyle.TextColor.IsEmpty)
                {
                    textColor = context.FocusStyle.TextColor;
                    textBrush = new SolidBrush(textColor);
                    dispose = true;
                }
                else if (!_Style.TextColor.IsEmpty)
                {
                    textColor = _Style.TextColor;
                    textBrush = new SolidBrush(textColor);
                    dispose = true;
                }
                PaintText(context,isImageVisible, textColor, textBounds, textBrush);
                if (dispose)
                    textBrush.Dispose();
            }
            if (isImageVisible)
            {
                PaintImage(context, textColor);
            }
            if (_IsSelected)
                OnPaintSelection(context);
        }
        /// 
        /// Returns whether strip text base line value is used when calculating position of the rendered text label.
        /// 
        protected bool UseStripBaseline
        {
            get
            {
                return TextBaseLineEnabled && TextPosition == eLayoutPosition.Default && (!IsImageVisible || IsImageVisible && (_ImagePosition == eLayoutPosition.Default || _ImagePosition == eLayoutPosition.Left || _ImagePosition == eLayoutPosition.Right));
            }
        }
        private bool _TextBaseLineEnabled = true;
        /// 
        /// Indicates whether shared text baseline between items is enabled so the text-base aligns.
        /// 
        [DefaultValue(true), Category("Appearance"), Description("Indicates whether shared text baseline between items is enabled so the text-base aligns.")]
        public bool TextBaseLineEnabled
        {
            get { return _TextBaseLineEnabled; }
            set
            {
                if (value != _TextBaseLineEnabled)
                {
                    bool oldValue = _TextBaseLineEnabled;
                    _TextBaseLineEnabled = value;
                    OnTextBaseLineEnabledChanged(oldValue, value);
                }
            }
        }
        /// 
        /// Called when TextBaseLineEnabled property has changed.
        /// 
        /// Old property value
        /// New property value
        protected virtual void OnTextBaseLineEnabledChanged(bool oldValue, bool newValue)
        {
            UpdateTextBounds();
            this.Invalidate();
            OnPropertyChanged(new PropertyChangedEventArgs("TextBaseLineEnabled"));
        }
        
        private static readonly Color SelectionColor = ColorHelpers.GetColor(0x696969);
        /// 
        /// Paints the selection adorner around the item.
        /// 
        /// 
        protected virtual void OnPaintSelection(PaintContext context)
        {
            if (this.DesignMode) return;
            Rectangle r = _Bounds;
            r.Width--;
            r.Height--;
            Graphics g = context.Graphics;
            using (Pen pen = new Pen(SelectionColor))
            {
                pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
                g.DrawRectangle(pen, r);
            }
        }
        /// 
        /// Updates bounds of the item in response to the scrolling of LayoutControl.
        /// 
        /// 
        /// 
        internal virtual void UpdateScrollBounds(int xScroll, int yScroll, bool moveControls)
        {
            _Bounds.Offset(xScroll, yScroll);
            if (!_ActualTextBounds.IsEmpty)
                _ActualTextBounds.Offset(xScroll, yScroll);
            if(!_ActualImageBounds.IsEmpty)
                _ActualImageBounds.Offset(xScroll, yScroll);
        }
        private Rectangle _Bounds;
        /// 
        /// Gets the bounds of the item.
        /// 
        [Browsable(false)]
        public virtual Rectangle Bounds
        {
            get
            {
                return _Bounds;
            }
        }
        /// 
        /// Processes accelerator key for the item.
        /// 
        /// 
        internal virtual bool ProcessMnemonic(char charCode)
        {
            return false;
        }
        /// 
        /// Sets new bounds of the item.
        /// 
        /// New bounds.
        public virtual void SetBounds(Rectangle r)
        {
            _Bounds = r;
            UpdateLayout();
        }
        /// 
        /// Sets new bounds of the item and actual text size.
        /// 
        /// 
        /// 
        public virtual void SetBounds(Rectangle r, Size actualTextSize)
        {
            _Bounds = r;
            ActualTextSize = actualTextSize;
            UpdateLayout();
        }
        /// 
        /// Updates the item layout. Actual layout is performed in OnUpdateLayout method.
        /// 
        internal void UpdateLayout()
        {
            OnUpdateLayout();
        }
        /// 
        /// Actual layout update implementation.
        /// 
        protected virtual void OnUpdateLayout()
        {
            UpdateTextBounds();
        }
        /// 
        /// Updates the layout of the text inside of item.
        /// 
        protected virtual void UpdateTextBounds()
        {
            Rectangle bounds = Helpers.Deflate(_Bounds, _Padding);
            _ActualTextBounds = Helpers.Deflate(bounds, _TextPadding);
            _ActualImageBounds = Rectangle.Empty;
            bool isImageVisible = IsImageVisible;
            Size imageSize = Size.Empty;
            if (isImageVisible)
                imageSize = GetImageSize();
            eTextAlignment textAlignment = _TextAlignment;
            if (textAlignment == eTextAlignment.Default)
            {
                LayoutControl lc = GetLayoutControl();
                if (lc != null)
                    textAlignment = lc.LabelTextAlignment;
            }
            if (_TextPosition == eLayoutPosition.Default || _TextPosition == eLayoutPosition.Left ||
                _TextPosition == eLayoutPosition.Right)
            {
                if (_TextLineAlignment == eTextLineAlignment.Middle)
                    _ActualTextBounds.Y += (_ActualTextBounds.Height - _ActualTextSize.Height) / 2;
                else if (_TextLineAlignment == eTextLineAlignment.Bottom)
                    _ActualTextBounds.Y = _ActualTextBounds.Bottom - _ActualTextSize.Height;
            }
            if (_TextPosition == eLayoutPosition.Default || _TextPosition == eLayoutPosition.Left || _TextPosition == eLayoutPosition.Top)
            {
                _ActualTextBounds.Size = _ActualTextSize;
            }
            else if (_TextPosition == eLayoutPosition.Bottom)
            {
                _ActualTextBounds.Y = _ActualTextBounds.Bottom - _ActualTextSize.Height;
                _ActualTextBounds.Size = _ActualTextSize;
            }
            else if (_TextPosition == eLayoutPosition.Right)
            {
                _ActualTextBounds.X = _ActualTextBounds.Right - _ActualTextSize.Width;
                _ActualTextBounds.Size = _ActualTextSize;
            }
            else if (_TextPosition == eLayoutPosition.Top)
            {
                _ActualTextBounds.Y = _ActualTextBounds.Bottom - _ActualTextSize.Height;
                _ActualTextBounds.Size = _ActualTextSize;
            }
            if (isImageVisible)
            {
                if (_ImagePosition == eLayoutPosition.Default || _ImagePosition == eLayoutPosition.Right)
                {
                    if (textAlignment == eTextAlignment.Right)
                        _ActualImageBounds = new Rectangle(_ActualTextBounds.Right - imageSize.Width, _ActualTextBounds.Y + (-_ActualTextBounds.Height - imageSize.Height) / 2, imageSize.Width, imageSize.Height);
                    else
                        _ActualImageBounds = new Rectangle(_ActualTextBounds.X + _ImageTextSpacing + _RealTextSize.Width, _ActualTextBounds.Y + (_ActualTextBounds.Height - imageSize.Height) / 2, imageSize.Width, imageSize.Height);
                }
                else if (_ImagePosition == eLayoutPosition.Left)
                {
                    if (textAlignment == eTextAlignment.Right)
                        _ActualImageBounds = new Rectangle(_ActualTextBounds.Right - (_RealTextSize.Width + imageSize.Width + _ImageTextSpacing), _ActualTextBounds.Y + (_ActualTextBounds.Height - imageSize.Height) / 2, imageSize.Width, imageSize.Height);
                    else
                    {
                        _ActualImageBounds = new Rectangle(_ActualTextBounds.X, _ActualTextBounds.Y + (_ActualTextBounds.Height - imageSize.Height) / 2, imageSize.Width, imageSize.Height);
                        _ActualTextBounds.X += _ActualImageBounds.Width + _ImageTextSpacing;
                    }
                }
                else if (_ImagePosition == eLayoutPosition.Top)
                {
                    _ActualImageBounds = new Rectangle(_ActualTextBounds.X + (_ActualTextBounds.Width - imageSize.Width) / 2,
                                             _ActualTextBounds.Y - (imageSize.Height + _ImageTextSpacing),
                                             imageSize.Width,
                                             imageSize.Height);
                }
                else if (_ImagePosition == eLayoutPosition.Bottom)
                {
                    _ActualImageBounds = new Rectangle(_ActualTextBounds.X + (_ActualTextBounds.Width - imageSize.Width) / 2,
                                             _ActualTextBounds.Bottom + _ImageTextSpacing,
                                             imageSize.Width,
                                             imageSize.Height);
                }
            }
        }
        protected virtual Size GetImageSize()
        {
            if (!string.IsNullOrEmpty(_Symbol))
                return _SymbolTextSize;
            if (_Image != null)
                return _Image.Size;
            return Size.Empty;
        }
        protected bool IsImageVisible
        {
            get
            {
                return _Image != null || !string.IsNullOrEmpty(_Symbol);
            }
        }
        /// 
        /// Scales item in response to the scaling of the LayoutControl. Should never be called directly.
        /// 
        /// 
        [EditorBrowsable(EditorBrowsableState.Never)]
        public virtual void ScaleItem(SizeF factor)
        {
            bool widthChanged = factor.Width != 1f;
            bool heightChanged = factor.Height != 1f;
            if (!_MinSize.IsEmpty && (widthChanged || heightChanged))
            {
                Size newMinSize = new Size();
                if (widthChanged)
                    newMinSize.Width = (int)(_MinSize.Width * factor.Width);
                else
                    newMinSize.Width = _MinSize.Width;
                if (heightChanged)
                    newMinSize.Height = (int)(_MinSize.Height * factor.Height);
                else
                    newMinSize.Height = _MinSize.Height;
                MinSize = newMinSize;
            }
            
            if (widthChanged && _WidthType == eLayoutSizeType.Absolute)
            {
                int newWidth = (int)Math.Round(_Width * factor.Width);
                if (_MinSize.Width > newWidth)
                    newWidth = _MinSize.Width;
                this.Width = newWidth;
            }
            if (heightChanged && _HeightType == eLayoutSizeType.Absolute)
            {
                int newHeight = (int)Math.Round(_Height * factor.Height);
                if (_MinSize.Height > newHeight)
                    newHeight = _MinSize.Height;
                this.Height = newHeight;
            }
            if (!_TextSize.IsEmpty && (widthChanged || heightChanged))
            {
                Size newTextSize = new Size();
                if (widthChanged)
                    newTextSize.Width = (int)(_TextSize.Width * factor.Width);
                else
                    newTextSize.Width = _TextSize.Width;
                if (heightChanged)
                    newTextSize.Height = (int)(_TextSize.Height * factor.Height);
                else
                    newTextSize.Height = _TextSize.Height;
                TextSize = newTextSize;
            }
            if (!Helpers.IsEmpty(_TextPadding) && (widthChanged || heightChanged))
            {
                System.Windows.Forms.Padding newTextPadding = _TextPadding;
                if (widthChanged)
                {
                    newTextPadding.Left = (int)(_TextPadding.Left * factor.Width);
                    newTextPadding.Right = (int)(_TextPadding.Right * factor.Width);
                }
                if (heightChanged)
                {
                    newTextPadding.Top = (int)(_TextPadding.Top * factor.Height);
                    newTextPadding.Bottom = (int)(_TextPadding.Bottom * factor.Height);
                }
                TextPadding = newTextPadding;
            }
            if (!Helpers.IsEmpty(_Padding) && (widthChanged || heightChanged))
            {
                System.Windows.Forms.Padding newPadding = _Padding;
                if (widthChanged)
                {
                    newPadding.Left = (int)(_Padding.Left * factor.Width);
                    newPadding.Right = (int)(_Padding.Right * factor.Width);
                }
                if (heightChanged)
                {
                    newPadding.Top = (int)(_Padding.Top * factor.Height);
                    newPadding.Bottom = (int)(_Padding.Bottom * factor.Height);
                }
                Padding = newPadding;
            }
        }
        /// 
        /// Measures the size of the item text. Actual measurement is done in OnMeasureText method.
        /// 
        /// 
        /// 
        internal Size MeasureText(LayoutContext c)
        {
            return OnMeasureText(c);
        }
        protected virtual Font GetTextFont(Font defaultFont)
        {
            Font font = defaultFont;
            if (_Style.Font != null)
                font = _Style.Font;
            return font;
        }
        /// 
        /// Returns the size of the items text.
        /// 
        /// 
        /// 
        protected virtual Size OnMeasureText(LayoutContext c)
        {
            if (!_TextVisible) return Size.Empty;
            if (_TextSize.Width > 0 && _TextSize.Height > 0)
                return _TextSize;
            Size size = Size.Empty;
            Graphics g = c.Graphics;
            Font font = GetTextFont(c.Font);
            if (_TextMarkup == null)
            { // Plain Text
                if (_TextSize.Width > 0)
                {
                    size = Size.Ceiling(g.MeasureString(_Text, font, _TextSize.Width));
                }
                else
                {
                    size = Size.Ceiling(g.MeasureString(_Text, font));
                }
            }
            else
            {
                // Text Markup
                Size availSize = new Size(_TextSize.Width > 0 ? _TextSize.Width : 1600, 1);
                TextMarkup.MarkupDrawContext d = new TextMarkup.MarkupDrawContext(g, font, Color.Empty, false);
                _TextMarkup.InvalidateElementsSize();
                _TextMarkup.Measure(availSize, d);
                availSize = _TextMarkup.Bounds.Size;
                d.RightToLeft = c.RightToLeft;
                _TextMarkup.Arrange(new Rectangle(0, 0, availSize.Width, availSize.Height), d);
                size = _TextMarkup.Bounds.Size;
            }
            if (_TextSize.Height > 0)
                size.Height = _TextSize.Height;
            size.Width += _TextPadding.Horizontal;
            size.Height += _TextPadding.Vertical;
            _RealTextSize = size;
            _TextBaseline = c.FontBaseline;
            if (IsImageVisible)
            {
                if (!string.IsNullOrEmpty(_Symbol))
                {
                    Font symFont = Symbols.GetFontAwesome(_SymbolSize);
                    _SymbolTextSize = TextDrawing.MeasureString(g, _Symbol, symFont);
                    int descent = (int)Math.Ceiling((symFont.FontFamily.GetCellDescent(symFont.Style) *
                    symFont.Size / symFont.FontFamily.GetEmHeight(symFont.Style)));
                    _SymbolTextSize.Height -= descent;
                }
                else
                    _SymbolTextSize = Size.Empty;
                if (_ImagePosition == eLayoutPosition.Default || _ImagePosition == eLayoutPosition.Left || _ImagePosition == eLayoutPosition.Right)
                    size.Width += _ImageTextSpacing + GetImageSize().Width;
            }
            return size;
        }
        private Size _RealTextSize = Size.Empty;
         //
         // Returns the real text-size for the text label that is valid after MeasureText is called.
         //
        [Browsable(false)]
        public Size RealTextSize
        {
            get
            {
                return _RealTextSize;
            }
        }
        private int _StripTextBaseline = 0;
        /// 
        /// Gets or sets the text-baseline that is used by whole strip.
        /// 
        internal virtual int StripTextBaseline
        {
            get { return _StripTextBaseline; }
            set
            {
                _StripTextBaseline = value;
            }
        }
        private int _TextBaseline = 0;
        /// 
        /// Returns the text base line.
        /// 
        internal virtual int TextBaseline
        {
            get
            {
                return _TextBaseline;
            }
            set
            {
                _TextBaseline = value;
            }
        }
        private object _Tag = "";
        /// 
        /// Gets or sets an object that contains additional data attached to the item.
        /// 
        [Bindable(true), DefaultValue(""), Localizable(false), TypeConverter(typeof(StringConverter)), Description("Indicates an object that contains additional data attached to the item")]
        public object Tag
        {
            get { return _Tag; }
            set
            {
                if (value != _Tag)
                {
                    object oldValue = _Tag;
                    _Tag = value;
                    OnTagChanged(oldValue, value);
                }
            }
        }
        /// 
        /// Called when Tag property has changed.
        /// 
        /// Old property value
        /// New property value
        protected virtual void OnTagChanged(object oldValue, object newValue)
        {
            OnPropertyChanged(new PropertyChangedEventArgs("Tag"));
        }
        private string _Text = "";
        /// 
        /// Indicates the item caption.
        /// 
        [Bindable(true), Category("Text"), DefaultValue(""), Localizable(true), Description("Indicates the item caption.")]
        [Editor("DevComponents.DotNetBar.Layout.Design.TextMarkupUIEditor, DevComponents.DotNetBar.Layout.Design, Version=14.1.0.37, Culture=neutral,  PublicKeyToken=7eb7c3a35b91de04", typeof(System.Drawing.Design.UITypeEditor))]
        public virtual string Text
        {
            get { return _Text; }
            set
            {
                if (value != _Text)
                {
                    string oldValue = _Text;
                    _Text = value;
                    OnTextChanged(oldValue, value);
                }
            }
        }
        /// 
        /// Called when Text property has changed.
        /// 
        /// Old property value
        /// New property value
        protected virtual void OnTextChanged(string oldValue, string newValue)
        {
            OnPropertyChanged(new PropertyChangedEventArgs("Text"));
            MarkupTextChanged();
            InvalidateLayout();
        }
        private Size _TextSize = Size.Empty;
        /// 
        /// Gets or sets the explicit size of the text part of item.
        /// 
        [Category("Appearance"), Description("Indicates explicit size of text part of the item")]
        public Size TextSize
        {
            get { return _TextSize; }
            set
            {
                if (value != _TextSize)
                {
                    Size oldValue = _TextSize;
                    _TextSize = value;
                    OnTextSizeChanged(oldValue, value);
                }
            }
        }
        [EditorBrowsable(EditorBrowsableState.Never)]
        public bool ShouldSerializeTextSize()
        {
            return !_TextSize.IsEmpty;
        }
        [EditorBrowsable(EditorBrowsableState.Never)]
        public void ResetTextSize()
        {
            TextSize = Size.Empty;
        }
        /// 
        /// Called when TextSize property has changed.
        /// 
        /// Old property value
        /// New property value
        protected virtual void OnTextSizeChanged(Size oldValue, Size newValue)
        {
            OnPropertyChanged(new PropertyChangedEventArgs("TextSize"));
            InvalidateLayout();
        }
        private Rectangle _ActualTextBounds = Rectangle.Empty;
        /// 
        /// Gets actual text bounds.
        /// 
        [Browsable(false)]
        public Rectangle ActualTextBounds
        {
            get
            {
                return _ActualTextBounds;
            }
            internal set
            {
                _ActualTextBounds = value;
            }
        }
        private Size _ActualTextSize = Size.Empty;
        /// 
        /// Gets actual text-size as used by the layout item.
        /// 
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false)]
        public Size ActualTextSize
        {
            get { return _ActualTextSize; }
            internal set
            {
                if (value != _ActualTextSize)
                {
                    Size oldValue = _ActualTextSize;
                    _ActualTextSize = value;
                    OnActualTextSizeChanged(oldValue, value);
                }
            }
        }
        /// 
        /// Called when ActualTextSize property has changed.
        /// 
        /// Old property value
        /// New property value
        protected virtual void OnActualTextSizeChanged(Size oldValue, Size newValue)
        {
            OnPropertyChanged(new PropertyChangedEventArgs("ActualTextSize"));
        }
        private System.Windows.Forms.Padding _TextPadding = new System.Windows.Forms.Padding(0, 0, 0, 0);
        /// 
        /// Gets or sets text padding.
        /// 
        [Browsable(true), Category("Appearance"), Description("Gets or sets text padding.")]
        public System.Windows.Forms.Padding TextPadding
        {
            get { return _TextPadding; }
            set
            {
                System.Windows.Forms.Padding oldValue = value;
                _TextPadding = value;
                OnTextPaddingChanged(oldValue, value);
            }
        }
        [EditorBrowsable(EditorBrowsableState.Never)]
        public bool ShouldSerializeTextPadding()
        {
            return _TextPadding.Bottom != 0 || _TextPadding.Top != 0 || _TextPadding.Left != 0 || _TextPadding.Right != 0;
        }
        [EditorBrowsable(EditorBrowsableState.Never)]
        public void ResetTextPadding()
        {
            _TextPadding = new System.Windows.Forms.Padding(0, 0, 0, 0);
        }
        /// 
        /// Called when TextPadding property has changed.
        /// 
        /// Old property value
        /// New property value
        protected virtual void OnTextPaddingChanged(System.Windows.Forms.Padding oldValue, System.Windows.Forms.Padding newValue)
        {
            this.InvalidateLayout();
            this.Invalidate();
            OnPropertyChanged(new PropertyChangedEventArgs("TextPadding"));
        }
        private bool _TextVisible = true;
        /// 
        /// Indicates whether caption/text is visible.
        /// 
        [DefaultValue(true), Category("Appearance"), Description("Indicates whether caption/text is visible."), Bindable(true)]
        public bool TextVisible
        {
            get { return _TextVisible; }
            set
            {
                if (value != _TextVisible)
                {
                    bool oldValue = _TextVisible;
                    _TextVisible = value;
                    OnTextVisibleChanged(oldValue, value);
                }
            }
        }
        /// 
        /// Called when TextVisible property has changed.
        /// 
        /// Old property value
        /// New property value
        protected virtual void OnTextVisibleChanged(bool oldValue, bool newValue)
        {
            OnPropertyChanged(new PropertyChangedEventArgs("TextVisible"));
            InvalidateLayout();
        }
        private eLayoutPosition _TextPosition = eLayoutPosition.Default;
        /// 
        /// Gets or sets the text position in relation to the other parts of the layout item. Default is same as Left.
        /// 
        [DefaultValue(eLayoutPosition.Default), Category("Appearance"), Description("Indicates text position in relation to the other parts of the layout item.")]
        public eLayoutPosition TextPosition
        {
            get { return _TextPosition; }
            set
            {
                if (value != _TextPosition)
                {
                    eLayoutPosition oldValue = _TextPosition;
                    _TextPosition = value;
                    OnTextPositionChanged(oldValue, value);
                }
            }
        }
        /// 
        /// Called when TextPosition property has changed.
        /// 
        /// Old property value
        /// New property value
        protected virtual void OnTextPositionChanged(eLayoutPosition oldValue, eLayoutPosition newValue)
        {
            OnPropertyChanged(new PropertyChangedEventArgs("TextPosition"));
            InvalidateLayout();
        }
        private int _Width = 0;
        /// 
        /// Indicates the total width of the item. The value specified here depends on the WidthType property setting. When using WidthType=Percentage the value specified here indicates the percent of the available client size of group.
        /// For example setting of 20 indicates 20% of the available client width.
        /// 
        [DefaultValue(0), Category("Appearance"), Description("Indicates the total width of the item. The value specified here depends on the WidthType property setting.")]
        public int Width
        {
            get { return _Width; }
            set
            {
                if (value != _Width)
                {
                    int oldValue = _Width;
                    _Width = value;
                    OnWidthChanged(oldValue, value);
                }
            }
        }
        /// 
        /// Called when Width property has changed.
        /// 
        /// Old property value
        /// New property value
        protected virtual void OnWidthChanged(int oldValue, int newValue)
        {
            OnPropertyChanged(new PropertyChangedEventArgs("Width"));
            InvalidateLayout();
        }
        private eLayoutSizeType _WidthType = eLayoutSizeType.Absolute;
        /// 
        /// Indicates width type used by the item.
        /// 
        [DefaultValue(eLayoutSizeType.Absolute), Category("Appearance"), Description("Indicates width type used by the item.")]
        public eLayoutSizeType WidthType
        {
            get { return _WidthType; }
            set
            {
                if (value != _WidthType)
                {
                    eLayoutSizeType oldValue = _WidthType;
                    _WidthType = value;
                    OnWidthTypeChanged(oldValue, value);
                }
            }
        }
        /// 
        /// Called when WidthType property has changed.
        /// 
        /// Old property value
        /// New property value
        protected virtual void OnWidthTypeChanged(eLayoutSizeType oldValue, eLayoutSizeType newValue)
        {
            OnPropertyChanged(new PropertyChangedEventArgs("WidthType"));
            InvalidateLayout();
        }
        /// 
        /// Indicates whether width type is the fixed width type, different than eLayoutSizeType.Percent
        /// 
        [Browsable(false)]
        public bool IsWidthFixed
        {
            get
            {
                return (_WidthType != eLayoutSizeType.Percent);
            }
        }
        private int _Height = 0;
        /// 
        /// Indicates the total height of the item. The value specified here depends on the HeightType property setting. When using HeightType=Percentage the value specified here indicates the percent of the available client size of group.
        /// For example setting of 10 indicates 10% of the available client height.
        /// 
        [DefaultValue(0), Category("Appearance"), Description("Indicates the total height of the item. The value specified here depends on the HeightType property setting.")]
        public int Height
        {
            get { return _Height; }
            set
            {
                if (value != _Height)
                {
                    int oldValue = _Height;
                    _Height = value;
                    OnHeightChanged(oldValue, value);
                }
            }
        }
        /// 
        /// Called when Height property has changed.
        /// 
        /// Old property value
        /// New property value
        protected virtual void OnHeightChanged(int oldValue, int newValue)
        {
            OnPropertyChanged(new PropertyChangedEventArgs("Height"));
            InvalidateLayout();
        }
        private eLayoutSizeType _HeightType = eLayoutSizeType.Absolute;
        /// 
        /// Indicates height type used by the item.
        /// 
        [DefaultValue(eLayoutSizeType.Absolute), Category("Appearance"), Description("Indicates height type used by the item.")]
        public eLayoutSizeType HeightType
        {
            get { return _HeightType; }
            set
            {
                if (value != _HeightType)
                {
                    eLayoutSizeType oldValue = _HeightType;
                    _HeightType = value;
                    OnHeightTypeChanged(oldValue, value);
                }
            }
        }
        /// 
        /// Called when HeightType property has changed.
        /// 
        /// Old property value
        /// New property value
        protected virtual void OnHeightTypeChanged(eLayoutSizeType oldValue, eLayoutSizeType newValue)
        {
            OnPropertyChanged(new PropertyChangedEventArgs("HeightType"));
            InvalidateLayout();
        }
        /// 
        /// Indicates whether height type is the fixed height type, different than eLayoutSizeType.Percent
        /// 
        [Browsable(false)]
        public bool IsHeightFixed
        {
            get
            {
                return (_HeightType != eLayoutSizeType.Percent);
            }
        }
        private Size _MinSize = Size.Empty;
        /// 
        /// Indicates the minimum size of the item. Setting Width or Height to zero indicates unconstrained minimum size for given dimension.
        /// 
        [Description("Indicates the minimum size of the item"), Category("Appearance")]
        public Size MinSize
        {
            get { return _MinSize; }
            set
            {
                if (value != _MinSize)
                {
                    Size oldValue = _MinSize;
                    _MinSize = value;
                    OnMinSizeChanged(oldValue, value);
                }
            }
        }
        [EditorBrowsable(EditorBrowsableState.Never)]
        public bool ShouldSerializeMinSize()
        {
            return !_MinSize.IsEmpty;
        }
        [EditorBrowsable(EditorBrowsableState.Never)]
        public void ResetMinSize()
        {
            MinSize = Size.Empty;
        }
        /// 
        /// Called when MinSize property has changed.
        /// 
        /// Old property value
        /// New property value
        protected virtual void OnMinSizeChanged(Size oldValue, Size newValue)
        {
            OnPropertyChanged(new PropertyChangedEventArgs("MinSize"));
            InvalidateLayout();
        }
        private int _SuggestedGroupId = 0;
        /// 
        /// When set to value greater than 0 it suggests to layout engine that items with same id that are in collection after each other should be kept on same line if possible.
        /// This is only suggestion to layout engine and engine will ignore it if there is insufficient client size available or other size constraints
        /// prevent it from keeping items in same line.
        /// 
        [DefaultValue(0), Category("Behavior"), Description("When set to value greater than 0 it suggests to layout engine that items with same id that are in collection after each other should be kept on same line if possible.")]
        public int SuggestedGroupId
        {
            get { return _SuggestedGroupId; }
            set
            {
                if (value != _SuggestedGroupId)
                {
                    int oldValue = _SuggestedGroupId;
                    _SuggestedGroupId = value;
                    OnSuggestedGroupIdChanged(oldValue, value);
                }
            }
        }
        /// 
        /// Called when SuggestedGroupId property has changed.
        /// 
        /// Old property value
        /// New property value
        protected virtual void OnSuggestedGroupIdChanged(int oldValue, int newValue)
        {
            OnPropertyChanged(new PropertyChangedEventArgs("SuggestedGroupId"));
        }
        private bool _MnemonicsEnabled = true;
        /// 
        /// Indicates whether accelerator keys assigned to item Text property are processed by items which respond to them.
        /// 
        [DefaultValue(true), Category("Behavior"), Description("Indicates whether accelerator keys assigned to item Text property are processed by items which respond to them.")]
        public bool MnemonicsEnabled
        {
            get { return _MnemonicsEnabled; }
            set
            {
                if (value != _MnemonicsEnabled)
                {
                    bool oldValue = _MnemonicsEnabled;
                    _MnemonicsEnabled = value;
                    OnMnemonicsEnabledChanged(oldValue, value);
                }
            }
        }
        /// 
        /// Called when MnemonicsEnabled property has changed.
        /// 
        /// Old property value
        /// New property value
        protected virtual void OnMnemonicsEnabledChanged(bool oldValue, bool newValue)
        {
            OnPropertyChanged(new PropertyChangedEventArgs("MnemonicsEnabled"));
        }
        private SimpleStyle _Style;
        /// 
        /// Gets the style for the background of the control.
        /// 
        [Browsable(true), Category("Appearance"), Description("Gets the style for the background of the item."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public SimpleStyle Style
        {
            get { return _Style; }
        }
        private void StylePropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            this.Invalidate();
            //throw new Exception("The method or operation is not implemented.");
        }
        private static readonly System.Windows.Forms.Padding DefaultPadding = new System.Windows.Forms.Padding(4);
        private System.Windows.Forms.Padding _Padding = DefaultPadding;
        /// 
        /// Specifies the amount of padding inside of the item. Padding is the spacing between the edges of item and its content.
        /// 
        [Category("Appearance"), Description("Specifies the amount of padding inside of the item.")]
        public System.Windows.Forms.Padding Padding
        {
            get { return _Padding; }
            set
            {
                if (value != _Padding)
                {
                    System.Windows.Forms.Padding oldValue = _Padding;
                    _Padding = value;
                    OnPaddingChanged(oldValue, value);
                }
            }
        }
        /// 
        /// Called when Padding property has changed.
        /// 
        /// Old property value
        /// New property value
        protected virtual void OnPaddingChanged(System.Windows.Forms.Padding oldValue, System.Windows.Forms.Padding newValue)
        {
            OnPropertyChanged(new PropertyChangedEventArgs("Padding"));
            InvalidateLayout();
        }
        [EditorBrowsable(EditorBrowsableState.Never)]
        public bool ShouldSerializePadding()
        {
            return _Padding != DefaultPadding;
        }
        [EditorBrowsable(EditorBrowsableState.Never)]
        public void ResetPadding()
        {
            Padding = DefaultPadding;
        }
        private int _AbsoluteIndex = -1;
        /// 
        /// Indicates the absolute index of the item inside of the LayoutControl.
        /// 
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public int AbsoluteIndex
        {
            get { return _AbsoluteIndex; }
            internal set
            {
                if (value != _AbsoluteIndex)
                {
                    int oldValue = _AbsoluteIndex;
                    _AbsoluteIndex = value;
                    OnAbsoluteIndexChanged(oldValue, value);
                }
            }
        }
        /// 
        /// Called when AbsoluteIndex property has changed.
        /// 
        /// Old property value
        /// New property value
        protected virtual void OnAbsoluteIndexChanged(int oldValue, int newValue)
        {
            OnPropertyChanged(new PropertyChangedEventArgs("AbsoluteIndex"));
        }
        /// 
        /// Returns the LayoutControl which hosts the item, if available.
        /// 
        /// reference to LayoutControl or null.
        public LayoutControl GetLayoutControl()
        {
            if (_LayoutControl != null) return _LayoutControl;
            LayoutItemBase item = this.Parent;
            while (item != null)
            {
                if (item.LayoutControl != null) return item.LayoutControl;
                item = item.Parent;
            }
            return null;
        }
        /// 
        /// Invalidates the paint region of the item.
        /// 
        public void Invalidate()
        {
            LayoutControl control = GetLayoutControl();
            if (control != null)
                control.Invalidate(_Bounds);
        }
        /// 
        /// Invalidates layout of the item and causes the LayoutControl to perform layout.
        /// 
        public void InvalidateLayout()
        {
            LayoutControl control = GetLayoutControl();
            if (control != null)
            {
                if (this.DesignMode)
                    control.Invalidate(true);
                control.PerformLayout();
            }
        }
        private LayoutControl _LayoutControl = null;
        /// 
        /// Gets the LayoutControl this group is directly attached too through RootGroup property.
        /// 
        [Browsable(false)]
        internal LayoutControl LayoutControl
        {
            get
            {
                return _LayoutControl;
            }
            set
            {
                _LayoutControl = value;
            }
        }
        private LayoutItemBase _Parent = null;
        /// 
        /// Gets the reference to parent item.
        /// 
        [Browsable(false)]
        public LayoutItemBase Parent
        {
            get { return _Parent; }
            internal set
            {
                if (value != _Parent)
                {
                    if (value == this) throw new ArgumentException("Item cannot parent itself");
                    if (IsChildItem(value)) throw new ArgumentException("Cannot set as Parent item that is child of this item");
                    LayoutItemBase oldValue = _Parent;
                    _Parent = value;
                    OnParentChanged(oldValue, value);
                }
            }
        }
        /// 
        /// Called when Parent property has changed.
        /// 
        /// Old property value
        /// New property value
        protected virtual void OnParentChanged(LayoutItemBase oldValue, LayoutItemBase newValue)
        {
            OnPropertyChanged(new PropertyChangedEventArgs("Parent"));
        }
        /// 
        /// Returns whether item is contained as child item by this item or one of its children.
        /// 
        /// Item to check.
        /// true if item is contained otherwise false
        public virtual bool IsChildItem(LayoutItemBase value)
        {
            return false;
        }
        private bool _IsKeyboardFocusWithin = false;
        /// 
        /// Gets whether keyboard focus is within the control which is assigned to the item.
        /// 
        [Browsable(false)]
        public bool IsKeyboardFocusWithin
        {
            get
            {
                return _IsKeyboardFocusWithin;
            }
            internal set
            {
                if (value != _IsKeyboardFocusWithin)
                {
                    _IsKeyboardFocusWithin = value;
                    this.Invalidate();
                }
            }
        }
        private Image _Image = null;
        /// 
        /// Indicates the image that is displayed next to the item text label.
        /// 
        [DefaultValue(null), Category("Appearance"), Description("Indicates the image that is displayed next to the item text label.")]
        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.InvalidateLayout();
        }
        private int _ImageTextSpacing = 4;
        /// 
        /// Specifies the distance between image and text.
        /// 
        [DefaultValue(4), Category("Appearance"), Description("Specifies the distance between image and text.")]
        public int ImageTextSpacing
        {
            get { return _ImageTextSpacing; }
            set
            {
                if (value != _ImageTextSpacing)
                {
                    int oldValue = _ImageTextSpacing;
                    _ImageTextSpacing = value;
                    OnImageTextSpacingChanged(oldValue, value);
                }
            }
        }
        /// 
        /// Called when ImageTextSpacing property has changed.
        /// 
        /// Old property value
        /// New property value
        protected virtual void OnImageTextSpacingChanged(int oldValue, int newValue)
        {
            OnPropertyChanged(new PropertyChangedEventArgs("ImageTextSpacing"));
            this.InvalidateLayout();
        }
        private eLayoutPosition _ImagePosition = eLayoutPosition.Default;
        /// 
        /// Indicates the position of the image in relation to the text label of item.
        /// 
        [DefaultValue(eLayoutPosition.Default), Category("Appearance"), Description("Indicates the position of the image in relation to the text label of item.")]
        public eLayoutPosition ImagePosition
        {
            get { return _ImagePosition; }
            set
            {
                if (value != _ImagePosition)
                {
                    eLayoutPosition oldValue = _ImagePosition;
                    _ImagePosition = value;
                    OnImagePositionChanged(oldValue, value);
                }
            }
        }
        /// 
        /// Called when ImagePosition property has changed.
        /// 
        /// Old property value
        /// New property value
        protected virtual void OnImagePositionChanged(eLayoutPosition oldValue, eLayoutPosition newValue)
        {
            OnPropertyChanged(new PropertyChangedEventArgs("ImagePosition"));
            this.InvalidateLayout();
        }
        private Rectangle _ActualImageBounds = Rectangle.Empty;
        /// 
        /// Gets actual image bounds if visible or Rectangle.Empty if image is not visible.
        /// 
        [Browsable(false)]
        public Rectangle ActualImageBounds
        {
            get { return _ActualImageBounds; }
            internal set { _ActualImageBounds = value; }
        }
        private Color _SymbolColor = Color.Empty;
        /// 
        /// Gets or sets the color of the Symbol.
        /// 
        [Category("Appearance"), Description("Indicates color of the Symbol.")]
        public Color SymbolColor
        {
            get { return _SymbolColor; }
            set { _SymbolColor = value; this.Invalidate(); }
        }
        /// 
        /// Gets whether property should be serialized.
        /// 
        [EditorBrowsable(EditorBrowsableState.Never)]
        public bool ShouldSerializeSymbolColor()
        {
            return !_SymbolColor.IsEmpty;
        }
        /// 
        /// Resets property to its default value.
        /// 
        [EditorBrowsable(EditorBrowsableState.Never)]
        public void ResetSymbolColor()
        {
            this.SymbolColor = Color.Empty;
        }
        private Size _SymbolTextSize = Size.Empty;
        private string _Symbol = "";
        /// 
        /// Indicates the symbol displayed on face of the item instead of the image. Setting the symbol overrides the image setting.
        /// 
        [DefaultValue(""), Category("Appearance"), Description("Indicates the symbol displayed on face of the button instead of the image. Setting the symbol overrides the image setting.")]
        [Editor("DevComponents.DotNetBar.Layout.Design.SymbolTypeEditor, DevComponents.DotNetBar.Layout.Design, Version=14.1.0.37, Culture=neutral,  PublicKeyToken=7eb7c3a35b91de04", typeof(System.Drawing.Design.UITypeEditor))]
        public string Symbol
        {
            get { return _Symbol; }
            set
            {
                if (value != _Symbol)
                {
                    string oldValue = _Symbol;
                    _Symbol = value;
                    OnSymbolChanged(oldValue, value);
                }
            }
        }
        /// 
        /// Called when Symbol property has changed.
        /// 
        /// Old property value
        /// New property value
        protected virtual void OnSymbolChanged(string oldValue, string newValue)
        {
            OnPropertyChanged(new PropertyChangedEventArgs("Symbol"));
            this.InvalidateLayout();
            this.Invalidate();
        }
        private float _SymbolSize = 0f;
        /// 
        /// 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 _SymbolSize; }
            set
            {
                if (value != _SymbolSize)
                {
                    float oldValue = _SymbolSize;
                    _SymbolSize = value;
                    OnSymbolSizeChanged(oldValue, value);
                }
            }
        }
        /// 
        /// Called when SymbolSize property has changed.
        /// 
        /// Old property value
        /// New property value
        protected virtual void OnSymbolSizeChanged(float oldValue, float newValue)
        {
            OnPropertyChanged(new PropertyChangedEventArgs("SymbolSize"));
            this.InvalidateLayout();
            this.Invalidate();
        }
        private bool _SharedTextSizeEnabled = true;
        /// 
        /// Indicates whether uniform text-size is used for text label. When shared text-size is used it ensures that all text-labels in LayoutControl use same text-size which is determined as largest text label size.
        /// 
        [DefaultValue(true), Category("Behavior"), Description("Indicates whether uniform text-size is used for text label. When shared text-size is used it ensures that all text-labels in LayoutControl use same text-size which is determined as largest text label size.")]
        public bool SharedTextSizeEnabled
        {
            get { return _SharedTextSizeEnabled; }
            set
            {
                if (value != _SharedTextSizeEnabled)
                {
                    bool oldValue = _SharedTextSizeEnabled;
                    _SharedTextSizeEnabled = value;
                    OnSharedTextSizeEnabledChanged(oldValue, value);
                }
            }
        }
        /// 
        /// Called when SharedTextSizeEnabled property has changed.
        /// 
        /// Old property value
        /// New property value
        protected virtual void OnSharedTextSizeEnabledChanged(bool oldValue, bool newValue)
        {
            OnPropertyChanged(new PropertyChangedEventArgs("SharedTextSizeEnabled"));
            this.InvalidateLayout();
            this.Invalidate();
        }
        /// 
        /// Brings item into view by scrolling the control if necessary.
        /// 
        public virtual void BringIntoView()
        {
            LayoutControl lc = GetLayoutControl();
            if (lc != null)
                lc.ScrollItemIntoView(this);
        }
        #endregion
        #region IDisposable Members
        protected virtual void OnDispose()
        {
            EventHandler eh = Disposed;
            if (eh != null) eh(this, EventArgs.Empty);
            _Style.PropertyChanged -= StylePropertyChanged;
        }
        public void Dispose()
        {
            OnDispose();
        }
        #endregion
        #region IComponent Members
        /// 
        /// Occurs when item is disposed.
        /// 
        [Description("Occurs when item is disposed.")]
        public event EventHandler Disposed;
        private string _Name = "";
        /// 
        /// Gets or sets the name of the item.
        /// 
        [DefaultValue(""), Category("Design"), Description("Indicates name of the item.")]
        public string Name
        {
            get
            {
                if (_ComponentSite != null)
                    _Name = _ComponentSite.Name;
                return _Name;
            }
            set
            {
                if (_ComponentSite != null)
                    _ComponentSite.Name = value;
                if (value == null)
                    _Name = "";
                else
                    _Name = value;
            }
        }
        private ISite _ComponentSite = null;
        /// 
        /// Gets or sets the Site associated with this component. Used by Windows forms designer.
        /// 
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public virtual System.ComponentModel.ISite Site
        {
            get
            {
                return _ComponentSite;
            }
            set
            {
                _ComponentSite = value;
            }
        }
        private bool _DesignMode = false;
        /// 
        /// Returns whether item is in design mode.
        /// 
        internal bool DesignMode
        {
            get
            {
                return _DesignMode || _ComponentSite != null && _ComponentSite.DesignMode;
            }
            set
            {
                _DesignMode = value;
            }
        }
        private bool _IsSelected = false;
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never)]
        public bool IsSelected
        {
            get { return _IsSelected; }
            set
            {
                if (value != _IsSelected)
                {
                    bool oldValue = _IsSelected;
                    _IsSelected = value;
                    OnIsSelectedChanged(oldValue, value);
                }
            }
        }
        /// 
        /// Called when IsSelected property has changed.
        /// 
        /// Old property value
        /// New property value
        protected virtual void OnIsSelectedChanged(bool oldValue, bool newValue)
        {
            OnPropertyChanged(new PropertyChangedEventArgs("IsSelected"));
            this.Invalidate();
        }
        public override string ToString()
        {
            return string.Format("Text:'{0}', Name:{1}, LayoutItemBase");
        }
        private eTextAlignment _TextAlignment = eTextAlignment.Default;
        /// 
        /// Indicates the text alignment within the text bounds. Depending on layout item type not all alignments are available.
        /// 
        [DefaultValue(eTextAlignment.Default), Category("Appearance"), Description("Indicates the text alignment within the text bounds.")]
        public eTextAlignment TextAlignment
        {
            get { return _TextAlignment; }
            set
            {
                if (value != _TextAlignment)
                {
                    eTextAlignment oldValue = _TextAlignment;
                    _TextAlignment = value;
                    OnTextAlignmentChanged(oldValue, value);
                }
            }
        }
        /// 
        /// Called when TextAlignment property has changed.
        /// 
        /// Old property value
        /// New property value
        protected virtual void OnTextAlignmentChanged(eTextAlignment oldValue, eTextAlignment newValue)
        {
            this.InvalidateLayout();
            this.Invalidate();
            OnPropertyChanged(new PropertyChangedEventArgs("TextAlignment"));
        }
        private eTextLineAlignment _TextLineAlignment = eTextLineAlignment.Default;
        /// 
        /// Indicates text line alignment. Usually there is no need to change this property value since Default setting will use text-base line so text-box text and captions align.
        /// 
        [DefaultValue(eTextLineAlignment.Default), Category("Appearance"), Description("Indicates text line alignment. Usually there is no need to change this property value since Default setting will use text-base line so text-box text and captions align.")]
        public eTextLineAlignment TextLineAlignment
        {
            get { return _TextLineAlignment; }
            set
            {
                if (value != _TextLineAlignment)
                {
                    eTextLineAlignment oldValue = _TextLineAlignment;
                    _TextLineAlignment = value;
                    OnTextLineAlignmentChanged(oldValue, value);
                }
            }
        }
        /// 
        /// Called when TextLineAlignment property has changed.
        /// 
        /// Old property value
        /// New property value
        protected virtual void OnTextLineAlignmentChanged(eTextLineAlignment oldValue, eTextLineAlignment newValue)
        {
            OnPropertyChanged(new PropertyChangedEventArgs("TextLineAlignment"));
            this.Invalidate();
        }
        /// 
        /// Gets whether this item text-size is shared with other items inside of its parent group.
        /// 
        [Browsable(false)]
        public virtual bool IsTextSizeShared
        {
            get
            {
                return _SharedTextSizeEnabled;
            }
        }
        /// 
        /// Gets whether this item's text-baseline is shared with other items inside of its parent group.
        /// 
        [Browsable(false)]
        public virtual bool IsTextBaselineShared
        {
            get
            {
                return true;
            }
        }
        private bool _Visible = true;
        /// 
        /// Indicates visibility of the item.
        /// 
        [DefaultValue(true), Category("Appearance"), Description("Indicates visibility of the item.")]
        public bool Visible
        {
            get { return _Visible; }
            set
            {
                if (value !=_Visible)
                {
                    bool oldValue = _Visible;
                    _Visible = value;
                    OnVisibleChanged(oldValue, value);
                }
            }
        }
        /// 
        /// Called when Visible property has changed.
        /// 
        /// Old property value
        /// New property value
        protected virtual void OnVisibleChanged(bool oldValue, bool newValue)
        {
            OnPropertyChanged(new PropertyChangedEventArgs("Visible"));
            InvalidateLayout();
        }
        #endregion
        #region TextMarkup
        /// 
        /// Occurs when text markup link is clicked. Markup links can be created using "a" tag, for example:
        /// Markup link
        /// 
        [Description("Occurs when text markup link is clicked. Markup links can be created using a tag.")]
        public event MarkupLinkClickEventHandler MarkupLinkClick;
        protected virtual void TextMarkupLinkClick(object sender, EventArgs e)
        {
            TextMarkup.HyperLink link = sender as TextMarkup.HyperLink;
            if (link != null)
                OnMarkupLinkClick(new MarkupLinkClickEventArgs(link.Name, link.HRef));
        }
        protected virtual void OnMarkupLinkClick(MarkupLinkClickEventArgs e)
        {
            if (this.MarkupLinkClick != null)
                MarkupLinkClick(this, e);
        }
        private TextMarkup.BodyElement _TextMarkup = null;
        private void MarkupTextChanged()
        {
            if (!IsMarkupSupported)
                return;
            if (_TextMarkup != null)
                _TextMarkup.HyperLinkClick -= this.TextMarkupLinkClick;
            _TextMarkup = null;
            if (!TextMarkup.MarkupParser.IsMarkup(ref _Text))
                return;
            _TextMarkup = TextMarkup.MarkupParser.Parse(_Text);
            if (_TextMarkup != null)
                _TextMarkup.HyperLinkClick += TextMarkupLinkClick;
        }
        /// 
        /// Gets reference to parsed markup body element if text was markup otherwise returns null.
        /// 
        internal TextMarkup.BodyElement TextMarkupBody
        {
            get { return _TextMarkup; }
        }
        private bool _TextMarkupEnabled = true;
        /// 
        /// Gets or sets whether item supports and renders text markup. Default value is true.
        /// 
        [DefaultValue(true), Category("Behavior"), Description("Gets or sets whether item supports and renders text markup.")]
        public bool TextMarkupEnabled
        {
            get { return _TextMarkupEnabled; }
            set
            {
                if (_TextMarkupEnabled != value)
                {
                    _TextMarkupEnabled = value;
                    this.InvalidateLayout();
                    this.Invalidate();
                }
            }
        }
        /// 
        /// Gets whether item supports text markup. Default is false.
        /// 
        protected virtual bool IsMarkupSupported
        {
            get { return _TextMarkupEnabled; }
        }
        private bool _IsMouseOver = false;
        /// 
        /// Gets whether mouse is over the item.
        /// 
        [Browsable(false)]
        internal bool IsMouseOver
        {
            get { return _IsMouseOver; }
            set
            {
                _IsMouseOver = value;
            }
        }
        private bool _HostedItemMouseEntered = false;
        protected internal virtual void OnMouseEnter(object sender, EventArgs e)
        {
            IsMouseOver = true;
            LayoutControl lc = GetLayoutControl();
            ResetHover(lc);
        }
        protected internal virtual void OnMouseMove(object sender, MouseEventArgs e)
        {
            if (_TextMarkup != null)
                _TextMarkup.MouseMove(sender as Control, e);
            if (!IsMouseOver) HideToolTip();
        }
        protected internal virtual void OnMouseDown(object sender, MouseEventArgs e)
        {
            HideToolTip();
            if (_TextMarkup != null)
                _TextMarkup.MouseDown(sender as Control, e);
        }
        protected internal virtual void OnMouseUp(object sender, MouseEventArgs e)
        {
            if (_TextMarkup != null)
                _TextMarkup.MouseUp(sender as Control, e);
        }
        protected internal virtual void OnMouseLeave(object sender, EventArgs e)
        {
            HideToolTip();
            if (_TextMarkup != null)
                _TextMarkup.MouseLeave(sender as Control);
            IsMouseOver = false;
        }
        protected internal virtual void OnClick(object sender, EventArgs e)
        {
            if (_TextMarkup != null)
                _TextMarkup.Click(sender as Control);
        }
        protected internal virtual void OnMouseHover(object sender, EventArgs e)
        {
            if (System.Windows.Forms.Control.MouseButtons == System.Windows.Forms.MouseButtons.None)
                this.ShowToolTip();
        }
        #endregion
        #region Tooltip Support
        /// 
        /// Occurs after Tooltip text has changed.
        /// 
        protected virtual void OnTooltipChanged() { }
        private string _Tooltip = "";
        /// 
        /// Gets/Sets informational text (tooltip) for the cell.
        /// 
        [Browsable(true), DefaultValue(""), Category("Appearance"), Description("Indicates the text that is displayed when mouse hovers over the cell."), Localizable(true)]
        public string Tooltip
        {
            get
            {
                return _Tooltip;
            }
            set
            {
                if (_Tooltip == value)
                    return;
                if (value == null) value = "";
                _Tooltip = value;
                if (this.ToolTipVisible)
                {
                    if (string.IsNullOrEmpty(_Tooltip))
                        this.HideToolTip();
                    else
                    {
                        DevComponents.DotNetBar.ToolTip tooltipWindow = _ToolTipWnd;
                        tooltipWindow.Text = _Tooltip;
                        tooltipWindow.ShowToolTip();
                        tooltipWindow.Invalidate();
                    }
                }
                OnTooltipChanged();
            }
        }
        /// 
        /// Gets whether tooltip is visible or not.
        /// 
        internal protected bool ToolTipVisible
        {
            get
            {
                return (_ToolTipWnd != null);
            }
        }
        /// 
        /// Called when tooltip is shown and hidden.
        /// 
        /// true if tooltip is being shown otherwise false.
        protected virtual void OnTooltip(bool isShown)
        {
        }
        private DevComponents.DotNetBar.ToolTip _ToolTipWnd = null;
        /// 
        /// Shows tooltip for this item.
        /// 
        public virtual void ShowToolTip()
        {
            if (this.DesignMode)
                return;
            LayoutControl lc = this.GetLayoutControl();
            if (lc != null && !lc.ShowToolTips || !this.ShowToolTips)
                return;
            OnTooltip(true);
            if (_Tooltip != "")
            {
                if (_ToolTipWnd == null)
                    _ToolTipWnd = new DevComponents.DotNetBar.ToolTip();
                _ToolTipWnd.Style = StyleManager.GetEffectiveStyle();
                _ToolTipWnd.Text = _Tooltip;
                _ToolTipWnd.ReferenceRectangle = ScreenRectangle;
                OnToolTipVisibleChanged(new EventArgs());
                _ToolTipWnd.ShowToolTip();
            }
        }
        /// 
        /// Destroys tooltip window.
        /// 
        internal protected void HideToolTip()
        {
            if (_ToolTipWnd != null)
            {
                System.Drawing.Rectangle tipRect = _ToolTipWnd.Bounds;
                tipRect.Width += 5;
                tipRect.Height += 6;
                OnTooltip(false);
                OnToolTipVisibleChanged(new EventArgs());
                try
                {
                    if (_ToolTipWnd != null)
                    {
                        _ToolTipWnd.Hide();
                        _ToolTipWnd.Dispose();
                        _ToolTipWnd = null;
                    }
                }
                catch { }
                LayoutControl lc = this.GetLayoutControl();
                if (lc != null)
                {
                    lc.Invalidate(lc.RectangleToClient(tipRect), false);
                }
            }
        }
        /// 
        /// Resets Hoover timer.
        /// 
        protected virtual void ResetHover(System.Windows.Forms.Control ctrl)
        {
            if (ctrl == null || ctrl.IsDisposed || !ctrl.IsHandleCreated)
                return;
            // We need to reset hover thing since it is fired only first time mouse hovers inside the window and we need it for each of our items
            WinApi.TRACKMOUSEEVENT tme = new WinApi.TRACKMOUSEEVENT();
            tme.dwFlags = WinApi.TME_QUERY;
            tme.hwndTrack = ctrl.Handle;
            tme.cbSize = System.Runtime.InteropServices.Marshal.SizeOf(tme);
            WinApi.TrackMouseEvent(ref tme);
            tme.dwFlags = tme.dwFlags | WinApi.TME_HOVER;
            WinApi.TrackMouseEvent(ref tme);
            ctrl = null;
        }
        /// 
        /// Occurs when item's tooltip visibility has changed.
        /// 
        [System.ComponentModel.Description("Occurs when item's tooltip visibility has changed.")]
        public event EventHandler ToolTipVisibleChanged;
        private void OnToolTipVisibleChanged(EventArgs eventArgs)
        {
            EventHandler h = ToolTipVisibleChanged;
            if (h != null)
                ToolTipVisibleChanged(this, eventArgs);
        }
        private Rectangle ScreenRectangle
        {
            get
            {
                LayoutControl lc = this.GetLayoutControl();
                if (lc == null) return Rectangle.Empty;
                return new Rectangle(lc.PointToScreen(this.Bounds.Location), this.Bounds.Size);
            }
        }
        private bool _ShowToolTips = true;
        /// 
        /// Gets or sets whether tooltips are shown when mouse is over the item when Tooltip property is set.
        /// 
        [DefaultValue(true), Category("Behavior"), Description("Indicates whether tooltips are shown when mouse is over the item when Tooltip property is set.")]
        public bool ShowToolTips
        {
            get { return _ShowToolTips; }
            set
            {
                _ShowToolTips = value;
            }
        }
        #endregion
        #region INotifyPropertyChanged Members
        /// 
        /// Raises the PropertyChanged event.
        /// 
        /// Provides event arguments.
        protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, e);
        }
        /// 
        /// Occurs when property on object has changed.
        /// 
        [Description("Occurs when property on object has changed.")]
        public event PropertyChangedEventHandler PropertyChanged;
        #endregion
    }
    /// 
    /// Specifies how layout items elements should be sized relative to their container.
    /// 
    public enum eLayoutSizeType
    {
        /// 
        /// The item should be sized to an exact number of pixels.
        /// 
        Absolute,
        /// 
        /// The item should be sized as a percentage of the parent container.
        /// 
        Percent,
    }
    /// 
    /// Contains values that specify how a specific element is positioned relative to another element.
    /// 
    public enum eLayoutPosition
    {
        /// 
        /// Default location, i.e. left.
        /// 
        Default = 0,
        /// 
        /// Item is located at the left edge of another item.
        /// 
        Left = 1,
        /// 
        /// Item is located at the right edge of another item.
        /// 
        Right = 2,
        /// 
        /// Item is located at the top edge of another item.
        /// 
        Top = 3,
        /// 
        /// Item is located at the bottom edge of another item.
        /// 
        Bottom = 4,
    }
    /// 
    /// Specifies layout text alignment within the text bounds.
    /// 
    public enum eTextAlignment
    {
        Default,
        Left,
        Right,
        Center
    }
    /// 
    /// Specifies layout text line alignment within the text bounds.
    /// 
    public enum eTextLineAlignment
    {
        Default,
        Top,
        Middle,
        Bottom
    }
    #region MarkupLinkClickEventArgs
    /// 
    /// Provides more information about MarkupLinkClick event.
    /// 
    public class MarkupLinkClickEventArgs : EventArgs
    {
        /// 
        /// Gets the value of href attribute from the markup link that was clicked.
        /// 
        public readonly string HRef = "";
        /// 
        /// Gets the value of name attribute from the markup link that was clicked.
        /// 
        public readonly string Name = "";
        /// 
        /// Creates new instance of the object.
        /// 
        /// Value of name attribute.
        /// Value of href attribute.
        public MarkupLinkClickEventArgs(string name, string href)
        {
            this.HRef = href;
            this.Name = name;
        }
    }
    /// 
    /// Defines delegate for MarkupLinkClick event.
    /// 
    public delegate void MarkupLinkClickEventHandler(object sender, MarkupLinkClickEventArgs e);
    #endregion
}