/// <summary>
        /// Raises the <see cref="System.Windows.Forms.Control.KeyPress"/> event.
        /// </summary>
        /// <param name="e">A <see cref="KeyPressEventArgs"/> that contains the event data.</param>
        protected override void OnKeyPress(KeyPressEventArgs e)
        {
            e.Handled = true;

            if (!char.IsDigit(e.KeyChar))
            {
                return;
            }

            if (!this.inEditMode)
            {
                this.inEditMode = true;
                this.Refresh();

                var keyCharString = e.KeyChar.ToString(CultureInfo.InvariantCulture);

                if (this.datePicker.UseNativeDigits)
                {
                    var number = int.Parse(keyCharString);
                    keyCharString = DateMethods.GetNativeNumberString(number, this.datePicker.Culture.NumberFormat.NativeDigits, false);
                }

                this.inputBox.Font            = this.Font;
                this.inputBox.Location        = new Point(0, 2);
                this.inputBox.Size            = this.Size;
                this.inputBox.Text            = keyCharString;
                this.inputBox.Visible         = true;
                this.inputBox.SelectionStart  = 1;
                this.inputBox.SelectionLength = 0;
                this.inputBox.BringToFront();
                this.inputBox.Focus();
            }

            this.Refresh();
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="MonthCalendarMonth"/> class.
        /// </summary>
        /// <param name="monthCal">The <see cref="MonthCalendar"/> which hosts the <see cref="MonthCalendarMonth"/> instance.</param>
        /// <param name="date">The date that represents the month and year which is displayed in this instance.</param>
        public MonthCalendarMonth(MonthCalendar monthCal, DateTime date)
        {
            this.MonthCalendar = monthCal;
            this.Date          = date;
            this.location      = new Point(0, 0);

            MonthCalendarDate dt = new MonthCalendarDate(monthCal.CultureCalendar, date).FirstOfMonth.GetFirstDayInWeek(monthCal.FormatProvider);

            List <MonthCalendarDay>  dayList  = new List <MonthCalendarDay>();
            List <MonthCalendarWeek> weekList = new List <MonthCalendarWeek>();

            int dayAdjust = 0;

            while (dt.AddDays(dayAdjust).DayOfWeek != monthCal.FormatProvider.FirstDayOfWeek)
            {
                dayAdjust++;
            }

            int d = dayAdjust != 0 ? 8 - dayAdjust : 0;

            for (int i = dayAdjust; i < 42 + dayAdjust; i++, dt = dt.AddDays(1))
            {
                MonthCalendarDay day = new MonthCalendarDay(this, dt.Date);

                dayList.Add(day);

                if (day.Visible)
                {
                    if (this.firstVisibleDate == DateTime.MinValue)
                    {
                        this.firstVisibleDate = dt.Date;
                    }

                    if (!day.TrailingDate)
                    {
                        this.lastVisibleDate = dt.Date;
                    }
                }

                if (i == dayAdjust || ((i - d) % 7) == 0)
                {
                    DateTime weekEnd = dt.GetEndDateOfWeek(monthCal.FormatProvider).Date;

                    int weekNumEnd = DateMethods.GetWeekOfYear(monthCal.Culture, monthCal.CultureCalendar, weekEnd);

                    weekList.Add(new MonthCalendarWeek(this, weekNumEnd, dt.Date, weekEnd));
                }

                if (dt.Date == monthCal.CultureCalendar.MaxSupportedDateTime.Date)
                {
                    break;
                }
            }

            this.Days  = dayList.ToArray();
            this.Weeks = weekList.ToArray();
        }
        /// <summary>
        /// Draws a single week header element.
        /// </summary>
        /// <param name="g">The <see cref="Graphics"/> object used to draw.</param>
        /// <param name="week">The <see cref="MonthCalendarWeek"/> to draw.</param>
        public override void DrawWeekHeaderItem(Graphics g, MonthCalendarWeek week)
        {
            if (!CheckParams(g, week.Bounds))
            {
                return;
            }

            var weekString = this.monthCal.UseNativeDigits
            ? DateMethods.GetNativeNumberString(week.WeekNumber, this.monthCal.Culture.NumberFormat.NativeDigits, false)
            : week.WeekNumber.ToString(CultureInfo.CurrentUICulture);

            // draw week header element
            using (StringFormat format = GetStringAlignment(this.monthCal.DayTextAlignment))
            {
                // set alignment
                format.Alignment = StringAlignment.Center;

                // draw string
                using (SolidBrush brush = new SolidBrush(this.ColorTable.WeekHeaderText))
                {
                    if (this.monthCal.Enabled)
                    {
                        g.DrawString(
                            weekString,
                            this.monthCal.Font,
                            brush,
                            week.Bounds,
                            format);
                    }
                    else
                    {
                        ControlPaint.DrawStringDisabled(
                            g,
                            weekString,
                            this.monthCal.Font,
                            Color.Transparent,
                            week.Bounds,
                            format);
                    }
                }
            }
        }
            /// <summary>
            /// Raises the <see cref="Control.KeyPress"/> event.
            /// </summary>
            /// <param name="e">A <see cref="KeyPressEventArgs"/> that contains the event data.</param>
            protected override void OnKeyPress(KeyPressEventArgs e)
            {
                var isNumber    = char.IsNumber(e.KeyChar);
                var isSeparator = this.parent.datePicker.FormatProvider.DateSeparator.Contains(e.KeyChar);

                var textContainsSeparator = this.Text.Contains(this.parent.datePicker.FormatProvider.DateSeparator);
                var txtLength             = textContainsSeparator ? 10 : 8;

                if (isSeparator)
                {
                    if (this.Text.Length == txtLength && e.KeyChar != '\b')
                    {
                        e.Handled = true;
                    }
                    else
                    {
                        base.OnKeyPress(e);
                    }

                    return;
                }

                if ((!isNumber || this.Text.Length == txtLength) && e.KeyChar != '\b')
                {
                    e.Handled = true;

                    return;
                }

                if (this.parent.datePicker.UseNativeDigits && isNumber)
                {
                    var number = int.Parse(e.KeyChar.ToString(CultureInfo.InvariantCulture));

                    var nativeNumber = DateMethods.GetNativeNumberString(number, this.parent.datePicker.Culture.NumberFormat.NativeDigits, false);

                    e.KeyChar = nativeNumber[0];
                }

                base.OnKeyPress(e);
            }
 /// <summary>
 /// Determines if the specified <paramref name="day"/> is a valid day in regard to the <paramref name="date"/> value.
 /// </summary>
 /// <param name="day">The day value.</param>
 /// <param name="date">The year and month value.</param>
 /// <param name="cal">The calendar to use.</param>
 /// <returns>true if it's a valid day; false otherwise.</returns>
 private static bool IsValidDay(int day, DateTime date, Calendar cal)
 {
     return(day >= 1 && day <= DateMethods.GetDaysInMonth(new MonthCalendarDate(cal, date)));
 }
        /// <summary>
        /// Processes a dialog key.
        /// </summary>
        /// <param name="keyData">One of the <see cref="System.Windows.Forms.Keys"/> values that represents the key to process.</param>
        /// <returns>true if the key was processed by the control; otherwise, false.</returns>
        protected override bool ProcessDialogKey(Keys keyData)
        {
            if (keyData == Keys.Left || keyData == Keys.Right)
            {
                this.SetDatePart(keyData == Keys.Left ? this.RightToLeft == RightToLeft.No : this.RightToLeft == RightToLeft.Yes);

                return(true);
            }

            Calendar cal = this.datePicker.Picker.CultureCalendar;

            MonthCalendarDate dt = new MonthCalendarDate(cal, this.currentDate);

            DateTime date = this.Date;

            if (keyData == Keys.Up || keyData == Keys.Down)
            {
                bool up = keyData == Keys.Up;

                switch (this.selectedPart)
                {
                case SelectedDatePart.Day:
                {
                    int day = dt.Day + (up ? 1 : -1);

                    int daysInMonth = DateMethods.GetDaysInMonth(dt);

                    if (day > daysInMonth)
                    {
                        day = 1;
                    }
                    else if (day < 1)
                    {
                        day = daysInMonth;
                    }

                    date = new DateTime(dt.Year, dt.Month, day, cal);

                    break;
                }

                case SelectedDatePart.Month:
                {
                    int day = dt.Day;

                    int month = dt.Month + (up ? 1 : -1);

                    int monthsInYear = cal.GetMonthsInYear(dt.Year);

                    if (month > monthsInYear)
                    {
                        month = 1;
                    }
                    else if (month < 1)
                    {
                        month = monthsInYear;
                    }

                    DateTime newDate = new DateTime(dt.Year, month, 1, cal);

                    dt = new MonthCalendarDate(cal, newDate);

                    int daysInMonth = DateMethods.GetDaysInMonth(dt);

                    newDate = daysInMonth < day?cal.AddDays(newDate, daysInMonth - 1) : cal.AddDays(newDate, day - 1);

                    date = newDate;

                    break;
                }

                case SelectedDatePart.Year:
                {
                    int year    = dt.Year + (up ? 1 : -1);
                    int minYear = cal.GetYear(this.MinDate);
                    int maxYear = cal.GetYear(this.MaxDate);

                    year = Math.Max(minYear, Math.Min(year, maxYear));

                    int yearDiff = year - dt.Year;

                    date = cal.AddYears(this.currentDate, yearDiff);

                    break;
                }
                }

                this.Date = date < this.MinDate ? this.MinDate : (date > this.MaxDate ? this.MaxDate : date);

                this.Refresh();

                return(true);
            }

            if (keyData == Keys.Home || keyData == Keys.End)
            {
                bool first = keyData == Keys.Home;

                switch (this.selectedPart)
                {
                case SelectedDatePart.Day:
                {
                    date = first ? new DateTime(dt.Year, dt.Month, 1, cal)
                        : new DateTime(dt.Year, dt.Month, DateMethods.GetDaysInMonth(dt), cal);

                    break;
                }

                case SelectedDatePart.Month:
                {
                    int day = dt.Day;

                    date = first ? new DateTime(dt.Year, 1, 1, cal)
                        : new DateTime(dt.Year, cal.GetMonthsInYear(dt.Year), 1, cal);

                    int daysInMonth = DateMethods.GetDaysInMonth(dt);

                    date = day > daysInMonth?cal.AddDays(date, daysInMonth - 1)
                               : cal.AddDays(date, day - 1);

                    break;
                }

                case SelectedDatePart.Year:
                {
                    date = first ? this.MinDate.Date : this.MaxDate.Date;

                    break;
                }
                }

                this.Date = date < this.MinDate ? this.MinDate : (date > this.MaxDate ? this.MaxDate : date);

                this.Refresh();

                return(true);
            }

            if (keyData == Keys.Space && !this.inEditMode)
            {
                this.datePicker.SwitchPickerState();

                return(true);
            }

            return(base.ProcessDialogKey(keyData));
        }
            public string ParsePattern(MonthCalendarDate date, string[] nativeDigits = null)
            {
                // replace date separator with '/'
                string format = this.pattern.Replace(provider.DateSeparator, "/");

                StringBuilder sb = new StringBuilder();

                Calendar c = provider.Calendar;

                int i     = 0;
                int index = 0;

                while (i < format.Length)
                {
                    int    tokLen;
                    char   ch = format[i];
                    string currentString;

                    switch (ch)
                    {
                    case 'd':
                    {
                        tokLen = CountChar(format, i, ch);

                        if (tokLen <= 2)
                        {
                            currentString = DateMethods.GetNumberString(date.Day, nativeDigits, tokLen == 2);

                            this.isDayNumber = true;

                            this.dayString = currentString;

                            this.dayPartIndex = index++;

                            this.dayIndex = sb.Length;
                        }
                        else
                        {
                            currentString = tokLen == 3 ? provider.GetAbbreviatedDayName(c.GetDayOfWeek(date.Date)) : provider.GetDayName(c.GetDayOfWeek(date.Date));

                            this.dayNameString = currentString;
                        }

                        sb.Append(currentString);

                        break;
                    }

                    case 'M':
                    {
                        tokLen = CountChar(format, i, ch);

                        if (tokLen <= 2)
                        {
                            currentString = DateMethods.GetNumberString(date.Month, nativeDigits, tokLen == 2);

                            this.isMonthNumber = true;
                        }
                        else
                        {
                            currentString = tokLen == 3
                                              ? provider.GetAbbreviatedMonthName(date.Year, date.Month)
                                              : provider.GetMonthName(date.Year, date.Month);
                        }

                        this.monthPartIndex = index++;

                        this.monthIndex = sb.Length;

                        this.monthString = currentString;

                        sb.Append(currentString);

                        break;
                    }

                    case 'y':
                    {
                        tokLen = CountChar(format, i, ch);

                        var year = tokLen <= 2 ? date.Year % 100 : date.Year;

                        currentString = DateMethods.GetNumberString(year, nativeDigits, tokLen <= 2);

                        this.yearString = currentString;

                        this.yearPartIndex = index++;

                        this.yearIndex = sb.Length;

                        sb.Append(currentString);

                        break;
                    }

                    case 'g':
                    {
                        tokLen = CountChar(format, i, ch);

                        currentString = provider.GetEraName(c.GetEra(date.Date));

                        this.eraString = currentString;

                        sb.Append(currentString);

                        break;
                    }

                    case '/':
                    {
                        tokLen = CountChar(format, i, ch);

                        sb.Append(provider.DateSeparator);

                        break;
                    }

                    default:
                    {
                        tokLen = 1;

                        sb.Append(ch.ToString(CultureInfo.CurrentUICulture));

                        break;
                    }
                    }

                    i += tokLen;
                }

                return(sb.ToString());
            }
        /// <summary>
        /// Draws the header of a <see cref="MonthCalendarMonth"/>.
        /// </summary>
        /// <param name="g">The <see cref="Graphics"/> object used to draw.</param>
        /// <param name="calMonth">The <see cref="MonthCalendarMonth"/> to draw the header for.</param>
        /// <param name="state">The <see cref="MonthCalendarHeaderState"/>.</param>
        public override void DrawMonthHeader(
            Graphics g,
            MonthCalendarMonth calMonth,
            MonthCalendarHeaderState state)
        {
            if (calMonth == null || !CheckParams(g, calMonth.TitleBounds))
            {
                return;
            }

            // get title bounds
            Rectangle rect = calMonth.TitleBounds;

            MonthCalendarDate date         = new MonthCalendarDate(monthCal.CultureCalendar, calMonth.Date);
            MonthCalendarDate firstVisible = new MonthCalendarDate(monthCal.CultureCalendar, calMonth.FirstVisibleDate);

            string month;
            int    year;

            // gets the month name for the month the MonthCalendarMonth represents and the year string
            if (firstVisible.Era != date.Era)
            {
                month = this.monthCal.FormatProvider.GetMonthName(firstVisible.Year, firstVisible.Month);
                year  = firstVisible.Year;
            }
            else
            {
                month = this.monthCal.FormatProvider.GetMonthName(date.Year, date.Month);
                year  = date.Year;
            }

            string yearString = this.monthCal.UseNativeDigits
            ? DateMethods.GetNativeNumberString(year, this.monthCal.Culture.NumberFormat.NativeDigits, false)
            : year.ToString(CultureInfo.CurrentUICulture);

            // get used font
            Font headerFont = this.monthCal.HeaderFont;

            // create bold font
            Font boldFont = new Font(headerFont.FontFamily, headerFont.SizeInPoints, FontStyle.Bold);

            // measure sizes
            SizeF monthSize = g.MeasureString(month, boldFont);

            SizeF yearSize = g.MeasureString(yearString, boldFont);

            float maxHeight = Math.Max(monthSize.Height, yearSize.Height);

            // calculates the width and the starting position of the arrows
            int width       = (int)monthSize.Width + (int)yearSize.Width + 7;
            int arrowLeftX  = rect.X + 6;
            int arrowRightX = rect.Right - 6;
            int arrowY      = rect.Y + (rect.Height / 2) - 4;

            int x = Math.Max(0, rect.X + (rect.Width / 2) + 1 - (width / 2));
            int y = Math.Max(
                0,
                rect.Y + (rect.Height / 2) + 1 - (((int)maxHeight + 1) / 2));

            // set the title month name bounds
            calMonth.TitleMonthBounds = new Rectangle(
                x,
                y,
                (int)monthSize.Width + 1,
                (int)maxHeight + 1);

            // set the title year bounds
            calMonth.TitleYearBounds = new Rectangle(
                x + calMonth.TitleMonthBounds.Width + 7,
                y,
                (int)yearSize.Width + 1,
                (int)maxHeight + 1);

            // generate points for the left and right arrow
            Point[] arrowLeft = new[]
            {
                new Point(arrowLeftX, arrowY + 4),
                new Point(arrowLeftX + 4, arrowY),
                new Point(arrowLeftX + 4, arrowY + 8),
                new Point(arrowLeftX, arrowY + 4)
            };

            Point[] arrowRight = new[]
            {
                new Point(arrowRightX, arrowY + 4),
                new Point(arrowRightX - 4, arrowY),
                new Point(arrowRightX - 4, arrowY + 8),
                new Point(arrowRightX, arrowY + 4)
            };

            // get color table
            MonthCalendarColorTable colorTable = this.ColorTable;

            // get brushes for normal, mouse over and selected state
            using (SolidBrush brush = new SolidBrush(colorTable.HeaderText),
                   brushOver = new SolidBrush(colorTable.HeaderActiveText),
                   brushSelected = new SolidBrush(colorTable.HeaderSelectedText))
            {
                // get title month name and year bounds
                Rectangle monthRect = calMonth.TitleMonthBounds;
                Rectangle yearRect  = calMonth.TitleYearBounds;

                // set used fonts
                Font monthFont = headerFont;
                Font yearFont  = headerFont;

                // set used brushes
                SolidBrush monthBrush = brush, yearBrush = brush;

                // adjust brush and font if year selected
                if (state == MonthCalendarHeaderState.YearSelected)
                {
                    yearBrush       = brushSelected;
                    yearFont        = boldFont;
                    yearRect.Width += 4;
                }
                else if (state == MonthCalendarHeaderState.YearActive)
                {
                    // adjust brush if mouse over year
                    yearBrush = brushOver;
                }

                // adjust brush and font if month name is selected
                if (state == MonthCalendarHeaderState.MonthNameSelected)
                {
                    monthBrush       = brushSelected;
                    monthFont        = boldFont;
                    monthRect.Width += 4;
                }
                else if (state == MonthCalendarHeaderState.MonthNameActive)
                {
                    // adjust brush if mouse over month name
                    monthBrush = brushOver;
                }

                // draws the month name and year string
                g.DrawString(month, monthFont, monthBrush, monthRect);
                g.DrawString(yearString, yearFont, yearBrush, yearRect);
            }

            boldFont.Dispose();

            // if left arrow has to be drawn
            //if (calMonth.DrawLeftButton)
            //{
            //   // get arrow color
            //   Color arrowColor = this.monthCal.LeftButtonState == ButtonState.Normal ?
            //      GetGrayColor(this.monthCal.Enabled, colorTable.HeaderArrow) : colorTable.HeaderActiveArrow;

            //   // set left arrow rect
            //   this.monthCal.SetLeftArrowRect(new Rectangle(rect.X, rect.Y, 15, rect.Height));

            //   // draw left arrow
            //   using (GraphicsPath path = new GraphicsPath())
            //   {
            //      path.AddLines(arrowLeft);

            //      using (SolidBrush brush = new SolidBrush(arrowColor))
            //      {
            //         g.FillPath(brush, path);
            //      }

            //      using (Pen p = new Pen(arrowColor))
            //      {
            //         g.DrawPath(p, path);
            //      }
            //   }
            //}

            // if right arrow has to be drawn
            //   if (calMonth.DrawRightButton)
            //   {
            //      // get arrow color
            //      Color arrowColor = this.monthCal.RightButtonState == ButtonState.Normal ?
            //         GetGrayColor(this.monthCal.Enabled, colorTable.HeaderArrow) : colorTable.HeaderActiveArrow;

            //      // set right arrow rect
            //      this.monthCal.SetRightArrowRect(new Rectangle(rect.Right - 15, rect.Y, 15, rect.Height));

            //      // draw arrow
            //      using (GraphicsPath path = new GraphicsPath())
            //      {
            //         path.AddLines(arrowRight);

            //         using (SolidBrush brush = new SolidBrush(arrowColor))
            //         {
            //            g.FillPath(brush, path);
            //         }

            //         using (Pen p = new Pen(arrowColor))
            //         {
            //            g.DrawPath(p, path);
            //         }
            //      }
            //   }
        }
        /// <summary>
        /// Draws the day header.
        /// </summary>
        /// <param name="g">The <see cref="Graphics"/> object used to draw.</param>
        /// <param name="rect">The <see cref="Rectangle"/> to draw in.</param>
        public override void DrawDayHeader(Graphics g, Rectangle rect)
        {
            // get day width
            int dayWidth = this.monthCal.DaySize.Width;

            if (!CheckParams(g, rect) || dayWidth <= 0)
            {
                return;
            }

            // get abbreviated day names
            List <string> names = new List <string>(DateMethods.GetDayNames(this.monthCal.FormatProvider, this.monthCal.UseShortestDayNames ? 2 : 1));

            // if in RTL mode, reverse order
            if (this.monthCal.UseRTL)
            {
                names.Reverse();
            }

            // get bounds for a single element
            Rectangle dayRect = rect;

            dayRect.Width = dayWidth;

            // draw day names
            using (StringFormat format =
                       new StringFormat(StringFormatFlags.LineLimit | StringFormatFlags.NoWrap)
            {
                Alignment = StringAlignment.Center,
                LineAlignment = StringAlignment.Center
            })
            {
                using (SolidBrush brush = new SolidBrush(this.ColorTable.DayHeaderText))
                {
                    names.ForEach(day =>
                    {
                        if (this.monthCal.Enabled)
                        {
                            g.DrawString(day, this.monthCal.DayHeaderFont, brush, dayRect, format);
                        }
                        else
                        {
                            ControlPaint.DrawStringDisabled(
                                g,
                                day,
                                this.monthCal.DayHeaderFont,
                                Color.Transparent,
                                dayRect,
                                format);
                        }

                        dayRect.X += dayWidth;
                    });
                }
            }

            // draw separator line
            using (Pen p = new Pen(GetGrayColor(this.monthCal.Enabled, this.ColorTable.MonthSeparator)))
            {
                g.DrawLine(p, rect.X, rect.Bottom - 1, rect.Right - 1, rect.Bottom - 1);
            }
        }
        /// <summary>
        /// Draws a day in the month body of the calendar control.
        /// </summary>
        /// <param name="g">The <see cref="Graphics"/> object used to draw.</param>
        /// <param name="day">The <see cref="MonthCalendarDay"/> to draw.</param>
        public override void DrawDay(Graphics g, MonthCalendarDay day)
        {
            if (!CheckParams(g, day.Bounds))
            {
                return;
            }

            // get color table
            MonthCalendarColorTable colors = this.ColorTable;

            // get the bounds of the day
            Rectangle rect = day.Bounds;

            var boldDate = this.monthCal.BoldedDatesCollection.Find(d => d.Value.Date == day.Date.Date);

            // if day is selected or in mouse over state
            if (day.MouseOver)
            {
                FillBackground(
                    g,
                    rect,
                    colors.DayActiveGradientBegin,
                    colors.DayActiveGradientEnd,
                    colors.DayActiveGradientMode);
            }
            else if (day.Selected)
            {
                this.FillBackgroundInternal(
                    g,
                    rect,
                    colors.DaySelectedGradientBegin,
                    colors.DaySelectedGradientEnd,
                    colors.DaySelectedGradientMode);
            }
            else if (!boldDate.IsEmpty && boldDate.Category.BackColorStart != Color.Empty && boldDate.Category.BackColorStart != Color.Transparent)
            {
                FillBackground(
                    g,
                    rect,
                    boldDate.Category.BackColorStart,
                    boldDate.Category.BackColorEnd.IsEmpty || boldDate.Category.BackColorEnd == Color.Transparent ? boldDate.Category.BackColorStart : boldDate.Category.BackColorEnd,
                    boldDate.Category.GradientMode);
            }

            // get bolded dates
            List <DateTime> boldedDates = this.monthCal.GetBoldedDates();

            bool bold = boldedDates.Contains(day.Date) || !boldDate.IsEmpty;

            // draw the day
            using (StringFormat format = GetStringAlignment(this.monthCal.DayTextAlignment))
            {
                Color textColor = bold ? (boldDate.IsEmpty || boldDate.Category.ForeColor == Color.Empty || boldDate.Category.ForeColor == Color.Transparent ? colors.DayTextBold : boldDate.Category.ForeColor)
               : (day.Selected ? colors.DaySelectedText
               : (day.MouseOver ? colors.DayActiveText
               : (day.TrailingDate ? colors.DayTrailingText
               : colors.DayText)));

                using (SolidBrush brush = new SolidBrush(textColor))
                {
                    using (Font font = new Font(
                               this.monthCal.Font.FontFamily,
                               this.monthCal.Font.SizeInPoints,
                               FontStyle.Bold))
                    {
                        // adjust width
                        Rectangle textRect = day.Bounds;
                        textRect.Width -= 2;

                        // determine if to use bold font
                        //bool useBoldFont = day.Date == DateTime.Today || bold;
                        bool useBoldFont = bold;

                        var calDate = new MonthCalendarDate(monthCal.CultureCalendar, day.Date);

                        string dayString = this.monthCal.UseNativeDigits
                                        ? DateMethods.GetNativeNumberString(calDate.Day, this.monthCal.Culture.NumberFormat.NativeDigits, false)
                                        : calDate.Day.ToString(this.monthCal.Culture);

                        //if (!day.TrailingDate)
                        //{

                        if (this.monthCal.Enabled)
                        {
                            g.DrawString(
                                dayString,
                                (useBoldFont ? font : this.monthCal.Font),
                                brush,
                                textRect,
                                format);
                        }
                        else
                        {
                            ControlPaint.DrawStringDisabled(
                                g,
                                dayString,
                                (useBoldFont ? font : this.monthCal.Font),
                                Color.Transparent,
                                textRect,
                                format);
                        }
                        //}
                    }
                }
            }

            // if today, draw border
            //if (day.Date == DateTime.Today)
            //{
            //   rect.Height -= 1;
            //   rect.Width -= 2;
            //   Color borderColor = day.Selected ? colors.DaySelectedTodayCircleBorder
            //      : (day.MouseOver ? colors.DayActiveTodayCircleBorder : colors.DayTodayCircleBorder);

            //   using (Pen p = new Pen(borderColor))
            //   {
            //      g.DrawRectangle(p, rect);

            //      rect.Offset(1, 0);

            //      g.DrawRectangle(p, rect);
            //   }
            //}
        }
        /// <summary>
        /// Returns a string representation of this object.
        /// </summary>
        /// <param name="format">The format pattern.</param>
        /// <param name="dtfi">The <see cref="DateTimeFormatInfo"/> to use for formatting.</param>
        /// <param name="nameProvider">The day and month name provider.</param>
        /// <param name="nativeDigits">If not <c>null</c> and valid, uses for number representation the specified native digits.</param>
        /// <returns>
        /// A <see cref="System.String"/> that represents this instance.
        /// </returns>
        private string ToString(string format, DateTimeFormatInfo dtfi, ICustomFormatProvider nameProvider, string[] nativeDigits = null)
        {
            if (dtfi == null)
            {
                dtfi = CultureInfo.CurrentUICulture.DateTimeFormat;
            }

            if (string.IsNullOrEmpty(format))
            {
                format = nameProvider != null ? nameProvider.ShortDatePattern : dtfi.ShortDatePattern;
            }
            else if (format.Length == 1)
            {
                switch (format[0])
                {
                case 'D':
                {
                    format = nameProvider != null ? nameProvider.LongDatePattern : dtfi.LongDatePattern;

                    break;
                }

                case 'm':
                case 'M':
                {
                    format = nameProvider != null ? nameProvider.MonthDayPattern : dtfi.MonthDayPattern;

                    break;
                }

                case 'y':
                case 'Y':
                {
                    format = nameProvider != null ? nameProvider.YearMonthPattern : dtfi.YearMonthPattern;

                    break;
                }

                default:
                {
                    format = nameProvider != null ? nameProvider.ShortDatePattern : dtfi.ShortDatePattern;

                    break;
                }
                }
            }

            format = format.Replace(nameProvider != null ? nameProvider.DateSeparator : dtfi.DateSeparator, "/");

            StringBuilder sb = new StringBuilder();

            Calendar c = nameProvider != null ? nameProvider.Calendar : dtfi.Calendar;

            int i = 0;

            while (i < format.Length)
            {
                int  tokLen;
                char ch = format[i];

                switch (ch)
                {
                case 'd':
                {
                    tokLen = CountChar(format, i, ch);

                    sb.Append(tokLen <= 2
                        ? DateMethods.GetNumberString(this.Day, nativeDigits, tokLen == 2)
                        : GetDayName(c.GetDayOfWeek(this.Date), dtfi, nameProvider, tokLen == 3));

                    break;
                }

                case 'M':
                {
                    tokLen = CountChar(format, i, ch);

                    sb.Append(tokLen <= 2
                        ? DateMethods.GetNumberString(this.Month, nativeDigits, tokLen == 2)
                        : GetMonthName(this.Month, this.Year, dtfi, nameProvider, tokLen == 3));

                    break;
                }

                case 'y':
                {
                    tokLen = CountChar(format, i, ch);

                    sb.Append(tokLen <= 2
                        ? DateMethods.GetNumberString(this.Year % 100, nativeDigits, true)
                        : DateMethods.GetNumberString(this.Year, nativeDigits, false));

                    break;
                }

                case 'g':
                {
                    tokLen = CountChar(format, i, ch);

                    sb.Append(nameProvider != null
                        ? nameProvider.GetEraName(c.GetEra(this.Date))
                        : dtfi.GetEraName(c.GetEra(this.Date)));

                    break;
                }

                case '/':
                {
                    tokLen = CountChar(format, i, ch);

                    sb.Append(nameProvider != null
                        ? nameProvider.DateSeparator
                        : dtfi.DateSeparator);

                    break;
                }

                case '\'':
                {
                    tokLen = 1;

                    break;
                }

                default:
                {
                    tokLen = 1;

                    sb.Append(ch.ToString(CultureInfo.CurrentUICulture));

                    break;
                }
                }

                i += tokLen;
            }

            return(sb.ToString());
        }