#if FRAMEWORK20
using System;
using System.Text;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Globalization;
using System.Data;
using System.Windows.Forms;
using DevComponents.DotNetBar;
using DevComponents.DotNetBar.Animation;
using DevComponents.DotNetBar.Rendering;
namespace DevComponents.Editors.DateTimeAdv
{
    /// 
    /// Represents the container that presents single calendar month.
    /// 
    [ToolboxItem(false), DesignTimeVisible(false), Designer("DevComponents.DotNetBar.Design.ItemContainerDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral,  PublicKeyToken=90f470f34c89ccaf")]
    public class SingleMonthCalendar : CalendarBase
    {
        private const string NavigationContainerName = "navigationContainer";
        #region Private Variables
        internal static readonly Size _DefaultDaySize = new Size(24, 15);
        internal static readonly Size _DefaultNavigationButtonSize = new Size(13, 18);
        private const string NavMonthLabel = "monthLabel";
        private const string NavYearLabel = "yearLabel";
        private const string NavDecreaseMonth = "decreaseMonth";
        private const string NavIncreaseMonth = "increaseMonth";
        private const string NavDecreaseYear = "decreaseYear";
        private const string NavIncreaseYear = "increaseYear";
        //private const string MonthsPopupMenu = "monthsPopupMenu";
        //private ButtonItem _MonthsPopupMenu = null;
        private YearSelectorControl _YearSelector = null;
        private MonthSelectorControl _MonthSelector = null;
        private YearSelectorContainer _YearSelectionItem = null;
        private MonthSelectorContainer _MonthSelectionItem = null;
        #endregion
        #region Events
        /// 
        /// Occurs when month displayed by the item has changed.
        /// 
        public event EventHandler MonthChanged;
        /// 
        /// Occurs before the month that is displayed is changed.
        /// 
        public event EventHandler MonthChanging;
        /// 
        /// Occurs when child label representing days is rendered and it allows you to override default rendering.
        /// 
        public event DayPaintEventHandler PaintLabel;
        /// 
        /// Occurs when mouse button is pressed over the day/week label inside of the calendar.
        /// 
        [System.ComponentModel.Description("Occurs when mouse button is pressed over the day/week label inside of the calendar.")]
        public event System.Windows.Forms.MouseEventHandler LabelMouseDown;
        /// 
        /// Occurs when mouse button is released over day/week label inside of the calendar.
        /// 
        [System.ComponentModel.Description("Occurs when mouse button is released over day/week label inside of the calendar.")]
        public event System.Windows.Forms.MouseEventHandler LabelMouseUp;
        /// 
        /// Occurs when mouse enters the day/week label inside of the calendar.
        /// 
        [System.ComponentModel.Description("Occurs when mouse enters the day/week label inside of the calendar.")]
        public event EventHandler LabelMouseEnter;
        /// 
        /// Occurs when mouse leaves the day/week label inside of the calendar.
        /// 
        [System.ComponentModel.Description("Occurs when mouse leaves the day/week label inside of the calendar.")]
        public event EventHandler LabelMouseLeave;
        /// 
        /// Occurs when mouse moves over the day/week label inside of the calendar.
        /// 
        [System.ComponentModel.Description("Occurs when mouse moves over the day/week label inside of the calendar.")]
        public event System.Windows.Forms.MouseEventHandler LabelMouseMove;
        /// 
        /// Occurs when mouse remains still inside an day/week label of the calendar for an amount of time.
        /// 
        [System.ComponentModel.Description("Occurs when mouse remains still inside an day/week label of the calendar for an amount of time.")]
        public event EventHandler LabelMouseHover;
        /// 
        /// Occurs when SelectedDate property has changed.
        /// 
        [System.ComponentModel.Description("Occurs when SelectedDate property has changed.")]
        public event EventHandler DateChanged;
        #endregion
        #region Constructor
        /// 
        /// Initializes a new instance of the CalendarMonth class.
        /// 
        public SingleMonthCalendar()
        {
            _FirstDayOfWeek = DateTimeInput.GetActiveCulture().DateTimeFormat.FirstDayOfWeek;
            m_IsContainer = true;
            this.AutoCollapseOnClick = true;
            this.MouseUpNotification = true;
            this.AccessibleRole = System.Windows.Forms.AccessibleRole.Grouping;
            _Colors.Parent = this;
            for (int i = 0; i < 49; i++)
            {
                DayLabel day = new DayLabel();
                day.Visible = false;
                this.SubItems.Add(day);
            }
            // Add navigation container
            Size fixedButtonSize = _DefaultNavigationButtonSize;
            ItemContainer cont = new ItemContainer();
            cont.Name = NavigationContainerName;
            cont.AutoCollapseOnClick = false;
            cont.MinimumSize = new Size(0, fixedButtonSize.Height + 3);
            cont.LayoutOrientation = eOrientation.Horizontal;
            cont.HorizontalItemAlignment = eHorizontalItemsAlignment.Center;
            cont.VerticalItemAlignment = eVerticalItemsAlignment.Middle;
            cont.ItemSpacing = 2;
            ButtonItem nav = new ButtonItem(NavDecreaseMonth);
            nav.GlobalItem = false;
            nav._FadeEnabled = false;
            nav.Text = "";
            nav.Click += new EventHandler(MonthNavigationDecreaseClick);
            nav.AutoCollapseOnClick = false;
            nav.FixedSize = fixedButtonSize;
            nav._FixedSizeCenterText = true;
            nav.ClickAutoRepeat = true;
            cont.SubItems.Add(nav);
            LabelItem label = new LabelItem(NavMonthLabel);
            label.AutoCollapseOnClick = false;
            label.GlobalItem = false;
            label.TextAlignment = StringAlignment.Center;
            label.TextLineAlignment = StringAlignment.Center;
            label.PaddingBottom = 2;
            label.Click += new EventHandler(ShowMonthSelection);
            label.Cursor = Cursors.Hand;
            cont.SubItems.Add(label);
            nav = new ButtonItem(NavIncreaseMonth);
            nav.GlobalItem = false;
            nav._FadeEnabled = false;
            nav.Text = "";
            nav.Click += new EventHandler(MonthNavigationIncreaseClick);
            nav.AutoCollapseOnClick = false;
            nav.FixedSize = fixedButtonSize;
            nav._FixedSizeCenterText = true;
            nav.ClickAutoRepeat = true;
            cont.SubItems.Add(nav);
            // Year Navigation
            nav = new ButtonItem(NavDecreaseYear);
            nav.GlobalItem = false;
            nav._FadeEnabled = false;
            nav.Text = "";
            nav.Click += new EventHandler(YearNavigationDecreaseClick);
            nav.AutoCollapseOnClick = false;
            nav.FixedSize = fixedButtonSize;
            nav._FixedSizeCenterText = true;
            nav.ClickAutoRepeat = true;
            cont.SubItems.Add(nav);
            label = new LabelItem(NavYearLabel);
            label.AutoCollapseOnClick = false;
            label.GlobalItem = false;
            label.TextAlignment = StringAlignment.Center;
            label.TextLineAlignment = StringAlignment.Center;
            label.PaddingBottom = 2;
            label.Click += ShowYearSelection;
            label.Cursor = Cursors.Hand;
            cont.SubItems.Add(label);
            nav = new ButtonItem(NavIncreaseYear);
            nav.GlobalItem = false;
            nav._FadeEnabled = false;
            nav.Text = "";
            nav.Click += new EventHandler(YearNavigationIncreaseClick);
            nav.AutoCollapseOnClick = false;
            nav.FixedSize = fixedButtonSize;
            nav._FixedSizeCenterText = true;
            nav.ClickAutoRepeat = true;
            cont.SubItems.Add(nav);
            //_MonthsPopupMenu = new ButtonItem(MonthsPopupMenu);
            //_MonthsPopupMenu.Visible = false;
            //cont.SubItems.Add(_MonthsPopupMenu);
            this.SubItems.Add(cont);
        }
        #endregion
        #region Internal Implementation
        private bool _MonthSelectionMode = false;
        /// 
        /// Indicates whether calendar is used in month selection mode which shows only month and year.
        /// 
        [DefaultValue(false), Category("Behavior"), Description("Indicates whether calendar is used in month selection mode which shows only month and year.")]
        public bool MonthSelectionMode
        {
            get { return _MonthSelectionMode; }
            set
            {
                if (value != _MonthSelectionMode)
                {
                    bool oldValue = _MonthSelectionMode;
                    _MonthSelectionMode = value;
                    OnMonthSelectionModeChanged(oldValue, value);
                }
            }
        }
        /// 
        /// Called when MonthSelectionMode property has changed.
        /// 
        /// Old property value
        /// New property value
        protected virtual void OnMonthSelectionModeChanged(bool oldValue, bool newValue)
        {
            if (newValue)
            {
                _MonthSelectionItem = new MonthSelectorContainer();
                _MonthSelectionItem.FixedSize = new Size(162, 140);
                if (_SelectedDate != DateTime.MinValue)
                    _MonthSelectionItem.SelectedMonth = this.SelectedDate.Month;
                _MonthSelectionItem.SelectedMonthChanged += new EventHandler(MonthSelectionItemSelectedMonthChanged);
                _MonthSelectionItem.UseMonthNames = _MonthSelectorShortMonthNames;
                this.SubItems.Add(_MonthSelectionItem);
                _YearSelectionItem = new YearSelectorContainer();
                _YearSelectionItem.FixedSize = new Size(162, 140);
                if (_SelectedDate != DateTime.MinValue)
                    _YearSelectionItem.SelectedYear = this.SelectedDate.Year;
                _YearSelectionItem.SelectedYearChanged += new EventHandler(YearSelectionItemSelectedYearChanged);
                this.SubItems.Add(_YearSelectionItem);
            }
            else
            {
                this.SubItems.Remove(_MonthSelectionItem);
                this.SubItems.Remove(_YearSelectionItem);
                _MonthSelectionItem.Dispose();
                _MonthSelectionItem = null;
                _YearSelectionItem.Dispose();
                _YearSelectionItem = null;
                this.DisplayMonth = _DisplayMonth;
            }
            NeedRecalcSize = true;
            OnAppearanceChanged();
            //OnPropertyChanged(new PropertyChangedEventArgs("MonthSelectionMode"));
        }
        internal void DropDownClosed()
        {
            if (_YearSelectionItem != null)
                _YearSelectionItem.RemoveCenturySelector();
        }
        void YearSelectionItemSelectedYearChanged(object sender, EventArgs e)
        {
            if (_SelectedDate != DateTime.MinValue)
            {
                DateTime dt=new DateTime(_YearSelectionItem.SelectedYear, _SelectedDate.Month, _SelectedDate.Day, _SelectedDate.Hour, _SelectedDate.Minute, _SelectedDate.Second, _SelectedDate.Kind);
                DisplayMonth = dt;
                this.SelectedDate = dt;
            }
            else if (!_MonthSelectionItem.IsEmpty)
            {
                DateTime dt = new DateTime(_YearSelectionItem.SelectedYear, _MonthSelectionItem.SelectedMonth, 1);
                DisplayMonth = dt;
                this.SelectedDate = dt;
            }
            //else 
            //    this.SelectedDate = new DateTime(_YearSelectionItem.SelectedYear, DateTime.Now.Month, 1);
        }
        void MonthSelectionItemSelectedMonthChanged(object sender, EventArgs e)
        {
            if (_SelectedDate != DateTime.MinValue)
            {
                int selectedDay = Math.Min(_SelectedDate.Day,
                    DateTimeInput.GetActiveCulture()
                        .Calendar.GetDaysInMonth(_SelectedDate.Year, _MonthSelectionItem.SelectedMonth));
                DateTime dt = new DateTime(_SelectedDate.Year, _MonthSelectionItem.SelectedMonth, selectedDay, _SelectedDate.Hour, _SelectedDate.Minute, _SelectedDate.Second, _SelectedDate.Kind);
                DisplayMonth = dt;
                this.SelectedDate = dt;
            }
            else if (_YearSelectionItem.SelectedYear > 0)
            {
                DateTime dt = new DateTime(_YearSelectionItem.SelectedYear, _MonthSelectionItem.SelectedMonth, 1);
                DisplayMonth = dt;
                this.SelectedDate = dt;
            }
        }
        private bool _YearSelectionEnabled = true;
        /// 
        /// Gets or sets whether Year/Century selection is enabled.
        /// 
        [DefaultValue(true), Category("Behavior"), Description("Indicates whether Year/Century selection is enabled.")]
        public bool YearSelectionEnabled
        {
            get { return _YearSelectionEnabled; }
            set
            {
                if (_YearSelectionEnabled != value)
                {
                    _YearSelectionEnabled = value;
                    ItemContainer nav = GetNavigationContainer();
                    if (nav != null)
                    {
                        LabelItem label = nav.SubItems[NavYearLabel] as LabelItem;
                        if (label != null)
                        {
                            label.Cursor = _YearSelectionEnabled ? Cursors.Hand : null;
                        }
                    }
                }
            }
        }
        private bool _MonthSelectorShortMonthNames = true;
        /// 
        /// Indicates whether month selector which is displayed when month label is clicked is using abbreviated month names instead of month number.
        /// 
        [DefaultValue(true), Category("Behavior"), Description("Indicates whether month selector which is displayed when month label is clicked is using abbreviated month names instead of month number.")]
        public bool MonthSelectorShortMonthNames
        {
            get { return _MonthSelectorShortMonthNames; }
            set
            {
                _MonthSelectorShortMonthNames = value;
                if (_MonthSelectionItem != null)
                    _MonthSelectionItem.UseMonthNames = _MonthSelectorShortMonthNames;
            }
        }
        private eCurrentSingleMonthCalendarOperation _CurrentOperation = eCurrentSingleMonthCalendarOperation.None;
        private void ShowYearSelection(object sender, EventArgs e)
        {
            if (_YearSelector != null || !_YearSelectionEnabled || _CurrentOperation != eCurrentSingleMonthCalendarOperation.None || this.Parent is MonthCalendarItem && (((MonthCalendarItem)this.Parent).CalendarDimensions.Width > 1 || ((MonthCalendarItem)this.Parent).CalendarDimensions.Height > 1))
                return;
            _CurrentOperation = eCurrentSingleMonthCalendarOperation.AnimatingShowYearSelector;
            _YearSelector = new YearSelectorControl();
            _YearSelector.Size = new Size(8, 8);
            _YearSelector.Location = new Point(this.LeftInternal + (this.WidthInternal - 8) / 2, this.TopInternal + (this.HeightInternal - 8) / 2);
            _YearSelector.Visible = true;
            _YearSelector.Style = eDotNetBarStyle.StyleManagerControlled;
            if (BarFunctions.IsOffice2007Style(this.Style))
            {
                Office2007ColorTable table = ((Office2007Renderer)GlobalManager.Renderer).ColorTable;
                ElementStyle es = (ElementStyle)table.StyleClasses[ElementStyleClassKeys.ItemPanelKey];
                _YearSelector.BackgroundStyle.BackColor = es.BackColor;
                _YearSelector.BackgroundStyle.BackColor2 = es.BackColor2;
            }
            else
                _YearSelector.BackgroundStyle.BackColor = SystemColors.Window;
            ItemContainer nav = GetNavigationContainer();
            LabelItem label = nav.SubItems[NavMonthLabel] as LabelItem;
            if (!StyleManager.IsMetro(this.EffectiveStyle))
                _YearSelector.YearSelector.TextColor = label.ForeColor;
            Control cc = (Control)this.ContainerControl;
            cc.Controls.Add(_YearSelector);
            _YearSelector.YearSelector.CenturyYearStart = (this.DisplayMonth.Year / 10) * 10;
            _YearSelector.YearSelector.SelectedYear = this.DisplayMonth.Year;
            Rectangle targetBounds = this.Bounds;
            _YearSelector.YearSelector.SelectedYearChanged += YearSelectorSelectedYearChanged;
            DevComponents.DotNetBar.Animation.AnimationRectangle anim = new DevComponents.DotNetBar.Animation.AnimationRectangle(
                new AnimationRequest(_YearSelector, "Bounds", targetBounds),
                DevComponents.DotNetBar.Animation.AnimationEasing.EaseInOutQuad, 200);
            anim.AutoDispose = true;
            anim.AnimationCompleted += ShowAnimationCompleted;
            anim.Start();
        }
        private void ShowAnimationCompleted(object sender, EventArgs e)
        {
            _CurrentOperation = eCurrentSingleMonthCalendarOperation.None;
        }
        private void YearSelectorSelectedYearChanged(object sender, EventArgs e)
        {
            if (_CurrentOperation != eCurrentSingleMonthCalendarOperation.None)
                return;
            RemoveYearSelector(true);
            DateTime newDisplayMonth = new DateTime(_YearSelector.YearSelector.SelectedYear, this.DisplayMonth.Month, this.DisplayMonth.Day);
            if (newDisplayMonth < MinDate)
                newDisplayMonth = MinDate;
            else if (newDisplayMonth > MaxDate)
                newDisplayMonth = MaxDate;
            SetDisplayMonth(newDisplayMonth.Month, newDisplayMonth.Year, eEventSource.Mouse);
        }
        private void RemoveYearSelector(bool animate)
        {
            if (_CurrentOperation == eCurrentSingleMonthCalendarOperation.AnimatingHideYearSelector) return;
            if (animate)
            {
                _CurrentOperation = eCurrentSingleMonthCalendarOperation.AnimatingHideYearSelector;
                Rectangle targetBounds = new Rectangle(this.LeftInternal + (this.WidthInternal - 8) / 2, this.TopInternal + (this.HeightInternal - 8) / 2, 8, 8);
                DevComponents.DotNetBar.Animation.AnimationRectangle anim = new DevComponents.DotNetBar.Animation.AnimationRectangle(
                    new AnimationRequest(_YearSelector, "Bounds", targetBounds),
                    DevComponents.DotNetBar.Animation.AnimationEasing.EaseInOutQuad, 200);
                anim.AnimationCompleted += AnimationCompleted;
                anim.Start();
            }
            else
            {
                if (_YearSelector.Parent != null)
                    _YearSelector.Parent.Controls.Remove(_YearSelector);
                _YearSelector.YearSelector.SelectedYearChanged -= YearSelectorSelectedYearChanged;
                _YearSelector.Dispose();
                _YearSelector = null;
            }
        }
        void AnimationCompleted(object sender, EventArgs e)
        {
            DevComponents.DotNetBar.Animation.AnimationRectangle anim = (DevComponents.DotNetBar.Animation.AnimationRectangle)sender;
            anim.Dispose();
            if (_YearSelector.Parent != null)
                _YearSelector.Parent.Controls.Remove(_YearSelector);
            _YearSelector.YearSelector.SelectedYearChanged -= YearSelectorSelectedYearChanged;
            _YearSelector.Dispose();
            _YearSelector = null;
            _CurrentOperation = eCurrentSingleMonthCalendarOperation.None;
        }
        private void ShowMonthSelection(object sender, EventArgs e)
        {
            if (_MonthSelector != null || _CurrentOperation != eCurrentSingleMonthCalendarOperation.None || this.Parent is MonthCalendarItem && (((MonthCalendarItem)this.Parent).CalendarDimensions.Width > 1 || ((MonthCalendarItem)this.Parent).CalendarDimensions.Height > 1))
                return;
            if (!HeaderNavigationEnabled) return;
            _CurrentOperation = eCurrentSingleMonthCalendarOperation.AnimatingShowMonthSelector;
            _MonthSelector = new MonthSelectorControl();
            _MonthSelector.Size = new Size(8, 8);
            _MonthSelector.Location = new Point(this.LeftInternal + (this.WidthInternal - 8) / 2, this.TopInternal + (this.HeightInternal - 8) / 2);
            _MonthSelector.MonthSelector.UseMonthNames = _MonthSelectorShortMonthNames;
            _MonthSelector.Visible = true;
            _MonthSelector.Style = eDotNetBarStyle.StyleManagerControlled;
            if (BarFunctions.IsOffice2007Style(this.Style))
            {
                Office2007ColorTable table = ((Office2007Renderer)GlobalManager.Renderer).ColorTable;
                ElementStyle es = (ElementStyle)table.StyleClasses[ElementStyleClassKeys.ItemPanelKey];
                _MonthSelector.BackgroundStyle.BackColor = es.BackColor;
                _MonthSelector.BackgroundStyle.BackColor2 = es.BackColor2;
            }
            else
                _MonthSelector.BackgroundStyle.BackColor = SystemColors.Window;
            ItemContainer nav = GetNavigationContainer();
            LabelItem label = nav.SubItems[NavMonthLabel] as LabelItem;
            if (!StyleManager.IsMetro(this.EffectiveStyle))
                _MonthSelector.MonthSelector.TextColor = label.ForeColor;
            Control cc = (Control)this.ContainerControl;
            cc.Controls.Add(_MonthSelector);
            _MonthSelector.MonthSelector.SelectedMonth = this.DisplayMonth.Month;
            Rectangle targetBounds = this.Bounds;
            _MonthSelector.MonthSelector.SelectedMonthChanged += MonthSelectorSelectedMonthChanged;
            DevComponents.DotNetBar.Animation.AnimationRectangle anim = new DevComponents.DotNetBar.Animation.AnimationRectangle(
                new AnimationRequest(_MonthSelector, "Bounds", targetBounds),
                DevComponents.DotNetBar.Animation.AnimationEasing.EaseInOutQuad, 200);
            anim.AutoDispose = true;
            anim.AnimationCompleted += ShowAnimationCompleted;
            anim.Start();
        }
        private void MonthSelectorSelectedMonthChanged(object sender, EventArgs e)
        {
            if (_CurrentOperation != eCurrentSingleMonthCalendarOperation.None)
                return;
            RemoveMonthSelector(true);
            DateTime newDisplayMonth = new DateTime(this.DisplayMonth.Year, _MonthSelector.MonthSelector.SelectedMonth, this.DisplayMonth.Day);
            if (newDisplayMonth < MinDate)
                newDisplayMonth = MinDate;
            else if (newDisplayMonth > MaxDate)
                newDisplayMonth = MaxDate;
            SetDisplayMonth(newDisplayMonth.Month, newDisplayMonth.Year, eEventSource.Mouse);
        }
        private void RemoveMonthSelector(bool animate)
        {
            if (_CurrentOperation == eCurrentSingleMonthCalendarOperation.AnimatingHideMonthSelector) return;
            if (animate)
            {
                _CurrentOperation = eCurrentSingleMonthCalendarOperation.AnimatingHideMonthSelector;
                Rectangle targetBounds = new Rectangle(this.LeftInternal + (this.WidthInternal - 8) / 2, this.TopInternal + (this.HeightInternal - 8) / 2, 8, 8);
                DevComponents.DotNetBar.Animation.AnimationRectangle anim = new DevComponents.DotNetBar.Animation.AnimationRectangle(
                    new AnimationRequest(_MonthSelector, "Bounds", targetBounds),
                    DevComponents.DotNetBar.Animation.AnimationEasing.EaseInOutQuad, 200);
                anim.AnimationCompleted += MonthSelectorAnimationCompleted;
                anim.Start();
            }
            else
            {
                if (_MonthSelector.Parent != null)
                    _MonthSelector.Parent.Controls.Remove(_MonthSelector);
                _MonthSelector.MonthSelector.SelectedMonthChanged -= MonthSelectorSelectedMonthChanged;
                _MonthSelector.Dispose();
                _MonthSelector = null;
            }
        }
        void MonthSelectorAnimationCompleted(object sender, EventArgs e)
        {
            DevComponents.DotNetBar.Animation.AnimationRectangle anim = (DevComponents.DotNetBar.Animation.AnimationRectangle)sender;
            anim.Dispose();
            if (_MonthSelector.Parent != null)
                _MonthSelector.Parent.Controls.Remove(_MonthSelector);
            _MonthSelector.MonthSelector.SelectedMonthChanged -= MonthSelectorSelectedMonthChanged;
            _MonthSelector.Dispose();
            _MonthSelector = null;
            _CurrentOperation = eCurrentSingleMonthCalendarOperation.None;
        }
        //private void ShowMonthSelectionPopupMenu(object sender, EventArgs e)
        //{
        //    if (!HeaderNavigationEnabled) return;
        //    ButtonItem parent = _MonthsPopupMenu;
        //    foreach (BaseItem item in parent.SubItems)
        //    {
        //        item.Click -= new EventHandler(PopupMonthSelectionClick);
        //    }
        //    parent.SubItems.Clear();
        //    string[] months = DateTimeInput.GetActiveCulture().DateTimeFormat.MonthNames;
        //    for (int i = 0; i < months.Length; i++)
        //    {
        //        if (months[i] == null || months[i].Length == 0) continue;
        //        ButtonItem m = new ButtonItem((i + 1).ToString(), months[i]);
        //        m.AutoCollapseOnClick = false;
        //        parent.SubItems.Add(m);
        //        m.Click += new EventHandler(PopupMonthSelectionClick);
        //    }
        //    parent.Popup(Control.MousePosition);
        //}
        private void PopupMonthSelectionClick(object sender, EventArgs e)
        {
            ButtonItem b = sender as ButtonItem;
            if (b == null) return;
            int month = int.Parse(b.Name);
            ((PopupItem)b.Parent).Expanded = false;
            SetDisplayMonth(month, this.DisplayMonth.Year, eEventSource.Mouse);
        }
        public override void RecalcSize()
        {
            Point innerLocation = m_Rect.Location;
            bool disposeStyle = false;
            ElementStyle style = ElementStyleDisplay.GetElementStyle(this.BackgroundStyle, out disposeStyle);
            innerLocation.X += ElementStyleLayout.LeftWhiteSpace(style); // m_BackgroundStyle.PaddingLeft + m_BackgroundStyle.MarginLeft;
            innerLocation.Y += ElementStyleLayout.TopWhiteSpace(style);
            if (_MonthSelectionMode)
            {
                foreach (BaseItem item in this.SubItems)
                {
                    item.Displayed = false;
                }
                _MonthSelectionItem.LeftInternal = innerLocation.X;
                _MonthSelectionItem.TopInternal = innerLocation.Y + 22;
                _MonthSelectionItem.RecalcSize();
                _MonthSelectionItem.Displayed = true;
                _YearSelectionItem.LeftInternal = innerLocation.X + _MonthSelectionItem.WidthInternal;
                _YearSelectionItem.TopInternal = innerLocation.Y;
                _YearSelectionItem.RecalcSize();
                _YearSelectionItem.Displayed = true;
                m_Rect.Width = _MonthSelectionItem.WidthInternal + _YearSelectionItem.WidthInternal;
                m_Rect.Height = Math.Max(_MonthSelectionItem.HeightInternal, _YearSelectionItem.HeightInternal);
                m_Rect.Width += ElementStyleLayout.HorizontalStyleWhiteSpace(style);
                m_Rect.Height += ElementStyleLayout.VerticalStyleWhiteSpace(style);
            }
            else
            {
                int c = 49;
                int itemsInLine = 0;
                int lineHeight = 0;
                int daysSpacing = 2;
                Point weekStartPoint = innerLocation;
                Point daysStartPoint = innerLocation;
                Size daySize = Dpi.Size(_DaySize);
                if (_ShowWeekNumbers)
                {
                    daysStartPoint.X += daySize.Width;
                }
                ItemContainer nav = GetNavigationContainer();
                nav.LeftInternal = innerLocation.X;
                nav.TopInternal = innerLocation.Y;
                nav.WidthInternal = daySize.Width * (_ShowWeekNumbers ? 8 : 7);
                nav.RecalcSize();
                nav.WidthInternal = daySize.Width * (_ShowWeekNumbers ? 8 : 7);
                weekStartPoint.Y += nav.HeightInternal + 1;
                daysStartPoint.Y += nav.HeightInternal + 1;
                Point p = daysStartPoint;
                int line = 0;
                for (int i = 0; i < c; i++)
                {
                    BaseItem item = this.SubItems[i];
                    if (item is YearSelectorContainer) continue;
                    DayLabel day = item as DayLabel;
                    if (day != null)
                    {
                        day.RecalcSize();
                        day.Bounds = new Rectangle(p, daySize);
                    }
                    else
                    {
                        item.RecalcSize();
                    }
                    if (item.Visible)
                    {
                        if (item.HeightInternal > lineHeight)
                            lineHeight = item.HeightInternal;
                        p.X += item.WidthInternal;
                    }
                    itemsInLine++;
                    if (itemsInLine == 7)
                    {
                        if (_ShowWeekNumbers)
                        {
                            if (line > 0)
                            {
                                DayLabel weekLabel = this.SubItems[c + line - 1] as DayLabel;
                                weekLabel.RecalcSize();
                                weekLabel.Bounds = new Rectangle(weekStartPoint, daySize);
                                weekStartPoint.Y += lineHeight;
                            }
                            else
                                weekStartPoint.Y += lineHeight + daysSpacing;
                        }
                        itemsInLine = 0;
                        p.Y += lineHeight;
                        if (line == 0) p.Y += daysSpacing;
                        p.X = daysStartPoint.X;
                        lineHeight = 0;
                        line++;
                    }
                }
                m_Rect.Width = daySize.Width * 7;
                m_Rect.Height = daySize.Height * 7 + daysSpacing;
                if (_ShowWeekNumbers)
                    m_Rect.Width += daySize.Width;
                m_Rect.Width += ElementStyleLayout.HorizontalStyleWhiteSpace(style);
                m_Rect.Height += ElementStyleLayout.VerticalStyleWhiteSpace(style) + nav.HeightInternal + 1;
            }
            if (disposeStyle) style.Dispose();
            base.RecalcSize();
        }
        /// 
        /// Must be overridden by class that is inheriting to provide the painting for the item.
        /// 
        public override void Paint(ItemPaintArgs p)
        {
            ItemContainer nav = GetNavigationContainer();
            LabelItem label = nav.SubItems[NavMonthLabel] as LabelItem;
            label.ForeColor = p.Colors.ItemText;
            label = nav.SubItems[NavYearLabel] as LabelItem;
            label.ForeColor = p.Colors.ItemText;
            base.Paint(p);
        }
        /// 
        /// Returns copy of the item.
        /// 
        public override BaseItem Copy()
        {
            SingleMonthCalendar objCopy = new SingleMonthCalendar();
            this.CopyToItem(objCopy);
            return objCopy;
        }
        /// 
        /// Copies the CalendarMonth specific properties to new instance of the item.
        /// 
        /// New ButtonItem instance.
        protected override void CopyToItem(BaseItem c)
        {
            SingleMonthCalendar copy = c as SingleMonthCalendar;
            base.CopyToItem(copy);
        }
        private void SetDisplayMonth(DateTime date, eEventSource source)
        {
            SetDisplayMonth(date.Month, date.Year, source);
        }
        private void SetDisplayMonth(int month, int year, eEventSource source)
        {
            DateTime d = new DateTime(year, month, 1);
            bool monthChanged = d != _DisplayMonth;
            if (_MonthSelectionMode)
            {
                _DisplayMonth = d;
                if (monthChanged)
                    OnMonthChanged(new DevComponents.DotNetBar.Events.EventSourceArgs(source));
                return;
            }
            if (monthChanged)
                OnMonthChanging(new DevComponents.DotNetBar.Events.EventSourceArgs(source));
            _DisplayMonth = d;
            // Initialize days
            string[] dayNames = DateTimeInput.GetActiveCulture().DateTimeFormat.AbbreviatedDayNames;
            string[] shortestDayNames = DateTimeInput.GetActiveCulture().DateTimeFormat.ShortestDayNames;
            if (_DayNames != null)
                dayNames = _DayNames;
            int firstDay = (int)_FirstDayOfWeek, currentDay = firstDay;
            for (int i = 0; i < 7; i++)
            {
                DayLabel day = this.SubItems[i] as DayLabel;
                day.Text = _TwoLetterDayName ? GetTwoLetterDayName(shortestDayNames[currentDay]) : dayNames[currentDay];
                day.Visible = true;
                day.Displayed = true;
                day.TrackMouse = false;
                day.Selectable = false;
                day.IsDayLabel = true;
                ApplyDayOfWeekMarker(day);
                currentDay++;
                if (currentDay > 6)
                    currentDay = 0;
            }
            // Recurring monthly markers
            bool[] monthlyMarkers = GetMonthlyMarkers();
            bool[] weeklyMarkers = GetWeeklyMarkers();
            bool[] annualMarkers = GetAnnualMarkers(month);
            bool[] markedDays = GetMarkedDays(month, year);
            DateTime today = _ShowTodayMarker ? (_TodayDate == DateTime.MinValue ? DateTime.Today : _TodayDate) : DateTime.MinValue;
            bool markToday = today != DateTime.MinValue;
            // Initialize days, If Visible=true, but Displayed=False item not displayed but takes space in layout. 
            // If Visible=false item not visible and does not take space in layout.
            int firstDayOfMonth = (int)d.DayOfWeek - firstDay;
            if (firstDayOfMonth < 0) firstDayOfMonth = 7 + firstDayOfMonth;
            int startIndex = 7;
            if (firstDayOfMonth > 0)
            {
                DateTime dt = d;
                dt = dt.AddDays(-firstDayOfMonth);
                annualMarkers = GetAnnualMarkers(dt.Month);
                markedDays = GetMarkedDays(dt.Month, dt.Year);
                for (int i = startIndex; i < startIndex + firstDayOfMonth; i++)
                {
                    DayLabel day = this.SubItems[i] as DayLabel;
                    day.Date = dt;
                    day.Visible = true;
                    ResetDayLabel(day);
                    if (weeklyMarkers[(int)dt.DayOfWeek])
                        ApplyWeeklyMarker(day);
                    if (monthlyMarkers[dt.Day - 1])
                        ApplyMonthlyMarker(day);
                    if (annualMarkers[dt.Day - 1])
                        ApplyAnnualMarker(day);
                    if (markedDays[dt.Day - 1])
                        ApplyDayMarker(day);
                    if (markToday && today == dt) day.IsToday = true;
                    if (!_WeekendDaysSelectable && DayLabel.IsWeekend(dt))
                    {
                        day.Selectable = false;
                        day.TrackMouse = false;
                    }
                    day.Enabled = CanSelect(dt);
                    day.Displayed = _TrailingDaysVisible && _TrailingDaysBeforeVisible;
                    day.IsTrailing = true;
                    dt = dt.AddDays(1);
                }
                startIndex += firstDayOfMonth;
            }
            annualMarkers = GetAnnualMarkers(month);
            markedDays = GetMarkedDays(month, year);
            bool newMonthFirstSwitch = true;
            int runningWeek = 0, dayCount = startIndex % 7;
            for (int i = startIndex; i < 49; i++)
            {
                DayLabel day = this.SubItems[i] as DayLabel;
                day.Date = d;
                ResetDayLabel(day);
                if (d.Month != month && newMonthFirstSwitch)
                {
                    annualMarkers = GetAnnualMarkers(d.Month);
                    markedDays = GetMarkedDays(d.Month, d.Year);
                    newMonthFirstSwitch = false;
                }
                if (weeklyMarkers[(int)d.DayOfWeek])
                    ApplyWeeklyMarker(day);
                if (monthlyMarkers[d.Day - 1])
                    ApplyMonthlyMarker(day);
                if (annualMarkers[d.Day - 1])
                    ApplyAnnualMarker(day);
                if (markedDays[d.Day - 1])
                    ApplyDayMarker(day);
                if (markToday && today == d) day.IsToday = true;
                if (!_WeekendDaysSelectable && DayLabel.IsWeekend(d))
                {
                    day.Selectable = false;
                    day.TrackMouse = false;
                }
                day.Enabled = CanSelect(d);
                day.Visible = true;
                if (d.Month != month)
                {
                    day.IsTrailing = true;
                    day.Displayed = _TrailingDaysVisible && _TrailingDaysAfterVisible;
                }
                else
                {
                    day.Displayed = true;
                    day.IsTrailing = false;
                    if (day.Date == _SelectedDate) day.IsSelected = true;
                }
                if (dayCount == 6)
                {
                    if (_ShowWeekNumbers)
                    {
                        DayLabel week = this.SubItems[49 + runningWeek] as DayLabel;
                        week.Text = DateTimeInput.GetActiveCulture().Calendar.GetWeekOfYear(d, _WeekOfYearRule, _FirstDayOfWeek).ToString();
                        week.Visible = true;
                        week.TrackMouse = false;
                        week.Selectable = false;
                        if (d.Month != month && d.AddDays(-dayCount).Month != month)
                            week.Displayed = _TrailingDaysVisible;
                        else
                            week.Displayed = true;
                        ApplyWeekOfYearMarker(week);
                    }
                    runningWeek++;
                    dayCount = -1;
                }
                d = d.AddDays(1);
                dayCount++;
            }
            // Update Navigation Container
            ItemContainer nav = GetNavigationContainer();
            nav.Visible = true;
            nav.Displayed = true;
            LabelItem label = nav.SubItems[NavMonthLabel] as LabelItem;
            //Size daySize = Dpi.Size(_DaySize);
            label.Width = _DaySize.Width * 3;
            label.Text = DateTimeInput.GetActiveCulture().DateTimeFormat.MonthNames[month - 1];
            label = nav.SubItems[NavYearLabel] as LabelItem;
            label.Text = year.ToString();
            label.Width = (int)(_DaySize.Width * 1.4);
            // Enable/disable navigation buttons
            UpdateNavigationButtonsEnabled();
            this.OnAppearanceChanged();
            this.Refresh();
            if (monthChanged)
            {
                OnMonthChanged(new DevComponents.DotNetBar.Events.EventSourceArgs(source));
                if (_YearSelector != null)
                    RemoveYearSelector(false);
                if (_MonthSelector != null)
                    RemoveMonthSelector(false);
            }
        }
        private void UpdateNavigationButtonsEnabled()
        {
            // Enable/disable navigation buttons
            ItemContainer nav = GetNavigationContainer();
            DateTime d = _DisplayMonth.AddMonths(_NavigationMonthsAheadVisibility);
            if (d > this.MaxDate)
            {
                nav.SubItems[NavIncreaseMonth].Enabled = false;
                nav.SubItems[NavIncreaseYear].Enabled = false;
            }
            else
            {
                nav.SubItems[NavIncreaseMonth].Enabled = true;
                d = _DisplayMonth.AddYears(1);
                nav.SubItems[NavIncreaseYear].Enabled = (MaxDate > d);
            }
            d = _DisplayMonth.AddMonths(-1);
            if (d < GetBeginningOfTheMonth(this.MinDate))
            {
                nav.SubItems[NavDecreaseMonth].Enabled = false;
                nav.SubItems[NavDecreaseYear].Enabled = false;
            }
            else
            {
                nav.SubItems[NavDecreaseMonth].Enabled = true;
                d = _DisplayMonth.AddYears(-1);
                nav.SubItems[NavDecreaseYear].Enabled = (d > MinDate);
            }
            d = _DisplayMonth;
            if (this.MinDate != DateTimeGroup.MinDateTime && d.Year > this.MinDate.Year && d.Month>=this.MinDate.Month)
                nav.SubItems[NavDecreaseYear].Enabled = true;
        }
        private DateTime GetBeginningOfTheMonth(DateTime date)
        {
            if (date.Day > 1)
                date = date.AddDays(-date.Day);
            return date;
        }
        private bool CanSelect(DateTime d)
        {
            if (d > MaxDate || d < MinDate)
                return false;
            return true;
        }
        private void ApplyWeekOfYearMarker(DayLabel day)
        {
            MonthCalendarColors c = GetColors();
            if (c == null || !c.WeekOfYear.IsCustomized) return;
            ApplyMarker(day, c.WeekOfYear);
        }
        private void ApplyDayOfWeekMarker(DayLabel day)
        {
            MonthCalendarColors c = GetColors();
            if (c == null || !c.DayLabel.IsCustomized) return;
            ApplyMarker(day, c.DayLabel);
        }
        private void ApplyDayMarker(DayLabel day)
        {
            MonthCalendarColors c = GetColors();
            if (c == null || !c.DayMarker.IsCustomized) return;
            ApplyMarker(day, c.DayMarker);
        }
        private bool[] GetMarkedDays(int month, int year)
        {
            bool[] markers = new bool[31];
            if (this.Parent is MonthCalendarItem)
            {
                MonthCalendarItem mc = this.Parent as MonthCalendarItem;
                DateTime[] dates = mc.MarkedDates;
                foreach (DateTime d in dates)
                {
                    if (d.Month == month && d.Year == year)
                    {
                        markers[d.Day - 1] = true;
                    }
                }
            }
            return markers;
        }
        private void ApplyAnnualMarker(DayLabel day)
        {
            MonthCalendarColors c = GetColors();
            if (c == null || !c.AnnualMarker.IsCustomized) return;
            ApplyMarker(day, c.AnnualMarker);
        }
        internal MonthCalendarColors GetColors()
        {
            MonthCalendarItem mc = this.Parent as MonthCalendarItem;
            MonthCalendarColors c = null;
            if (mc != null)
                c = mc.Colors;
            else
                c = _Colors;
            return c;
        }
        private void ApplyWeeklyMarker(DayLabel day)
        {
            MonthCalendarColors c = GetColors();
            if (c == null || !c.WeeklyMarker.IsCustomized) return;
            ApplyMarker(day, c.WeeklyMarker);
        }
        private void ApplyMonthlyMarker(DayLabel day)
        {
            MonthCalendarColors c = GetColors();
            if (c == null || !c.MonthlyMarker.IsCustomized) return;
            ApplyMarker(day, c.MonthlyMarker);
        }
        private void ApplyMarker(DayLabel day, DateAppearanceDescription c)
        {
            day.BackgroundStyle.BackColor = c.BackColor;
            day.BackgroundStyle.BackColor2 = c.BackColor2;
            day.BackgroundStyle.BackColorGradientAngle = c.BackColorGradientAngle;
            if (!c.BorderColor.IsEmpty)
            {
                day.BackgroundStyle.Border = eStyleBorderType.Solid;
                day.BackgroundStyle.BorderColor = c.BorderColor;
                day.BackgroundStyle.BorderWidth = 1;
            }
            day.IsBold = c.IsBold;
            if (!c.TextColor.IsEmpty)
                day.TextColor = c.TextColor;
            day.Selectable = c.Selectable;
            if (!c.Selectable)
                day.TrackMouse = false;
        }
        private bool[] GetMonthlyMarkers()
        {
            bool[] markers = new bool[31];
            if (this.Parent is MonthCalendarItem)
            {
                MonthCalendarItem mc = this.Parent as MonthCalendarItem;
                DateTime[] dates = mc.MonthlyMarkedDates;
                foreach (DateTime d in dates)
                {
                    markers[d.Day - 1] = true;
                }
            }
            return markers;
        }
        private bool[] GetAnnualMarkers(int month)
        {
            bool[] markers = new bool[31];
            if (this.Parent is MonthCalendarItem)
            {
                MonthCalendarItem mc = this.Parent as MonthCalendarItem;
                DateTime[] dates = mc.AnnuallyMarkedDates;
                foreach (DateTime d in dates)
                {
                    if (d.Month == month)
                    {
                        markers[d.Day - 1] = true;
                    }
                }
            }
            return markers;
        }
        private bool[] GetWeeklyMarkers()
        {
            bool[] markers = new bool[7];
            if (this.Parent is MonthCalendarItem)
            {
                MonthCalendarItem mc = this.Parent as MonthCalendarItem;
                DayOfWeek[] days = mc.WeeklyMarkedDays;
                foreach (DayOfWeek d in days)
                {
                    markers[(int)d] = true;
                }
            }
            return markers;
        }
        private ItemContainer GetNavigationContainer()
        {
            return this.SubItems[NavigationContainerName] as ItemContainer;
        }
        private void ResetDayLabel(DayLabel day)
        {
            day.IsSelected = false;
            day.Selectable = true;
            day.TrackMouse = true;
            day.IsToday = false;
            day.IsBold = false;
            day.Image = null;
            day.ImageAlign = eLabelPartAlignment.MiddleRight;
            day.TextAlign = _DefaultDayLabelTextAlign;
            day.TextColor = Color.Empty;
            day.Tooltip = "";
            day.ExpandOnMouseDown = false;
            day.SubItems.Clear();
            day.BackgroundStyle. Reset();
        }
        /// 
        /// Raises the MonthChanged event.
        /// 
        /// Provides additional event data.
        protected virtual void OnMonthChanged(EventArgs e)
        {
            if (MonthChanged != null)
                MonthChanged(this, e);
        }
        /// 
        /// Raises the MonthChanging event.
        /// 
        /// Provides additional event data.
        protected virtual void OnMonthChanging(EventArgs e)
        {
            if (MonthChanging != null)
                MonthChanging(this, e);
        }
        private DateTime _DisplayMonth = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
        [Description("")]
        public DateTime DisplayMonth
        {
            get { return _DisplayMonth; }
            set
            {
                if (value < MinDate)
                    value = MinDate;
                else if (value > MaxDate)
                    value = MaxDate;
                //if (value > MaxDate || value < MinDate)
                //{
                //    throw new ArgumentException("DisplayMonth must be less than MaxDate and greater than MinDate");
                //}
                SetDisplayMonth(value.Month, value.Year, eEventSource.Code);
            }
        }
        private string GetTwoLetterDayName(string s)
        {
            if (s.Length > 2)
                return s.Substring(0, 2);
            return s;
        }
        private DayOfWeek _FirstDayOfWeek = DayOfWeek.Sunday;
        /// 
        /// Gets or sets the first day of week displayed on the calendar. Default value is Sunday.
        /// 
        [DefaultValue(DayOfWeek.Sunday), Description("Indicates first day of week displayed on the calendar.")]
        public DayOfWeek FirstDayOfWeek
        {
            get { return _FirstDayOfWeek; }
            set
            {
                if (_FirstDayOfWeek != value)
                {
                    _FirstDayOfWeek = value;
                    SetDisplayMonth(_DisplayMonth.Month, _DisplayMonth.Year, eEventSource.Code);
                }
            }
        }
        internal bool _TrailingDaysVisible = true;
        /// 
        /// Gets or sets whether trailing days outside of the current displayed month are visible on calendar.
        /// 
        [DefaultValue(true)]
        public bool TrailingDaysVisible
        {
            get { return _TrailingDaysVisible; }
            set
            {
                if (_TrailingDaysVisible != value)
                {
                    _TrailingDaysVisible = value;
                    OnTrailingDaysVisibleChanged();
                }
            }
        }
        internal bool _TrailingDaysBeforeVisible = true;
        internal bool TrailingDaysBeforeVisible
        {
            get { return _TrailingDaysBeforeVisible; }
            set
            {
                if (_TrailingDaysBeforeVisible != value)
                {
                    _TrailingDaysBeforeVisible = value;
                    OnTrailingDaysVisibleChanged();
                }
            }
        }
        internal bool _TrailingDaysAfterVisible = true;
        internal bool TrailingDaysAfterVisible
        {
            get { return _TrailingDaysAfterVisible; }
            set
            {
                if (_TrailingDaysAfterVisible != value)
                {
                    _TrailingDaysAfterVisible = value;
                    OnTrailingDaysVisibleChanged();
                }
            }
        }
        private void OnTrailingDaysVisibleChanged()
        {
            if (_MonthSelectionMode) return;
            foreach (BaseItem item in this.SubItems)
            {
                DayLabel day = item as DayLabel;
                if (day != null && day.IsTrailing)
                {
                    bool visible = _TrailingDaysVisible;
                    if (day.Date < this.DisplayMonth)
                        visible &= _TrailingDaysBeforeVisible;
                    else
                        visible &= _TrailingDaysAfterVisible;
                    day.Displayed = visible;
                }
            }
            this.Refresh();
        }
        private bool _ShowWeekNumbers = false;
        /// 
        /// Gets or sets whether week of year is visible. Default value is false.
        /// 
        [DefaultValue(false), Description("Indicates whether week of year is visible.")]
        public bool ShowWeekNumbers
        {
            get { return _ShowWeekNumbers; }
            set
            {
                if (_ShowWeekNumbers != value)
                {
                    _ShowWeekNumbers = value;
                    OnShowWeekNumbersChanged();
                    NeedRecalcSize = true;
                    OnAppearanceChanged();
                }
            }
        }
        private void OnShowWeekNumbersChanged()
        {
            if (_ShowWeekNumbers)
            {
                // Add week of year labels, always after the days 
                for (int i = 0; i < 6; i++)
                {
                    DayLabel week = new DayLabel();
                    week.IsWeekOfYear = true;
                    this.SubItems.Insert(49 + i, week);
                }
            }
            else
            {
                // Remove week of year labels
                for (int i = 0; i < 7; i++)
                {
                    DayLabel week = this.SubItems[49] as DayLabel;
                    if (week != null && week.IsWeekOfYear)
                        this.SubItems.Remove(49);
                }
            }
        }
        private CalendarWeekRule _WeekOfYearRule = CalendarWeekRule.FirstDay;
        /// 
        /// Gets or sets the rule used to determine first week of the year for week of year display on calendar. Default value is first-day.
        /// 
        [DefaultValue(CalendarWeekRule.FirstDay), Description("Indicates rule used to determine first week of the year for week of year display on calendar.")]
        public CalendarWeekRule WeekOfYearRule
        {
            get { return _WeekOfYearRule; }
            set
            {
                _WeekOfYearRule = value;
                if (_ShowWeekNumbers)
                    this.OnAppearanceChanged();
            }
        }
        /// 
        /// Returns the collection of sub items.
        /// 
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override SubItemsCollection SubItems
        {
            get
            {
                return base.SubItems;
            }
        }
        private Size _DaySize = _DefaultDaySize;
        /// 
        /// Gets or sets the size of each day item on the calendar. Default value is 24, 15.
        /// 
        [Description("Indicate size of each day item on the calendar.")]
        public Size DaySize
        {
            get { return _DaySize; }
            set
            {
                _DaySize = value;
                OnDaySizeChanged();
            }
        }
        private void OnDaySizeChanged()
        {
            ItemContainer ic = GetNavigationContainer();
            Size daySize = _DaySize;
            if (ic.MinimumSize.Height < daySize.Height)
                ic.MinimumSize = new Size(ic.MinimumSize.Width, daySize.Height);
            OnAppearanceChanged();
        }
        /// 
        /// Gets whether property should be serialized. Provided for designer support.
        /// 
        /// 
        [EditorBrowsable(EditorBrowsableState.Never)]
        public bool ShouldSerializeDaySize()
        {
            return _DaySize.Width != _DefaultDaySize.Width || _DaySize.Height != _DefaultDaySize.Height;
        }
        /// 
        /// Reset property to default value. Provided for designer support.
        /// 
        [EditorBrowsable(EditorBrowsableState.Never)]
        public void ResetDaySize()
        {
            this.DaySize = _DefaultDaySize;
        }
        private Size _NavigationButtonSize = _DefaultNavigationButtonSize;
        /// 
        /// Gets or sets the size of date navigation buttons on the calendar. Default value is 13, 18. If you increase size of the navigation
        /// buttons change DaySize as well so everything fits.
        /// 
        [Description("Indicate size of date navigation buttons on the calendar. If you increase size of the navigation buttons change DaySize as well so everything fits.")]
        public Size NavigationButtonSize
        {
            get { return _NavigationButtonSize; }
            set
            {
                _NavigationButtonSize = value;
                OnNavigationButtonSizeChanged();
            }
        }
        protected override void ScaleItem(SizeF factor)
        {
            base.ScaleItem(factor);
            OnNavigationButtonSizeChanged();
        }
        private void OnNavigationButtonSizeChanged()
        {
            Size fixedButtonSize = _NavigationButtonSize;
            ItemContainer cont = GetNavigationContainer();
            cont.MinimumSize = new Size(0, fixedButtonSize.Height + 3);
            ButtonItem nav = (ButtonItem)cont.SubItems[NavDecreaseMonth];
            nav.FixedSize = fixedButtonSize;
            nav = (ButtonItem)cont.SubItems[NavIncreaseMonth];
            nav.FixedSize = fixedButtonSize;
            nav = (ButtonItem)cont.SubItems[NavDecreaseYear];
            nav.FixedSize = fixedButtonSize;
            nav = (ButtonItem)cont.SubItems[NavIncreaseYear];
            nav.FixedSize = fixedButtonSize;
            OnAppearanceChanged();
        }
        /// 
        /// Gets whether property should be serialized. Provided for designer support.
        /// 
        /// 
        [EditorBrowsable(EditorBrowsableState.Never)]
        public bool ShouldSerializeNavigationButtonSize()
        {
            return _NavigationButtonSize.Width != _DefaultNavigationButtonSize.Width || _NavigationButtonSize.Height != _DefaultNavigationButtonSize.Height;
        }
        /// 
        /// Reset property to default value. Provided for designer support.
        /// 
        [EditorBrowsable(EditorBrowsableState.Never)]
        public void ResetNavigationButtonSize()
        {
            this.NavigationButtonSize = _DefaultNavigationButtonSize;
        }
        /// 
        /// Raises the PaintLabel event.
        /// 
        /// Provides event data.
        internal void OnPaintLabel(DayLabel label, DayPaintEventArgs e)
        {
            if (PaintLabel != null)
                PaintLabel(label, e);
        }
        private MonthCalendarColors _Colors = new MonthCalendarColors();
        /// 
        /// Gets the calendar colors used by the control.
        /// 
        [NotifyParentPropertyAttribute(true), Category("Appearance"), Description("Gets colors used by control."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public MonthCalendarColors Colors
        {
            get { return _Colors; }
        }
        internal void DayLabelClick(DayLabel day)
        {
            if (!_MouseSelectionEnabled) return;
            if (day.Selectable && day.Date != DateTime.MinValue)
            {
                if (!_WeekendDaysSelectable && DayLabel.IsWeekend(day.Date))
                    return;
                if (MultiSelect)
                {
                    if (_SelectedDate == DateTime.MinValue)
                        _SelectedDate = day.Date;
                    day.IsSelected = !day.IsSelected;
                }
                else
                {
                    SelectedDate = day.Date;
                }
            }
        }
        private bool _MultiSelect = false;
        /// 
        /// Gets or sets whether multiple days can be selected by clicking each day. Default value is false.
        /// 
        [DefaultValue(false), Description("Indicates whether multiple days can be selected by clicking each day.")]
        public bool MultiSelect
        {
            get { return _MultiSelect; }
            set
            {
                if (_MultiSelect != value)
                {
                    _MultiSelect = value;
                }
            }
        }
        private bool _MouseSelectionEnabled = true;
        /// 
        /// Gets or sets whether selection of dates using mouse is enabled. Default value is true.
        /// 
        [DefaultValue(true), Description("Indicates whether selection of dates using mouse is enabled.")]
        public bool MouseSelectionEnabled
        {
            get { return _MouseSelectionEnabled; }
            set
            {
                if (_MouseSelectionEnabled != value)
                {
                    _MouseSelectionEnabled = value;
                }
            }
        }
        private DateTime _SelectedDate = DateTime.MinValue;
        /// 
        /// Gets or sets the calendar selected date.
        /// 
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public DateTime SelectedDate
        {
            get { return _SelectedDate; }
            set
            {
                _SelectedDate = value;
                foreach (BaseItem item in this.SubItems)
                {
                    DayLabel day = item as DayLabel;
                    if (day == null || day.Date == DateTime.MinValue) continue;
                    if (day.Date == _SelectedDate.Date)
                    {
                        day.IsSelected = true;
                    }
                    else
                    {
                        day.IsSelected = false;
                    }
                }
                if (_MonthSelectionMode)
                {
                    if (value != DateTime.MinValue && value != DateTime.MaxValue)
                    {
                        _MonthSelectionItem.SelectedMonth = _SelectedDate.Month;
                        _YearSelectionItem.SelectedYear = _SelectedDate.Year;
                    }
                    else
                    {
                        _MonthSelectionItem.IsEmpty = true;
                        _YearSelectionItem.SelectedYear = 0;
                    }
                }
                OnSelectedDateChanged(new EventArgs());
            }
        }
        /// 
        /// Raises the DateChanged event.
        /// 
        /// Provides event data.
        protected virtual void OnSelectedDateChanged(EventArgs e)
        {
            if (DateChanged != null)
                DateChanged(this, e);
        }
        private bool _WeekendDaysSelectable = true;
        /// 
        /// Gets or sets whether weekend days can be selected. Default value is true.
        /// 
        [DefaultValue(true), Description("Indicates whether weekend days can be selected.")]
        public bool WeekendDaysSelectable
        {
            get { return _WeekendDaysSelectable; }
            set
            {
                if (_WeekendDaysSelectable != value)
                {
                    _WeekendDaysSelectable = value;
                    SetDisplayMonth(_DisplayMonth.Month, _DisplayMonth.Year, eEventSource.Code);
                }
            }
        }
        /// 
        /// Gets the DayLabel item assigned to the given date. Returns null if there is no label displayed for the date.
        /// 
        /// Date to return label for.
        /// DayLabel instance or null if date is not displayed on this calendar.
        public DayLabel GetDayLabel(DateTime date)
        {
            foreach (BaseItem item in this.SubItems)
            {
                DayLabel day = item as DayLabel;
                if (day != null && day.Date.Date == date.Date && day.Visible && day.Displayed)
                    return day;
            }
            return null;
        }
        /// 
        /// Gets or sets a value indicating whether the item is expanded or not. For Popup items this would indicate whether the item is popped up or not.
        /// 
        [System.ComponentModel.Browsable(false), System.ComponentModel.DefaultValue(false), System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden)]
        public override bool Expanded
        {
            get
            {
                return m_Expanded;
            }
            set
            {
                base.Expanded = value;
                if (!value)
                    BaseItem.CollapseSubItems(this);
            }
        }
        /// 
        /// Occurs when sub item expanded state has changed.
        /// 
        /// Sub item affected.
        protected internal override void OnSubItemExpandChange(BaseItem item)
        {
            base.OnSubItemExpandChange(item);
            if (item.Expanded)
                this.Expanded = true;
        }
        private eLabelPartAlignment _DefaultDayLabelTextAlign = eLabelPartAlignment.MiddleCenter;
        /// 
        /// Gets or sets default text alignment for the DayLabel items representing calendar days.
        /// 
        [DefaultValue(eLabelPartAlignment.MiddleCenter), Description("Indicates default text alignment for the DayLabel items representing calendar days.")]
        public eLabelPartAlignment DefaultDayLabelTextAlign
        {
            get { return _DefaultDayLabelTextAlign; }
            set
            {
                if (_DefaultDayLabelTextAlign != value)
                {
                    _DefaultDayLabelTextAlign = value;
                    SetDisplayMonth(_DisplayMonth.Month, _DisplayMonth.Year, eEventSource.Code);
                    this.Refresh();
                }
            }
        }
        internal void OnLabelMouseDown(DayLabel sender, MouseEventArgs e)
        {
            if (LabelMouseDown != null)
                LabelMouseDown(sender, e);
        }
        internal void OnLabelMouseUp(DayLabel sender, MouseEventArgs e)
        {
            if (LabelMouseUp != null)
                LabelMouseUp(sender, e);
        }
        internal void OnLabelMouseEnter(DayLabel sender, EventArgs e)
        {
            if (LabelMouseEnter != null)
                LabelMouseEnter(sender, e);
        }
        internal void OnLabelMouseLeave(DayLabel sender, EventArgs e)
        {
            if (LabelMouseLeave != null)
                LabelMouseLeave(sender, e);
        }
        internal void OnLabelMouseMove(DayLabel sender, MouseEventArgs e)
        {
            if (LabelMouseMove != null)
                LabelMouseMove(sender, e);
        }
        internal void OnLabelMouseHover(DayLabel sender, EventArgs e)
        {
            if (LabelMouseHover != null)
                LabelMouseHover(sender, e);
        }
        private bool _TwoLetterDayName = true;
        /// 
        /// Gets or sets whether control uses the two letter day names. Default value is true.
        /// 
        [DefaultValue(true), Description("Indicates whether control uses the two letter day names.")]
        public bool TwoLetterDayName
        {
            get { return _TwoLetterDayName; }
            set
            {
                if (_TwoLetterDayName != value)
                {
                    _TwoLetterDayName = value;
                    SetDisplayMonth(_DisplayMonth.Month, _DisplayMonth.Year, eEventSource.Code);
                    this.Refresh();
                }
            }
        }
        private string[] _DayNames = null;
        /// 
        /// Gets or sets the array of custom names for days displayed on calendar header. The array must have exactly 7 elements representing day names from 0 to 6.
        /// 
        [DefaultValue(null), Description("Indicates array of custom names for days displayed on calendar header."), Localizable(true)]
        public string[] DayNames
        {
            get { return _DayNames; }
            set
            {
                if (value != null && value.Length != 7)
                    throw new ArgumentException("DayNames must have exactly 7 items in collection.");
                _DayNames = value;
            }
        }
        private void MonthNavigationDecreaseClick(object sender, EventArgs e)
        {
            SetDisplayMonth(_DisplayMonth.AddMonths(-1), eEventSource.Mouse);
            if (AutoSelectDate())
                this.SelectedDate = this.DisplayMonth;
        }
        private bool AutoSelectDate()
        {
            BaseItem parent = this.Parent;
            while (parent != null)
            {
                parent = parent.Parent;
                if (parent != null && parent.Name == "sysPopupProvider")
                {
                    DateTimeInput dt = parent.ContainerControl as DateTimeInput;
                    if (dt != null)
                        return dt.AutoSelectDate;
                }
            }
            return false;
        }
        private void MonthNavigationIncreaseClick(object sender, EventArgs e)
        {
            SetDisplayMonth(_DisplayMonth.AddMonths(1), eEventSource.Mouse);
            if (AutoSelectDate())
                this.SelectedDate = this.DisplayMonth;
        }
        private void YearNavigationDecreaseClick(object sender, EventArgs e)
        {
            SetDisplayMonth(_DisplayMonth.AddMonths(-12), eEventSource.Mouse);
            if (AutoSelectDate())
                this.SelectedDate = this.DisplayMonth;
        }
        private void YearNavigationIncreaseClick(object sender, EventArgs e)
        {
            SetDisplayMonth(_DisplayMonth.AddMonths(12), eEventSource.Mouse);
            if (AutoSelectDate())
                this.SelectedDate = this.DisplayMonth;
        }
        private bool _HeaderNavigationEnabled = true;
        /// 
        /// Gets or sets whether header navigation buttons for month and year are visible. Default value is true.
        /// 
        [DefaultValue(true), Description("Indicates whether header navigation buttons for month and year are visible.")]
        public bool HeaderNavigationEnabled
        {
            get { return _HeaderNavigationEnabled; }
            set
            {
                if (_HeaderNavigationEnabled != value)
                {
                    _HeaderNavigationEnabled = value;
                    OnHeaderNavigationEnabledChanged();
                }
            }
        }
        private void OnHeaderNavigationEnabledChanged()
        {
            ItemContainer nav = GetNavigationContainer();
            bool b = _HeaderNavigationEnabled;
            nav.SubItems[NavDecreaseMonth].Visible = b;
            nav.SubItems[NavIncreaseMonth].Visible = b;
            nav.SubItems[NavDecreaseYear].Visible = b;
            nav.SubItems[NavIncreaseYear].Visible = b;
            nav.NeedRecalcSize = true;
            this.OnAppearanceChanged();
            this.Refresh();
        }
        /// 
        /// Specifies the navigation container background style. Navigation container displays month, year and optional buttons. Default value is an empty style which means that container does not display any background.
        /// BeginGroup property set to true will override this style on some styles.
        /// 
        [Browsable(true), Category("Style"), Description("Indicates navigation container background style."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public ElementStyle NavigationBackgroundStyle
        {
            get { return GetNavigationContainer().BackgroundStyle; }
        }
        private bool _ShowTodayMarker = true;
        /// 
        /// Gets or sets whether today marker that indicates TodayDate is visible on the calendar. Default value is true.
        /// 
        [DefaultValue(true), Description("Indicates whether today marker that indicates TodayDate is visible on the calendar.")]
        public bool ShowTodayMarker
        {
            get { return _ShowTodayMarker; }
            set
            {
                if (_ShowTodayMarker != value)
                {
                    _ShowTodayMarker = value;
                    UpdateTodayMarker();
                }
            }
        }
        private DateTime _TodayDate = DateTime.MinValue;
        /// 
        /// Gets or sets the value that is used by calendar as today's date.
        /// 
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public DateTime TodayDate
        {
            get { return _TodayDate; }
            set
            {
                value = value.Date;
                if (_TodayDate != value)
                {
                    _TodayDate = value;
                    if (_ShowTodayMarker)
                        UpdateTodayMarker();
                }
            }
        }
        /// 
        /// Gets a value indicating whether the TodayDate property has been explicitly set. 
        /// 
        [Browsable(false)]
        public bool TodayDateSet
        {
            get { return _TodayDate != DateTime.MinValue; }
        }
        private void UpdateTodayMarker()
        {
            DateTime today = _ShowTodayMarker ? (_TodayDate == DateTime.MinValue ? DateTime.Today : DateTime.MinValue) : DateTime.MinValue;
            bool noMarker = today == DateTime.MinValue;
            foreach (BaseItem item in this.SubItems)
            {
                DayLabel day = item as DayLabel;
                if (day != null)
                {
                    if (noMarker)
                        day.IsToday = false;
                    else
                        day.IsToday = (day.Date == today);
                }
            }
        }
        private System.DateTime _MinDate = DateTimeGroup.MinDateTime;
        /// 
        /// Gets or sets the minimum date and time that can be selected in the control.
        /// 
        [Description("Indicates minimum date and time that can be selected in the control.")]
        public System.DateTime MinDate
        {
            get { return _MinDate; }
            set { _MinDate = value;
                UpdateNavigationButtonsEnabled();
            }
        }
        /// 
        /// Gets whether Value property should be serialized by Windows Forms designer.
        /// 
        /// true if value serialized otherwise false.
        [EditorBrowsable(EditorBrowsableState.Never)]
        public bool ShouldSerializeMinDate()
        {
            return !MinDate.Equals(DateTimeGroup.MinDateTime);
        }
        /// 
        /// Reset the MinDate property to its default value.
        /// 
        [EditorBrowsable(EditorBrowsableState.Never)]
        public void ResetMinDate()
        {
            MinDate = DateTimeGroup.MinDateTime;
        }
        private System.DateTime _MaxDate = DateTimeGroup.MaxDateTime;
        /// 
        /// Gets or sets the maximum date and time that can be selected in the control.
        /// 
        [Description("Indicates maximum date and time that can be selected in the control.")]
        public System.DateTime MaxDate
        {
            get { return _MaxDate; }
            set { _MaxDate = value;
                UpdateNavigationButtonsEnabled();
            }
        }
        /// 
        /// Gets whether Value property should be serialized by Windows Forms designer.
        /// 
        /// true if value serialized otherwise false.
        [EditorBrowsable(EditorBrowsableState.Never)]
        public bool ShouldSerializeMaxDate()
        {
            return !_MaxDate.Equals(DateTimeGroup.MaxDateTime);
        }
        /// 
        /// Reset the MaxDate property to its default value.
        /// 
        [EditorBrowsable(EditorBrowsableState.Never)]
        public void ResetMaxDate()
        {
            MaxDate = DateTimeGroup.MaxDateTime;
        }
        private int _NavigationMonthsAheadVisibility = 1;
        internal int NavigationMonthsAheadVisibility
        {
            get { return _NavigationMonthsAheadVisibility; }
            set
            {
                if (_NavigationMonthsAheadVisibility != value)
                {
                    _NavigationMonthsAheadVisibility = value;
                    UpdateNavigationButtonsEnabled();
                }
            }
        }
        private bool _DayClickAutoClosePopup = true;
        /// 
        /// Gets or sets whether clicking the day closes the parent popup if item is on popup.
        /// 
        [Browsable(false), DefaultValue(true)]
        public bool DayClickAutoClosePopup
        {
            get { return _DayClickAutoClosePopup; }
            set
            {
                if (value != _DayClickAutoClosePopup)
                {
                    bool oldValue = _DayClickAutoClosePopup;
                    _DayClickAutoClosePopup = value;
                    OnDayClickAutoClosePopupChanged(oldValue, value);
                }
            }
        }
        /// 
        /// Called when DayClickAutoClosePopup property has changed.
        /// 
        /// Old property value
        /// New property value
        protected virtual void OnDayClickAutoClosePopupChanged(bool oldValue, bool newValue)
        {
            //OnPropertyChanged(new PropertyChangedEventArgs("DayClickAutoClosePopup"));
            foreach (BaseItem item in this.SubItems)
            {
                if (item is DayLabel)
                    item.AutoCollapseOnClick = newValue;
            }
        }
        #endregion
    }
    #region Year Selector
    internal class YearSelectorControl : BaseItemControl
    {
        /// 
        /// Initializes a new instance of the YearSelectoControl class.
        /// 
        public YearSelectorControl()
        {
            _YearSelector = new YearSelectorContainer();
            this.HostItem = _YearSelector;
            this.FocusCuesEnabled = false;
        }
        protected override void OnResize(EventArgs e)
        {
            _YearSelector.FixedSize = Dpi.Descale(this.Size);
            base.OnResize(e);
        }
        private YearSelectorContainer _YearSelector;
        public YearSelectorContainer YearSelector
        {
            get { return _YearSelector; }
        }
    }
    internal class CenturySelectorControl : BaseItemControl
    {
        /// 
        /// Initializes a new instance of the CenturySelectorControl class.
        /// 
        public CenturySelectorControl()
        {
            _CenturySelector = new CenturySelectorContainer();
            this.HostItem = _CenturySelector;
            this.FocusCuesEnabled = false;
        }
        protected override void OnResize(EventArgs e)
        {
            _CenturySelector.FixedSize = Dpi.Descale(this.Size);
            base.OnResize(e);
        }
        private CenturySelectorContainer _CenturySelector;
        public CenturySelectorContainer CenturySelector
        {
            get { return _CenturySelector; }
        }
    }
    internal class YearSelectorContainer : ItemContainer
    {
        private Size _FixedButtonSize = new Size(13, 18);
        private ItemContainer _YearsContainer = null;
        private LabelItem _CenturyLabel = null;
        /// 
        /// Initializes a new instance of the YearSelectorContainer class.
        /// 
        public YearSelectorContainer()
        {
            this.LayoutOrientation = eOrientation.Vertical;
            // Add navigation container
            ItemContainer cont = new ItemContainer();
            cont.Name = "yearSelectonContainerHeader";
            cont.AutoCollapseOnClick = false;
            cont.MinimumSize = new Size(0, _FixedButtonSize.Height + 3);
            cont.LayoutOrientation = eOrientation.Horizontal;
            cont.HorizontalItemAlignment = eHorizontalItemsAlignment.Center;
            cont.VerticalItemAlignment = eVerticalItemsAlignment.Middle;
            cont.ItemSpacing = 2;
            ButtonItem nav = new ButtonItem("NavDecreaseYears");
            nav.GlobalItem = false;
            nav._FadeEnabled = false;
            nav.Text = "";
            nav.Click += YearsDecreaseClick;
            nav.AutoCollapseOnClick = false;
            nav.FixedSize = _FixedButtonSize;
            nav._FixedSizeCenterText = true;
            nav.ClickAutoRepeat = true;
            cont.SubItems.Add(nav);
            LabelItem label = new LabelItem("CenturyLabel");
            label.AutoCollapseOnClick = false;
            label.GlobalItem = false;
            label.TextAlignment = StringAlignment.Center;
            label.TextLineAlignment = StringAlignment.Center;
            label.PaddingBottom = 2;
            label.Text = "2010-2019";
            label.Click += ShowCenturySelector;
            label.Cursor = Cursors.Hand;
            _CenturyLabel = label;
            cont.SubItems.Add(label);
            nav = new ButtonItem("NavIncreaseYears");
            nav.GlobalItem = false;
            nav._FadeEnabled = false;
            nav.Text = "";
            nav.Click += YearsIncreaseClick;
            nav.AutoCollapseOnClick = false;
            nav.FixedSize = _FixedButtonSize;
            nav._FixedSizeCenterText = true;
            nav.ClickAutoRepeat = true;
            cont.SubItems.Add(nav);
            this.SubItems.Add(cont);
            cont = new ItemContainer();
            cont.LayoutOrientation = eOrientation.Horizontal;
            cont.MultiLine = true;
            this.SubItems.Add(cont);
            for (int i = 0; i < 12; i++)
            {
                ButtonItem by = new ButtonItem("yearSelector" + i.ToString());
                by.Text = (2009 + i).ToString();
                by.FixedSize = new Size(54, 35);
                by._FixedSizeCenterText = true;
                by.OptionGroup = "year";
                by.AutoCheckOnClick = true;
                by.AutoCollapseOnClick = false;
                by.Click += YearClick;
                cont.SubItems.Add(by);
            }
            _YearsContainer = cont;
            CenturyYearStart = (DateTime.Today.Year / 10) * 10;
        }
        private void YearClick(object sender, EventArgs e)
        {
            ButtonItem button = (ButtonItem)sender;
            int year = int.Parse(button.Text);
            this.SelectedYear = year;
            OnSelectedYearChanged(EventArgs.Empty);
        }
        public event EventHandler SelectedYearChanged;
        /// 
        /// Raises SelectedYearChanged event.
        /// 
        /// Provides event arguments.
        protected virtual void OnSelectedYearChanged(EventArgs e)
        {
            EventHandler handler = SelectedYearChanged;
            if (handler != null)
                handler(this, e);
        }
        private Color _TextColor = Color.Empty;
        public Color TextColor
        {
            get { return _TextColor; }
            set { _TextColor = value; OnTextColorChanged(); }
        }
        private void OnTextColorChanged()
        {
            SetTextColor(this.SubItems);
        }
        private void SetTextColor(SubItemsCollection subItems)
        {
            foreach (BaseItem item in subItems)
            {
                if (item is ButtonItem)
                {
                    ((ButtonItem)item).ForeColor = _TextColor;
                    ((ButtonItem)item).HotForeColor = _TextColor;
                }
                else if (item is LabelItem)
                    ((LabelItem)item).ForeColor = _TextColor;
                else if (item is ItemContainer)
                    SetTextColor(item.SubItems);
            }
        }
        private int _CenturyYearStart;
        public int CenturyYearStart
        {
            get { return _CenturyYearStart; }
            set { _CenturyYearStart = value; UpdateYears(); }
        }
        private int _SelectedYear;
        public int SelectedYear
        {
            get { return _SelectedYear; }
            set
            {
                _SelectedYear = value;
                foreach (BaseItem item in _YearsContainer.SubItems)
                {
                    if (item.Name.StartsWith("yearSelector"))
                    {
                        ButtonItem by = (ButtonItem)item;
                        if (by.Text == _SelectedYear.ToString())
                        {
                            by.Checked = true;
                            break;
                        }
                        else if (by.Checked)
                            by.Checked = false;
                    }
                }
            }
        }
        private void UpdateYears()
        {
            // Assumes this indicates century start
            int y = _CenturyYearStart - 1;
            foreach (BaseItem item in _YearsContainer.SubItems)
            {
                if (item.Name.StartsWith("yearSelector"))
                {
                    ButtonItem by = (ButtonItem)item;
                    by.Text = y.ToString();
                    if (y == _SelectedYear)
                        by.Checked = true;
                    else if (by.Checked)
                        by.Checked = false;
                    y++;
                }
            }
            _CenturyLabel.Text = string.Format("{0}-{1}", _CenturyYearStart, _CenturyYearStart + 10);
            NeedRecalcSize = true;
            this.Refresh();
        }
        protected override void OnFixedSizeChanged(Size oldValue, Size newValue)
        {
            base.OnFixedSizeChanged(oldValue, newValue);
            // Update buttons size
            Size size = newValue;
            size.Height -= _FixedButtonSize.Height + 4;
            size.Width -= 4;
            Size sb = new Size(size.Width / 4, size.Height / 3);
            //sb.Width = (int)(sb.Width / Dpi.Factor.Width);
            //sb.Height = (int)(sb.Height / Dpi.Factor.Height);
            foreach (BaseItem item in _YearsContainer.SubItems)
            {
                if (item.Name.StartsWith("yearSelector"))
                {
                    ButtonItem by = (ButtonItem)item;
                    by.FixedSize = sb;
                }
            }
        }
        private void YearsDecreaseClick(object sender, EventArgs e)
        {
            if (CenturyYearStart - 10 > 1760)
                CenturyYearStart -= 10;
        }
        private void YearsIncreaseClick(object sender, EventArgs e)
        {
            CenturyYearStart += 10;
        }
        private CenturySelectorControl _CenturySelector = null;
        private void ShowCenturySelector(object sender, EventArgs e)
        {
            if (_CenturySelector != null) return;
            _CenturySelector = new CenturySelectorControl();
            Control parent = (Control)this.ContainerControl;
            _CenturySelector.Size = new Size(8, 8);
            _CenturySelector.Location = new Point(this.LeftInternal + (this.WidthInternal - 8) / 2, this.TopInternal + (this.HeightInternal - 8) / 2);
            _CenturySelector.Style = eDotNetBarStyle.StyleManagerControlled;
            if (BarFunctions.IsOffice2007Style(this.Style))
            {
                Office2007ColorTable table = ((Office2007Renderer)GlobalManager.Renderer).ColorTable;
                ElementStyle es = (ElementStyle)table.StyleClasses[ElementStyleClassKeys.ItemPanelKey];
                _CenturySelector.BackgroundStyle.BackColor = es.BackColor;
                _CenturySelector.BackgroundStyle.BackColor2 = es.BackColor2;
            }
            else
                _CenturySelector.BackgroundStyle.BackColor = SystemColors.Window;
            _CenturySelector.CenturySelector.TextColor = this.TextColor;
            parent.Controls.Add(_CenturySelector);
            Rectangle targetBounds = this.Bounds;
            DevComponents.DotNetBar.Animation.AnimationRectangle anim = new DevComponents.DotNetBar.Animation.AnimationRectangle(
                new AnimationRequest(_CenturySelector, "Bounds", targetBounds),
                DevComponents.DotNetBar.Animation.AnimationEasing.EaseInOutQuad, 200);
            anim.AutoDispose = true;
            anim.Start();
            _CenturySelector.CenturySelector.SelectedCenturyChanged += SelectedCenturyChanged;
        }
        private void SelectedCenturyChanged(object sender, EventArgs e)
        {
            this.CenturyYearStart = _CenturySelector.CenturySelector.SelectedCentury;
            Rectangle targetBounds = this.Bounds;
            DevComponents.DotNetBar.Animation.AnimationRectangle anim = new DevComponents.DotNetBar.Animation.AnimationRectangle(
                new AnimationRequest(_CenturySelector, "Bounds", new Rectangle(this.LeftInternal + (this.WidthInternal - 8) / 2, this.TopInternal + (this.HeightInternal - 8) / 2, 8, 8)),
                DevComponents.DotNetBar.Animation.AnimationEasing.EaseInOutQuad, 200);
            anim.AutoDispose = true;
            anim.AnimationCompleted += new EventHandler(AnimationCompleted);
            anim.Start();
        }
        public void RemoveCenturySelector()
        {
            if (_CenturySelector == null) return;
            Control parent = (Control)this.ContainerControl;
            parent.Controls.Remove(_CenturySelector);
            _CenturySelector.CenturySelector.SelectedCenturyChanged -= SelectedCenturyChanged;
            _CenturySelector.Dispose();
            _CenturySelector = null;
        }
        void AnimationCompleted(object sender, EventArgs e)
        {
            RemoveCenturySelector();
        }
    }
    #endregion
    #region Century Selector
    internal class CenturySelectorContainer : ItemContainer
    {
        private Size _FixedButtonSize = new Size(13, 18);
        private ItemContainer _YearsContainer = null;
        private LabelItem _CenturyLabel = null;
        /// 
        /// Initializes a new instance of the YearSelectorContainer class.
        /// 
        public CenturySelectorContainer()
        {
            this.LayoutOrientation = eOrientation.Vertical;
            // Add navigation container
            ItemContainer cont = new ItemContainer();
            cont.AutoCollapseOnClick = false;
            cont.MinimumSize = new Size(0, _FixedButtonSize.Height + 3);
            cont.LayoutOrientation = eOrientation.Horizontal;
            cont.HorizontalItemAlignment = eHorizontalItemsAlignment.Center;
            cont.VerticalItemAlignment = eVerticalItemsAlignment.Middle;
            cont.ItemSpacing = 2;
            ButtonItem nav = new ButtonItem("NavDecreaseYears");
            nav.GlobalItem = false;
            nav._FadeEnabled = false;
            nav.Text = "";
            nav.Click += YearsDecreaseClick;
            nav.AutoCollapseOnClick = false;
            nav.FixedSize = _FixedButtonSize;
            nav._FixedSizeCenterText = true;
            nav.ClickAutoRepeat = true;
            cont.SubItems.Add(nav);
            LabelItem label = new LabelItem("CenturyLabel");
            label.AutoCollapseOnClick = false;
            label.GlobalItem = false;
            label.TextAlignment = StringAlignment.Center;
            label.TextLineAlignment = StringAlignment.Center;
            label.PaddingBottom = 2;
            label.Text = "2000-2099";
            _CenturyLabel = label;
            cont.SubItems.Add(label);
            nav = new ButtonItem("NavIncreaseYears");
            nav.GlobalItem = false;
            nav._FadeEnabled = false;
            nav.Text = "";
            nav.Click += YearsIncreaseClick;
            nav.AutoCollapseOnClick = false;
            nav.FixedSize = _FixedButtonSize;
            nav._FixedSizeCenterText = true;
            nav.ClickAutoRepeat = true;
            cont.SubItems.Add(nav);
            this.SubItems.Add(cont);
            cont = new ItemContainer();
            cont.LayoutOrientation = eOrientation.Horizontal;
            cont.MultiLine = true;
            this.SubItems.Add(cont);
            for (int i = 0; i < 12; i++)
            {
                ButtonItem by = new ButtonItem("centurySelector" + i.ToString());
                by.Text = (2009 + i).ToString();
                by.FixedSize = new Size(54, 35);
                by._FixedSizeCenterText = true;
                by.OptionGroup = "century";
                by.AutoCheckOnClick = true;
                by.Click += CenturyClick;
                cont.SubItems.Add(by);
            }
            _YearsContainer = cont;
            CenturyYearStart = (DateTime.Today.Year / 100) * 100;
        }
        private void CenturyClick(object sender, EventArgs e)
        {
            ButtonItem button = (ButtonItem)sender;
            int year = (int)button.Tag;
            this.SelectedCentury = year;
        }
        public event EventHandler SelectedCenturyChanged;
        /// 
        /// Raises SelectedYearChanged event.
        /// 
        /// Provides event arguments.
        protected virtual void OnSelectedCenturyChanged(EventArgs e)
        {
            EventHandler handler = SelectedCenturyChanged;
            if (handler != null)
                handler(this, e);
        }
        private Color _TextColor = Color.Empty;
        public Color TextColor
        {
            get { return _TextColor; }
            set { _TextColor = value; OnTextColorChanged(); }
        }
        private void OnTextColorChanged()
        {
            SetTextColor(this.SubItems);
        }
        private void SetTextColor(SubItemsCollection subItems)
        {
            foreach (BaseItem item in subItems)
            {
                if (item is ButtonItem)
                {
                    ((ButtonItem)item).ForeColor = _TextColor;
                    ((ButtonItem)item).HotForeColor = _TextColor;
                }
                else if (item is LabelItem)
                    ((LabelItem)item).ForeColor = _TextColor;
                else if (item is ItemContainer)
                    SetTextColor(item.SubItems);
            }
        }
        private int _CenturyYearStart;
        public int CenturyYearStart
        {
            get { return _CenturyYearStart; }
            set { _CenturyYearStart = value; UpdateYears(); }
        }
        private int _SelectedYear;
        public int SelectedCentury
        {
            get { return _SelectedYear; }
            set
            {
                _SelectedYear = value;
                foreach (BaseItem item in _YearsContainer.SubItems)
                {
                    if (item.Name.StartsWith("centurySelector"))
                    {
                        ButtonItem by = (ButtonItem)item;
                        if ((int)by.Tag == _SelectedYear)
                        {
                            by.Checked = true;
                            break;
                        }
                    }
                }
                OnSelectedCenturyChanged(EventArgs.Empty);
            }
        }
        private void UpdateYears()
        {
            // Assumes this indicates century start
            int y = _CenturyYearStart - 10;
            foreach (BaseItem item in _YearsContainer.SubItems)
            {
                if (item.Name.StartsWith("centurySelector"))
                {
                    ButtonItem by = (ButtonItem)item;
                    by.Text = string.Format("{0}-
{1}
", y, y + 9);
                    by.Tag = y;
                    if (y == _SelectedYear)
                        by.Checked = true;
                    else if (by.Checked)
                        by.Checked = false;
                    y += 10;
                }
            }
            _CenturyLabel.Text = string.Format("{0}-{1}", _CenturyYearStart, _CenturyYearStart + 99);
            NeedRecalcSize = true;
            this.Refresh();
        }
        protected override void OnFixedSizeChanged(Size oldValue, Size newValue)
        {
            base.OnFixedSizeChanged(oldValue, newValue);
            // Update buttons size
            Size size = newValue;
            size.Height -= _FixedButtonSize.Height + 4;
            size.Width -= 4;
            Size sb = new Size(size.Width / 4, size.Height / 3);
            //sb.Width = (int)(sb.Width / Dpi.Factor.Width);
            //sb.Height = (int)(sb.Height / Dpi.Factor.Height);
            foreach (BaseItem item in _YearsContainer.SubItems)
            {
                if (item.Name.StartsWith("centurySelector"))
                {
                    ButtonItem by = (ButtonItem)item;
                    by.FixedSize = sb;
                }
            }
        }
        private void YearsDecreaseClick(object sender, EventArgs e)
        {
            if (CenturyYearStart - 100 > 1760)
                CenturyYearStart -= 100;
        }
        private void YearsIncreaseClick(object sender, EventArgs e)
        {
            CenturyYearStart += 100;
        }
    }
    #endregion
    #region MonthSelector
    internal class MonthSelectorControl : BaseItemControl
    {
        /// 
        /// Initializes a new instance of the CenturySelectorControl class.
        /// 
        public MonthSelectorControl()
        {
            _MonthSelector = new MonthSelectorContainer();
            this.HostItem = _MonthSelector;
            this.FocusCuesEnabled = false;
        }
        protected override void OnResize(EventArgs e)
        {
            _MonthSelector.FixedSize = Dpi.Descale(this.Size);
            base.OnResize(e);
        }
        private MonthSelectorContainer _MonthSelector;
        public MonthSelectorContainer MonthSelector
        {
            get { return _MonthSelector; }
        }
    }
    internal class MonthSelectorContainer : ItemContainer
    {
        private const string STR_MonthSelector = "monthSelector";
        private Size _FixedButtonSize = new Size(13, 18);
        private ItemContainer _MonthsContainer = null;
        /// 
        /// Initializes a new instance of the YearSelectorContainer class.
        /// 
        public MonthSelectorContainer()
        {
            this.LayoutOrientation = eOrientation.Vertical;
            // Add navigation container
            ItemContainer cont = new ItemContainer();
            cont.LayoutOrientation = eOrientation.Horizontal;
            cont.MultiLine = true;
            cont.AutoCollapseOnClick = false;
            this.SubItems.Add(cont);
            for (int i = 1; i <= 12; i++)
            {
                ButtonItem by = new ButtonItem(STR_MonthSelector + i.ToString());
                by.Text = i.ToString();
                by.Tag = i;
                by.FixedSize = new Size(54, 35);
                by._FixedSizeCenterText = true;
                by.OptionGroup = "month";
                by.AutoCheckOnClick = true;
                by.Click += MonthClick;
                by.AutoCollapseOnClick = false;
                cont.SubItems.Add(by);
            }
            _MonthsContainer = cont;
        }
        public bool IsEmpty
        {
            get
            {
                foreach (BaseItem item in _MonthsContainer.SubItems)
                {
                    if(item is ButtonItem && item.Name.StartsWith(STR_MonthSelector) && ((ButtonItem)item).Checked)
                        return false;
                }
                return true;
            }
            set
            {
                if (value)
                {
                    _SelectedMonth = 1;
                    foreach (BaseItem item in _MonthsContainer.SubItems)
                    {
                        if (item is ButtonItem && item.Name.StartsWith(STR_MonthSelector) && ((ButtonItem)item).Checked)
                            ((ButtonItem)item).Checked = false;
                    }
                }
            }
        }
        private void MonthClick(object sender, EventArgs e)
        {
            ButtonItem button = (ButtonItem)sender;
            int month = (int)button.Tag;
            this.SelectedMonth = month;
            OnSelectedMonthChanged(EventArgs.Empty);
        }
        public event EventHandler SelectedMonthChanged;
        /// 
        /// Raises SelectedYearChanged event.
        /// 
        /// Provides event arguments.
        protected virtual void OnSelectedMonthChanged(EventArgs e)
        {
            EventHandler handler = SelectedMonthChanged;
            if (handler != null)
                handler(this, e);
        }
        private Color _TextColor = Color.Empty;
        public Color TextColor
        {
            get { return _TextColor; }
            set { _TextColor = value; OnTextColorChanged(); }
        }
        private void OnTextColorChanged()
        {
            SetTextColor(this.SubItems);
        }
        private void SetTextColor(SubItemsCollection subItems)
        {
            foreach (BaseItem item in subItems)
            {
                if (item is ButtonItem)
                {
                    ((ButtonItem)item).ForeColor = _TextColor;
                    ((ButtonItem)item).HotForeColor = _TextColor;
                }
                else if (item is LabelItem)
                    ((LabelItem)item).ForeColor = _TextColor;
                else if (item is ItemContainer)
                    SetTextColor(item.SubItems);
            }
        }
        private int _SelectedMonth = 1;
        public int SelectedMonth
        {
            get { return _SelectedMonth; }
            set
            {
                if (value <= 0) value = 1;
                if (value > 12) value = 12;
                _SelectedMonth = value;
                ButtonItem month = (ButtonItem)_MonthsContainer.SubItems[STR_MonthSelector + _SelectedMonth.ToString()];
                if (month != null)
                {
                    month.Checked = true;
                }
            }
        }
        private bool _UseMonthNames = false;
        public bool UseMonthNames
        {
            get { return _UseMonthNames; }
            set
            {
                _UseMonthNames = value;
                UpdateMonthText();
            }
        }
        private void UpdateMonthText()
        {
            string[] monthNames = new string[0];
            if (_UseMonthNames)
            {
                CultureInfo ci = DateTimeInput.GetActiveCulture();
                monthNames = ci.DateTimeFormat.AbbreviatedMonthNames;
            }
            foreach (BaseItem item in _MonthsContainer.SubItems)
            {
                if (item.Name.StartsWith(STR_MonthSelector))
                {
                    ButtonItem by = (ButtonItem)item;
                    int month = (int)by.Tag;
                    if (_UseMonthNames)
                    {
                        by.Text = monthNames[month - 1];
                    }
                    else
                    {
                        by.Text = month.ToString();
                    }
                    //if (month == _SelectedMonth)
                    //    by.Checked = true;
                    //else if (by.Checked)
                    //    by.Checked = false;
                }
            }
            NeedRecalcSize = true;
            this.Refresh();
        }
        protected override void OnFixedSizeChanged(Size oldValue, Size newValue)
        {
            base.OnFixedSizeChanged(oldValue, newValue);
            // Update buttons size
            Size size = newValue;
            size.Height -= _FixedButtonSize.Height + 4;
            size.Width -= 4;
            Size sb = new Size(size.Width / 4, size.Height / 3);
            //sb.Width = (int)(sb.Width/Dpi.Factor.Width);
            //sb.Height = (int)(sb.Height/Dpi.Factor.Height);
            foreach (BaseItem item in _MonthsContainer.SubItems)
            {
                if (item.Name.StartsWith(STR_MonthSelector))
                {
                    ButtonItem by = (ButtonItem)item;
                    by.FixedSize = sb;
                }
            }
        }
    }
    #endregion
    internal enum eCurrentSingleMonthCalendarOperation
    {
        None,
        AnimatingShowYearSelector,
        AnimatingHideYearSelector,
        AnimatingShowMonthSelector,
        AnimatingHideMonthSelector
    }
}
#endif