Calendar.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / xsp / System / Web / UI / WebControls / Calendar.cs / 1305376 / Calendar.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Web.UI.WebControls { 
    using System.Threading; 
    using System.Globalization;
    using System.ComponentModel; 
    using System;
    using System.Web;
    using System.Web.UI;
    using System.Web.Util; 
    using System.Collections;
    using System.ComponentModel.Design; 
    using System.Drawing; 
    using System.Text;
 
    using System.IO;
    using System.Reflection;

 

    ///  
    ///    Displays a one-month calendar and allows the user to 
    ///       view and select a specific day, week, or month.
    ///  
    [
    ControlValueProperty("SelectedDate", typeof(DateTime), "1/1/0001"),
    DataBindingHandler("System.Web.UI.Design.WebControls.CalendarDataBindingHandler, " + AssemblyRef.SystemDesign),
    DefaultEvent("SelectionChanged"), 
    DefaultProperty("SelectedDate"),
    Designer("System.Web.UI.Design.WebControls.CalendarDesigner, " + AssemblyRef.SystemDesign), 
    SupportsEventValidation 
    ]
    public class Calendar : WebControl, IPostBackEventHandler { 

        private static readonly object EventDayRender = new object();
        private static readonly object EventSelectionChanged = new object();
        private static readonly object EventVisibleMonthChanged = new object(); 

        private TableItemStyle titleStyle; 
        private TableItemStyle nextPrevStyle; 
        private TableItemStyle dayHeaderStyle;
        private TableItemStyle selectorStyle; 
        private TableItemStyle dayStyle;
        private TableItemStyle otherMonthDayStyle;
        private TableItemStyle todayDayStyle;
        private TableItemStyle selectedDayStyle; 
        private TableItemStyle weekendDayStyle;
        private string defaultButtonColorText; 
 
        private static readonly Color DefaultForeColor = Color.Black;
        private Color defaultForeColor; 

        private ArrayList dateList;
        private SelectedDatesCollection selectedDates;
        private Globalization.Calendar threadCalendar; 
        private DateTime minSupportedDate;
        private DateTime maxSupportedDate; 
#if DEBUG 
        private bool threadCalendarInitialized;
#endif 

        private const string SELECT_RANGE_COMMAND = "R";
        private const string NAVIGATE_MONTH_COMMAND = "V";
 
        private static DateTime baseDate = new DateTime(2000, 1, 1);
 
        private const int STYLEMASK_DAY = 16; 
        private const int STYLEMASK_UNIQUE = 15;
        private const int STYLEMASK_SELECTED = 8; 
        private const int STYLEMASK_TODAY = 4;
        private const int STYLEMASK_OTHERMONTH = 2;
        private const int STYLEMASK_WEEKEND = 1;
        private const string ROWBEGINTAG = ""; 
        private const string ROWENDTAG = "";
 
        // Cache commonly used strings. This improves performance and memory usage. 
        private const int cachedNumberMax = 31;
        private static readonly string[] cachedNumbers = new string [] { 
                  "0",  "1",   "2",   "3",   "4",   "5",   "6",
                  "7",  "8",   "9",  "10",  "11",  "12",  "13",
                 "14", "15",  "16",  "17",  "18",  "19",  "20",
                 "21", "22",  "23",  "24",  "25",  "26",  "27", 
                 "28", "29",  "30",  "31",
        }; 
 

        ///  
        /// Initializes a new instance of the  class.
        /// 
        public Calendar() : base(HtmlTextWriterTag.Table) {
        } 

 
        [ 
        Localizable(true),
        DefaultValue(""), 
        WebCategory("Accessibility"),
        WebSysDescription(SR.Calendar_Caption)
        ]
        public virtual string Caption { 
            get {
                string s = (string)ViewState["Caption"]; 
                return (s != null) ? s : String.Empty; 
            }
            set { 
                ViewState["Caption"] = value;
            }
        }
 

        [ 
        DefaultValue(TableCaptionAlign.NotSet), 
        WebCategory("Accessibility"),
        WebSysDescription(SR.WebControl_CaptionAlign) 
        ]
        public virtual TableCaptionAlign CaptionAlign {
            get {
                object o = ViewState["CaptionAlign"]; 
                return (o != null) ? (TableCaptionAlign)o : TableCaptionAlign.NotSet;
            } 
            set { 
                if ((value < TableCaptionAlign.NotSet) ||
                    (value > TableCaptionAlign.Right)) { 
                    throw new ArgumentOutOfRangeException("value");
                }
                ViewState["CaptionAlign"] = value;
            } 
        }
 
 
        /// 
        ///    Gets or sets the amount of space between cells. 
        /// 
        [
        WebCategory("Layout"),
        DefaultValue(2), 
        WebSysDescription(SR.Calendar_CellPadding)
        ] 
        public int CellPadding { 
            get {
                object o = ViewState["CellPadding"]; 
                return((o == null) ? 2 : (int)o);
            }
            set {
                if (value < - 1 ) { 
                    throw new ArgumentOutOfRangeException("value");
                } 
                ViewState["CellPadding"] = value; 
            }
        } 


        /// 
        ///    Gets or sets the amount of space between the contents of a cell 
        ///       and the cell's border.
        ///  
        [ 
        WebCategory("Layout"),
        DefaultValue(0), 
        WebSysDescription(SR.Calendar_CellSpacing)
        ]
        public int CellSpacing {
            get { 
                object o = ViewState["CellSpacing"];
                return((o == null) ?  0 : (int)o); 
            } 
            set {
                if (value < -1 ) { 
                    throw new ArgumentOutOfRangeException("value");
                }
                ViewState["CellSpacing"] = (int)value;
            } 
        }
 
 
        /// 
        ///     Gets the style property of the day-of-the-week header. This property is read-only. 
        /// 
        [
        WebCategory("Styles"),
        WebSysDescription(SR.Calendar_DayHeaderStyle), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
        NotifyParentProperty(true), 
        PersistenceMode(PersistenceMode.InnerProperty) 
        ]
        public TableItemStyle DayHeaderStyle { 
            get {
                if (dayHeaderStyle == null) {
                    dayHeaderStyle = new TableItemStyle();
                    if (IsTrackingViewState) 
                        ((IStateManager)dayHeaderStyle).TrackViewState();
                } 
                return dayHeaderStyle; 
            }
        } 


        /// 
        ///    Gets or sets 
        ///       the format for the names of days.
        ///  
        [ 
        WebCategory("Appearance"),
        DefaultValue(DayNameFormat.Short), 
        WebSysDescription(SR.Calendar_DayNameFormat)
        ]
        public DayNameFormat DayNameFormat {
            get { 
                object dnf = ViewState["DayNameFormat"];
                return((dnf == null) ? DayNameFormat.Short : (DayNameFormat)dnf); 
            } 
            set {
                if (value < DayNameFormat.Full || value > DayNameFormat.Shortest) { 
                    throw new ArgumentOutOfRangeException("value");
                }
                ViewState["DayNameFormat"] = value;
            } 
        }
 
 
        /// 
        ///     Gets the style properties for the days. This property is read-only. 
        /// 
        [
        WebCategory("Styles"),
        DefaultValue(null), 
        WebSysDescription(SR.Calendar_DayStyle),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content), 
        NotifyParentProperty(true), 
        PersistenceMode(PersistenceMode.InnerProperty)
        ] 
        public TableItemStyle DayStyle {
            get {
                if (dayStyle == null) {
                    dayStyle = new TableItemStyle(); 
                    if (IsTrackingViewState)
                        ((IStateManager)dayStyle).TrackViewState(); 
                } 
                return dayStyle;
            } 
        }


        ///  
        ///     Gets
        ///       or sets the day of the week to display in the calendar's first 
        ///       column. 
        /// 
        [ 
        WebCategory("Appearance"),
        DefaultValue(FirstDayOfWeek.Default),
        WebSysDescription(SR.Calendar_FirstDayOfWeek)
        ] 
        public FirstDayOfWeek FirstDayOfWeek {
            get { 
                object o = ViewState["FirstDayOfWeek"]; 
                return((o == null) ? FirstDayOfWeek.Default : (FirstDayOfWeek)o);
            } 
            set {
                if (value < FirstDayOfWeek.Sunday || value > FirstDayOfWeek.Default) {
                    throw new ArgumentOutOfRangeException("value");
                } 

                ViewState["FirstDayOfWeek"] = value; 
            } 
        }
 

        /// 
        ///    Gets or sets the text shown for the next month
        ///       navigation hyperlink if the  property is set to 
        ///    .
        ///  
        [ 
        Localizable(true),
        WebCategory("Appearance"), 
        DefaultValue(">"),
        WebSysDescription(SR.Calendar_NextMonthText)
        ]
        public string NextMonthText { 
            get {
                object s = ViewState["NextMonthText"]; 
                return((s == null) ? ">" : (String) s); 
            }
            set { 
                ViewState["NextMonthText"] = value;
            }
        }
 

        ///  
        ///    Gets or sets the format of the next and previous month hyperlinks in the 
        ///       title.
        ///  
        [
        WebCategory("Appearance"),
        DefaultValue(NextPrevFormat.CustomText),
        WebSysDescription(SR.Calendar_NextPrevFormat) 
        ]
        public NextPrevFormat NextPrevFormat { 
            get { 
                object npf = ViewState["NextPrevFormat"];
                return((npf == null) ? NextPrevFormat.CustomText : (NextPrevFormat)npf); 
            }
            set {
                if (value < NextPrevFormat.CustomText || value > NextPrevFormat.FullMonth) {
                    throw new ArgumentOutOfRangeException("value"); 
                }
                ViewState["NextPrevFormat"] = value; 
            } 
        }
 

        /// 
        ///     Gets the style properties for the next/previous month navigators. This property is
        ///       read-only. 
        /// 
        [ 
        WebCategory("Styles"), 
        WebSysDescription(SR.Calendar_NextPrevStyle),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content), 
        NotifyParentProperty(true),
        PersistenceMode(PersistenceMode.InnerProperty)
        ]
        public TableItemStyle NextPrevStyle { 
            get {
                if (nextPrevStyle == null) { 
                    nextPrevStyle = new TableItemStyle(); 
                    if (IsTrackingViewState)
                        ((IStateManager)nextPrevStyle).TrackViewState(); 
                }
                return nextPrevStyle;
            }
        } 

 
 
        /// 
        ///    Gets the style properties for the days from the months preceding and following the current month. 
        ///       This property is read-only.
        /// 
        [
        WebCategory("Styles"), 
        DefaultValue(null),
        WebSysDescription(SR.Calendar_OtherMonthDayStyle), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content), 
        NotifyParentProperty(true),
        PersistenceMode(PersistenceMode.InnerProperty) 
        ]
        public TableItemStyle OtherMonthDayStyle {
            get {
                if (otherMonthDayStyle == null) { 
                    otherMonthDayStyle = new TableItemStyle();
                    if (IsTrackingViewState) 
                        ((IStateManager)otherMonthDayStyle).TrackViewState(); 

                } 
                return otherMonthDayStyle;
            }
        }
 

        ///  
        ///    Gets or sets the text shown for the previous month 
        ///       navigation hyperlink if the  property is set to
        ///     
        ///    .
        /// 
        [
        Localizable(true), 
        WebCategory("Appearance"),
        DefaultValue("<"), 
        WebSysDescription(SR.Calendar_PrevMonthText) 
        ]
        public string PrevMonthText { 
            get {
                object s = ViewState["PrevMonthText"];
                return((s == null) ? "<" : (String) s);
            } 
            set {
                ViewState["PrevMonthText"] = value; 
            } 
        }
 
        public override bool SupportsDisabledAttribute {
            get {
                return RenderingCompatibility < VersionUtil.Framework40;
            } 
        }
 
        ///  
        ///    Gets or sets the date that is currently selected
        ///       date. 
        /// 
        [
        Bindable(true, BindingDirection.TwoWay),
        DefaultValue(typeof(DateTime), "1/1/0001"), 
        WebSysDescription(SR.Calendar_SelectedDate)
        ] 
        public DateTime SelectedDate { 
            get {
                if (SelectedDates.Count == 0) { 
                    return DateTime.MinValue;
                }
                return SelectedDates[0];
            } 
            set {
                if (value == DateTime.MinValue) { 
                    SelectedDates.Clear(); 
                }
                else { 
                    SelectedDates.SelectRange(value, value);
                }
            }
        } 

 
        ///  
        /// Gets a collection of  objects representing days selected on the . This
        ///    property is read-only. 
        /// 
        [
        Browsable(false),
        WebSysDescription(SR.Calendar_SelectedDates), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ] 
        public SelectedDatesCollection SelectedDates { 
            get {
                if (selectedDates == null) { 
                    if (dateList == null) {
                        dateList = new ArrayList();
                    }
                    selectedDates = new SelectedDatesCollection(dateList); 
                }
                return selectedDates; 
            } 
        }
 

        /// 
        ///    Gets the style properties for the selected date. This property is read-only.
        ///  
        [
        WebCategory("Styles"), 
        DefaultValue(null), 
        WebSysDescription(SR.Calendar_SelectedDayStyle),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content), 
        NotifyParentProperty(true),
        PersistenceMode(PersistenceMode.InnerProperty)
        ]
        public TableItemStyle SelectedDayStyle { 
            get {
                if (selectedDayStyle == null) { 
                    selectedDayStyle = new TableItemStyle(); 
                    if (IsTrackingViewState)
                        ((IStateManager)selectedDayStyle).TrackViewState(); 
                }
                return selectedDayStyle;
            }
        } 

 
        ///  
        ///    Gets or sets the date selection capabilities on the
        ///     
        ///    to allow the user to select a day, week, or month.
        /// 
        [
        WebCategory("Behavior"), 
        DefaultValue(CalendarSelectionMode.Day),
        WebSysDescription(SR.Calendar_SelectionMode) 
        ] 
        public CalendarSelectionMode SelectionMode {
            get { 
                object csm = ViewState["SelectionMode"];
                return((csm == null) ? CalendarSelectionMode.Day : (CalendarSelectionMode)csm);
            }
            set { 
                if (value < CalendarSelectionMode.None || value > CalendarSelectionMode.DayWeekMonth) {
                    throw new ArgumentOutOfRangeException("value"); 
                } 
                ViewState["SelectionMode"] = value;
            } 
        }


        ///  
        ///    Gets or sets the text shown for the month selection in
        ///       the selector column if  is 
        ///    . 
        /// 
        [ 
        Localizable(true),
        WebCategory("Appearance"),
        DefaultValue(">>"),
        WebSysDescription(SR.Calendar_SelectMonthText) 
        ]
        public string SelectMonthText { 
            get { 
                object s = ViewState["SelectMonthText"];
                return((s == null) ? ">>" : (String) s); 
            }
            set {
                ViewState["SelectMonthText"] = value;
            } 
        }
 
 
        /// 
        ///     Gets the style properties for the week and month selectors. This property is read-only. 
        /// 
        [
        WebCategory("Styles"),
        WebSysDescription(SR.Calendar_SelectorStyle), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
        NotifyParentProperty(true), 
        PersistenceMode(PersistenceMode.InnerProperty) 
        ]
        public TableItemStyle SelectorStyle { 
            get {
                if (selectorStyle == null) {
                    selectorStyle = new TableItemStyle();
                    if (IsTrackingViewState) 
                        ((IStateManager)selectorStyle).TrackViewState();
                } 
                return selectorStyle; 
            }
        } 

        /// 
        ///    Gets or sets the text shown for the week selection in
        ///       the selector column if  is 
        ///    or
        ///    . 
        ///  
        [
        Localizable(true), 
        WebCategory("Appearance"),
        DefaultValue(">"),
        WebSysDescription(SR.Calendar_SelectWeekText)
        ] 
        public string SelectWeekText {
            get { 
                object s = ViewState["SelectWeekText"]; 
                return((s == null) ? ">" : (String) s);
            } 
            set {
                ViewState["SelectWeekText"] = value;
            }
        } 

 
        ///  
        ///    Gets or sets
        ///       a value indicating whether the days of the week are displayed. 
        /// 
        [
        WebCategory("Appearance"),
        DefaultValue(true), 
        WebSysDescription(SR.Calendar_ShowDayHeader)
        ] 
        public bool ShowDayHeader { 
            get {
                object b = ViewState["ShowDayHeader"]; 
                return((b == null) ? true : (bool)b);
            }
            set {
                ViewState["ShowDayHeader"] = value; 
            }
        } 
 

        ///  
        ///    Gets or set
        ///       a value indicating whether days on the calendar are displayed with a border.
        /// 
        [ 
        WebCategory("Appearance"),
        DefaultValue(false), 
        WebSysDescription(SR.Calendar_ShowGridLines) 
        ]
        public bool ShowGridLines { 
            get {
                object b= ViewState["ShowGridLines"];
                return((b == null) ? false : (bool)b);
            } 
            set {
                ViewState["ShowGridLines"] = value; 
            } 
        }
 

        /// 
        /// Gets or sets a value indicating whether the 
        /// displays the next and pervious month 
        /// hyperlinks in the title.
        ///  
        [ 
        WebCategory("Appearance"),
        DefaultValue(true), 
        WebSysDescription(SR.Calendar_ShowNextPrevMonth)
        ]
        public bool ShowNextPrevMonth {
            get { 
                object b = ViewState["ShowNextPrevMonth"];
                return((b == null) ? true : (bool)b); 
            } 
            set {
                ViewState["ShowNextPrevMonth"] = value; 
            }
        }

 
        /// 
        ///     Gets or 
        ///       sets a value indicating whether the title is displayed. 
        /// 
        [ 
        WebCategory("Appearance"),
        DefaultValue(true),
        WebSysDescription(SR.Calendar_ShowTitle)
        ] 
        public bool ShowTitle {
            get { 
                object b = ViewState["ShowTitle"]; 
                return((b == null) ? true : (bool)b);
            } 
            set {
                ViewState["ShowTitle"] = value;
            }
        } 

 
        ///  
        ///    Gets or sets how the month name is formatted in the title
        ///       bar. 
        /// 
        [
        WebCategory("Appearance"),
        DefaultValue(TitleFormat.MonthYear), 
        WebSysDescription(SR.Calendar_TitleFormat)
        ] 
        public TitleFormat TitleFormat { 
            get {
                object tf = ViewState["TitleFormat"]; 
                return((tf == null) ? TitleFormat.MonthYear : (TitleFormat)tf);
            }
            set {
                if (value < TitleFormat.Month || value > TitleFormat.MonthYear) { 
                    throw new ArgumentOutOfRangeException("value");
                } 
                ViewState["TitleFormat"] = value; 
            }
        } 


        /// 
        /// Gets the style properties of the  title. This property is 
        ///    read-only.
        ///  
        [ 
        WebCategory("Styles"),
        WebSysDescription(SR.Calendar_TitleStyle), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
        NotifyParentProperty(true),
        PersistenceMode(PersistenceMode.InnerProperty),
        ] 
        public TableItemStyle TitleStyle {
            get { 
                if (titleStyle == null) { 
                    titleStyle = new TableItemStyle();
                    if (IsTrackingViewState) 
                        ((IStateManager)titleStyle).TrackViewState();
                }
                return titleStyle;
            } 
        }
 
 
        /// 
        ///    Gets the style properties for today's date on the 
        ///    . This
        ///       property is read-only.
        /// 
        [ 
        WebCategory("Styles"),
        DefaultValue(null), 
        WebSysDescription(SR.Calendar_TodayDayStyle), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
        NotifyParentProperty(true), 
        PersistenceMode(PersistenceMode.InnerProperty)
        ]
        public TableItemStyle TodayDayStyle {
            get { 
                if (todayDayStyle == null) {
                    todayDayStyle = new TableItemStyle(); 
                    if (IsTrackingViewState) 
                        ((IStateManager)todayDayStyle).TrackViewState();
                } 
                return todayDayStyle;
            }
        }
 

        ///  
        ///    Gets or sets the value to use as today's date. 
        /// 
        [ 
        Browsable(false),
        WebSysDescription(SR.Calendar_TodaysDate),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ] 
        public DateTime TodaysDate {
            get { 
                object o = ViewState["TodaysDate"]; 
                return((o == null) ? DateTime.Today : (DateTime)o);
            } 
            set {
                ViewState["TodaysDate"] = value.Date;
            }
        } 

 
        [ 
        DefaultValue(true),
        WebCategory("Accessibility"), 
        WebSysDescription(SR.Table_UseAccessibleHeader)
        ]
        public virtual bool UseAccessibleHeader {
            get { 
                object o = ViewState["UseAccessibleHeader"];
                return (o != null) ? (bool)o : true; 
            } 
            set {
                ViewState["UseAccessibleHeader"] = value; 
            }
        }

 
        /// 
        ///    Gets or sets the date that specifies what month to display. The date can be 
        ///       be any date within the month. 
        /// 
        [ 
        Bindable(true),
        DefaultValue(typeof(DateTime), "1/1/0001"),
        WebSysDescription(SR.Calendar_VisibleDate)
        ] 
        public DateTime VisibleDate {
            get { 
                object o = ViewState["VisibleDate"]; 
                return((o == null) ? DateTime.MinValue : (DateTime)o);
            } 
            set {
                ViewState["VisibleDate"] = value.Date;
            }
        } 

 
        ///  
        ///    Gets the style properties for the displaying weekend dates. This property is
        ///       read-only. 
        /// 
        [
        WebCategory("Styles"),
        WebSysDescription(SR.Calendar_WeekendDayStyle), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
        NotifyParentProperty(true), 
        PersistenceMode(PersistenceMode.InnerProperty) 
        ]
        public TableItemStyle WeekendDayStyle { 
            get {
                if (weekendDayStyle == null) {
                    weekendDayStyle = new TableItemStyle();
                    if (IsTrackingViewState) 
                        ((IStateManager)weekendDayStyle).TrackViewState();
                } 
                return weekendDayStyle; 
            }
        } 



        ///  
        /// Occurs when each day is created in teh control hierarchy for the .
        ///  
        [ 
        WebCategory("Action"),
        WebSysDescription(SR.Calendar_OnDayRender) 
        ]
        public event DayRenderEventHandler DayRender {
            add {
                Events.AddHandler(EventDayRender, value); 
            }
            remove { 
                Events.RemoveHandler(EventDayRender, value); 
            }
        } 



 
        /// 
        ///    Occurs when the user clicks on a day, week, or month 
        ///       selector and changes the . 
        /// 
        [ 
        WebCategory("Action"),
        WebSysDescription(SR.Calendar_OnSelectionChanged)
        ]
        public event EventHandler SelectionChanged { 
            add {
                Events.AddHandler(EventSelectionChanged, value); 
            } 
            remove {
                Events.RemoveHandler(EventSelectionChanged, value); 
            }
        }

 

        ///  
        ///    Occurs when the 
        ///       user clicks on the next or previous month  controls on the title.
        ///  
        [
        WebCategory("Action"),
        WebSysDescription(SR.Calendar_OnVisibleMonthChanged)
        ] 
        public event MonthChangedEventHandler VisibleMonthChanged {
            add { 
                Events.AddHandler(EventVisibleMonthChanged, value); 
            }
            remove { 
                Events.RemoveHandler(EventVisibleMonthChanged, value);
            }
        }
 
        // Methods
 
 
        /// 
        ///  
        private void ApplyTitleStyle(TableCell titleCell, Table titleTable, TableItemStyle titleStyle) {
            // apply affects that affect the whole background to the cell
            if (titleStyle.BackColor != Color.Empty) {
                titleCell.BackColor = titleStyle.BackColor; 
            }
            if (titleStyle.BorderColor != Color.Empty) { 
                titleCell.BorderColor = titleStyle.BorderColor; 
            }
            if (titleStyle.BorderWidth != Unit.Empty) { 
                titleCell.BorderWidth= titleStyle.BorderWidth;
            }
            if (titleStyle.BorderStyle != BorderStyle.NotSet) {
                titleCell.BorderStyle = titleStyle.BorderStyle; 
            }
            if (titleStyle.Height != Unit.Empty) { 
                titleCell.Height = titleStyle.Height; 
            }
            if (titleStyle.VerticalAlign != VerticalAlign.NotSet) { 
                titleCell.VerticalAlign = titleStyle.VerticalAlign;
            }

            // apply affects that affect everything else to the table 
            if (titleStyle.CssClass.Length > 0) {
                titleTable.CssClass = titleStyle.CssClass; 
            } 
            else if (CssClass.Length > 0) {
                titleTable.CssClass = CssClass; 
            }

            if (titleStyle.ForeColor != Color.Empty) {
                titleTable.ForeColor = titleStyle.ForeColor; 
            }
            else if (ForeColor != Color.Empty) { 
                titleTable.ForeColor = ForeColor; 
            }
            titleTable.Font.CopyFrom(titleStyle.Font); 
            titleTable.Font.MergeWith(this.Font);

        }
 

        ///  
        ///  
        /// 
        protected override ControlCollection CreateControlCollection() { 
            return new InternalControlCollection(this);
        }

 

        ///  
        ///  
        private DateTime EffectiveVisibleDate() {
            DateTime visDate = VisibleDate; 
            if (visDate.Equals(DateTime.MinValue)) {
                visDate = TodaysDate;
            }
 
            // VSWhidbey 366243
            if (IsMinSupportedYearMonth(visDate)) { 
                return minSupportedDate; 
            }
            else { 
                return threadCalendar.AddDays(visDate, -(threadCalendar.GetDayOfMonth(visDate) - 1));
            }
        }
 

        ///  
        ///  
        private DateTime FirstCalendarDay(DateTime visibleDate) {
            DateTime firstDayOfMonth = visibleDate; 

            // VSWhidbey 366243
            if (IsMinSupportedYearMonth(firstDayOfMonth)) {
                return firstDayOfMonth; 
            }
 
            int daysFromLastMonth = ((int)threadCalendar.GetDayOfWeek(firstDayOfMonth)) - NumericFirstDayOfWeek(); 
            // Always display at least one day from the previous month
            if (daysFromLastMonth <= 0) { 
                daysFromLastMonth += 7;
            }
            return threadCalendar.AddDays(firstDayOfMonth, -daysFromLastMonth);
        } 

 
        ///  
        /// 
        private string GetCalendarButtonText(string eventArgument, string buttonText, string title, bool showLink, Color foreColor) { 
            if (showLink) {
                StringBuilder sb = new StringBuilder();
                sb.Append("");
                sb.Append(buttonText); 
                sb.Append("");
                return sb.ToString();
            }
            else { 
                return buttonText;
            } 
        } 

 
        /// 
        /// 
        private int GetDefinedStyleMask() {
 
            // Selected is always defined because it has default effects
            int styleMask = STYLEMASK_SELECTED; 
 
            if (dayStyle != null && !dayStyle.IsEmpty)
                styleMask |= STYLEMASK_DAY; 
            if (todayDayStyle != null && !todayDayStyle.IsEmpty)
                styleMask |= STYLEMASK_TODAY;
            if (otherMonthDayStyle != null && !otherMonthDayStyle.IsEmpty)
                styleMask |= STYLEMASK_OTHERMONTH; 
            if (weekendDayStyle != null && !weekendDayStyle.IsEmpty)
                styleMask |= STYLEMASK_WEEKEND; 
            return styleMask; 
        }
 

        /// 
        /// 
        private string GetMonthName(int m, bool bFull) { 
            if (bFull) {
                return DateTimeFormatInfo.CurrentInfo.GetMonthName(m); 
            } 
            else {
                return DateTimeFormatInfo.CurrentInfo.GetAbbreviatedMonthName(m); 
            }
        }

 
        /// 
        /// Determines if a  
        /// contains week selectors. 
        /// 
        protected bool HasWeekSelectors(CalendarSelectionMode selectionMode) { 
            return(selectionMode == CalendarSelectionMode.DayWeek
                   || selectionMode == CalendarSelectionMode.DayWeekMonth);
        }
 
        private bool IsTheSameYearMonth(DateTime date1, DateTime date2) {
#if DEBUG 
            Debug.Assert(threadCalendarInitialized); 
#endif
            return (threadCalendar.GetEra(date1) == threadCalendar.GetEra(date2) && 
                    threadCalendar.GetYear(date1) == threadCalendar.GetYear(date2) &&
                    threadCalendar.GetMonth(date1) == threadCalendar.GetMonth(date2));
        }
 
        private bool IsMinSupportedYearMonth(DateTime date) {
#if DEBUG 
            Debug.Assert(threadCalendarInitialized); 
#endif
            return IsTheSameYearMonth(minSupportedDate, date); 
        }

        private bool IsMaxSupportedYearMonth(DateTime date) {
#if DEBUG 
            Debug.Assert(threadCalendarInitialized);
#endif 
            return IsTheSameYearMonth(maxSupportedDate, date); 
        }
 
        /// 
        /// 
        /// Loads a saved state of the . 
        ///  
        protected override void LoadViewState(object savedState) {
            if (savedState != null) { 
                object[] myState = (object[])savedState; 

                if (myState[0] != null) 
                    base.LoadViewState(myState[0]);
                if (myState[1] != null)
                    ((IStateManager)TitleStyle).LoadViewState(myState[1]);
                if (myState[2] != null) 
                    ((IStateManager)NextPrevStyle).LoadViewState(myState[2]);
                if (myState[3] != null) 
                    ((IStateManager)DayStyle).LoadViewState(myState[3]); 
                if (myState[4] != null)
                    ((IStateManager)DayHeaderStyle).LoadViewState(myState[4]); 
                if (myState[5] != null)
                    ((IStateManager)TodayDayStyle).LoadViewState(myState[5]);
                if (myState[6] != null)
                    ((IStateManager)WeekendDayStyle).LoadViewState(myState[6]); 
                if (myState[7] != null)
                    ((IStateManager)OtherMonthDayStyle).LoadViewState(myState[7]); 
                if (myState[8] != null) 
                    ((IStateManager)SelectedDayStyle).LoadViewState(myState[8]);
                if (myState[9] != null) 
                    ((IStateManager)SelectorStyle).LoadViewState(myState[9]);

                ArrayList selDates = (ArrayList)ViewState["SD"];
                if (selDates != null) { 
                    dateList = selDates;
                    selectedDates = null;   // reset wrapper collection 
                } 

            } 
        }


        ///  
        /// 
        ///    Marks the starting point to begin tracking and saving changes to the 
        ///       control as part of the control viewstate. 
        /// 
        protected override void TrackViewState() { 
            base.TrackViewState();

            if (titleStyle != null)
                ((IStateManager)titleStyle).TrackViewState(); 
            if (nextPrevStyle != null)
                ((IStateManager)nextPrevStyle).TrackViewState(); 
            if (dayStyle != null) 
                ((IStateManager)dayStyle).TrackViewState();
            if (dayHeaderStyle != null) 
                ((IStateManager)dayHeaderStyle).TrackViewState();
            if (todayDayStyle != null)
                ((IStateManager)todayDayStyle).TrackViewState();
            if (weekendDayStyle != null) 
                ((IStateManager)weekendDayStyle).TrackViewState();
            if (otherMonthDayStyle != null) 
                ((IStateManager)otherMonthDayStyle).TrackViewState(); 
            if (selectedDayStyle != null)
                ((IStateManager)selectedDayStyle).TrackViewState(); 
            if (selectorStyle != null)
                ((IStateManager)selectorStyle).TrackViewState();
        }
 

        ///  
        ///  
        private int NumericFirstDayOfWeek() {
            // Used globalized value by default 
            return(FirstDayOfWeek == FirstDayOfWeek.Default)
            ? (int) DateTimeFormatInfo.CurrentInfo.FirstDayOfWeek
            : (int) FirstDayOfWeek;
        } 

 
        ///  
        /// Raises the event for a .
        ///  
        protected virtual void OnDayRender(TableCell cell, CalendarDay day) {
            DayRenderEventHandler handler = (DayRenderEventHandler)Events[EventDayRender];
            if (handler != null) {
                int absoluteDay = day.Date.Subtract(baseDate).Days; 

                // VSWhidbey 215383: We return null for selectUrl if a control is not in 
                // the page control tree. 
                string selectUrl = null;
                Page page = Page; 
                if (page != null) {
                    string eventArgument = absoluteDay.ToString(CultureInfo.InvariantCulture);
                    selectUrl = Page.ClientScript.GetPostBackClientHyperlink(this, eventArgument, true);
                } 
                handler(this, new DayRenderEventArgs(cell, day, selectUrl));
            } 
        } 

        ///  
        /// Raises the event for a .
        /// 
        protected virtual void OnSelectionChanged() {
            EventHandler handler = (EventHandler)Events[EventSelectionChanged]; 
            if (handler != null) {
                handler(this, EventArgs.Empty); 
            } 
        }
 

        /// 
        /// Raises the event for a .
        ///  
        protected virtual void OnVisibleMonthChanged(DateTime newDate, DateTime previousDate) {
            MonthChangedEventHandler handler = (MonthChangedEventHandler)Events[EventVisibleMonthChanged]; 
            if (handler != null) { 
                handler(this, new MonthChangedEventArgs(newDate, previousDate));
            } 
        }


        ///  
        /// 
        /// Raises events on post back for the  control. 
        ///  
        protected virtual void RaisePostBackEvent(string eventArgument) {
 
            ValidateEvent(UniqueID, eventArgument);

            if (AdapterInternal != null) {
                IPostBackEventHandler pbeh = AdapterInternal as IPostBackEventHandler; 
                if (pbeh != null) {
                    pbeh.RaisePostBackEvent(eventArgument); 
                } 
            } else {
 
                if (String.Compare(eventArgument, 0, NAVIGATE_MONTH_COMMAND, 0, NAVIGATE_MONTH_COMMAND.Length, StringComparison.Ordinal) == 0) {
                    // Month navigation. The command starts with a "V" and the remainder is day difference from the
                    // base date.
                    DateTime oldDate = VisibleDate; 
                    if (oldDate.Equals(DateTime.MinValue)) {
                        oldDate = TodaysDate; 
                    } 
                    int newDateDiff = Int32.Parse(eventArgument.Substring(NAVIGATE_MONTH_COMMAND.Length), CultureInfo.InvariantCulture);
                    VisibleDate = baseDate.AddDays(newDateDiff); 
                    if (VisibleDate == DateTime.MinValue) {
                        // MinValue would make the calendar shows today's month instead because it
                        // is the default value of VisibleDate property, so we add a day to keep
                        // showing the first supported month. 
                        // We assume the first supported month has more than one day.
                        VisibleDate = DateTimeFormatInfo.CurrentInfo.Calendar.AddDays(VisibleDate, 1); 
                    } 
                    OnVisibleMonthChanged(VisibleDate, oldDate);
                } 
                else if (String.Compare(eventArgument, 0, SELECT_RANGE_COMMAND, 0, SELECT_RANGE_COMMAND.Length, StringComparison.Ordinal) == 0) {
                    // Range selection. The command starts with an "R". The remainder is an integer. When divided by 100
                    // the result is the day difference from the base date of the first day, and the remainder is the
                    // number of days to select. 
                    int rangeValue = Int32.Parse(eventArgument.Substring(SELECT_RANGE_COMMAND.Length), CultureInfo.InvariantCulture);
                    int dayDiff = rangeValue / 100; 
                    int dayRange = rangeValue % 100; 
                    if (dayRange < 1) {
                        dayRange = 100 + dayRange; 
                        dayDiff -= 1;
                    }
                    DateTime dt = baseDate.AddDays(dayDiff);
                    SelectRange(dt, dt.AddDays(dayRange - 1)); 
                }
                else { 
                    // Single day selection. This is just a number which is the day difference from the base date. 
                    int dayDiff = Int32.Parse(eventArgument, CultureInfo.InvariantCulture);
                    DateTime dt = baseDate.AddDays(dayDiff); 
                    SelectRange(dt, dt);
                }
            }
        } 

 
        void IPostBackEventHandler.RaisePostBackEvent(string eventArgument) { 
            RaisePostBackEvent(eventArgument);
        } 


        /// 
        protected internal override void OnPreRender(EventArgs e) { 
            base.OnPreRender(e);
            if (Page != null) { 
                Page.RegisterPostBackScript(); 
            }
        } 


        /// 
        ///  
        /// Displays the  control on the client.
        ///  
        protected internal override void Render(HtmlTextWriter writer) { 
            threadCalendar = DateTimeFormatInfo.CurrentInfo.Calendar;
            minSupportedDate = threadCalendar.MinSupportedDateTime; 
            maxSupportedDate = threadCalendar.MaxSupportedDateTime;
#if DEBUG
            threadCalendarInitialized = true;
#endif 
            DateTime visibleDate = EffectiveVisibleDate();
            DateTime firstDay = FirstCalendarDay(visibleDate); 
            CalendarSelectionMode selectionMode = SelectionMode; 

            // Make sure we are in a form tag with runat=server. 
            if (Page != null) {
                Page.VerifyRenderingInServerForm(this);
            }
 
            // We only want to display the link if we have a page, or if we are on the design surface
            // If we can stops links being active on the Autoformat dialog, then we can remove this these checks. 
            Page page = Page; 
            bool buttonsActive;
            if (page == null || DesignMode) { 
                buttonsActive = false;
            }
            else {
                buttonsActive = IsEnabled; 
            }
 
            defaultForeColor = ForeColor; 
            if (defaultForeColor == Color.Empty) {
                defaultForeColor = DefaultForeColor; 
            }
            defaultButtonColorText = ColorTranslator.ToHtml(defaultForeColor);

            Table table = new Table(); 

            if (ID != null) { 
                table.ID = ClientID; 
            }
            table.CopyBaseAttributes(this); 
            if (ControlStyleCreated) {
                table.ApplyStyle(ControlStyle);
            }
            table.Width = Width; 
            table.Height = Height;
            table.CellPadding = CellPadding; 
            table.CellSpacing = CellSpacing; 

            // default look 
            if ((ControlStyleCreated == false) ||
                (ControlStyle.IsSet(System.Web.UI.WebControls.Style.PROP_BORDERWIDTH) == false) ||
                BorderWidth.Equals(Unit.Empty)) {
                table.BorderWidth = Unit.Pixel(1); 
            }
 
            if (ShowGridLines) { 
                table.GridLines = GridLines.Both;
            } 
            else {
                table.GridLines = GridLines.None;
            }
 
            bool useAccessibleHeader = UseAccessibleHeader;
            if (useAccessibleHeader) { 
                if (table.Attributes["title"] == null) { 
                    table.Attributes["title"] = SR.GetString(SR.Calendar_TitleText);
                } 
            }

            string caption = Caption;
            if (caption.Length > 0) { 
                table.Caption = caption;
                table.CaptionAlign = CaptionAlign; 
            } 

            table.RenderBeginTag(writer); 

            if (ShowTitle) {
                RenderTitle(writer, visibleDate, selectionMode, buttonsActive, useAccessibleHeader);
            } 

            if (ShowDayHeader) { 
                RenderDayHeader(writer, visibleDate, selectionMode, buttonsActive, useAccessibleHeader); 
            }
 
            RenderDays(writer, firstDay, visibleDate, selectionMode, buttonsActive, useAccessibleHeader);

            table.RenderEndTag(writer);
        } 

        private void RenderCalendarCell(HtmlTextWriter writer, TableItemStyle style, string text, string title, bool hasButton, string eventArgument) { 
            style.AddAttributesToRender(writer, this); 
            writer.RenderBeginTag(HtmlTextWriterTag.Td);
 
            if (hasButton) {

                // render the button
                Color foreColor = style.ForeColor; 
                writer.Write("");
                writer.Write(text);
                writer.Write("");
            } 
            else {
                writer.Write(text); 
            } 

            writer.RenderEndTag(); 
        }

        private void RenderCalendarHeaderCell(HtmlTextWriter writer, TableItemStyle style, string text, string abbrText) {
            style.AddAttributesToRender(writer, this); 
            writer.AddAttribute("abbr", abbrText);
            writer.AddAttribute("scope", "col"); 
            writer.RenderBeginTag(HtmlTextWriterTag.Th); 
            writer.Write(text);
            writer.RenderEndTag(); 
        }


        ///  
        /// 
        private void RenderDayHeader(HtmlTextWriter writer, DateTime visibleDate, CalendarSelectionMode selectionMode, bool buttonsActive, bool useAccessibleHeader) { 
 
            writer.Write(ROWBEGINTAG);
 
            DateTimeFormatInfo dtf = DateTimeFormatInfo.CurrentInfo;

            if (HasWeekSelectors(selectionMode)) {
                TableItemStyle monthSelectorStyle = new TableItemStyle(); 
                monthSelectorStyle.HorizontalAlign = HorizontalAlign.Center;
                // add the month selector button if required; 
                if (selectionMode == CalendarSelectionMode.DayWeekMonth) { 

                    // Range selection. The command starts with an "R". The remainder is an integer. When divided by 100 
                    // the result is the day difference from the base date of the first day, and the remainder is the
                    // number of days to select.
                    int startOffset = visibleDate.Subtract(baseDate).Days;
                    int monthLength = threadCalendar.GetDaysInMonth(threadCalendar.GetYear(visibleDate), threadCalendar.GetMonth(visibleDate), threadCalendar.GetEra(visibleDate)); 
                    if (IsMinSupportedYearMonth(visibleDate)) {
                        // The first supported month might not start with day 1 
                        // (e.g. Sept 8 is the first supported date of JapaneseCalendar) 
                        monthLength = monthLength - threadCalendar.GetDayOfMonth(visibleDate) + 1;
                    } 
                    else if (IsMaxSupportedYearMonth(visibleDate)) {
                        // The last supported month might not have all days supported in that calendar month
                        // (e.g. April 3 is the last supported date of HijriCalendar)
                        monthLength = threadCalendar.GetDayOfMonth(maxSupportedDate); 
                    }
 
                    string monthSelectKey = SELECT_RANGE_COMMAND + ((startOffset * 100) + monthLength).ToString(CultureInfo.InvariantCulture); 
                    monthSelectorStyle.CopyFrom(SelectorStyle);
 
                    string selectMonthTitle = null;
                    if (useAccessibleHeader) {
                        selectMonthTitle = SR.GetString(SR.Calendar_SelectMonthTitle);
                    } 
                    RenderCalendarCell(writer, monthSelectorStyle, SelectMonthText, selectMonthTitle, buttonsActive, monthSelectKey);
                } 
                else { 
                    // otherwise make it look like the header row
                    monthSelectorStyle.CopyFrom(DayHeaderStyle); 
                    RenderCalendarCell(writer, monthSelectorStyle, string.Empty, null, false, null);
                }
            }
 
            TableItemStyle dayNameStyle = new TableItemStyle();
            dayNameStyle.HorizontalAlign = HorizontalAlign.Center; 
            dayNameStyle.CopyFrom(DayHeaderStyle); 
            DayNameFormat dayNameFormat = DayNameFormat;
 
            int numericFirstDay = NumericFirstDayOfWeek();
            for (int i = numericFirstDay; i < numericFirstDay + 7; i++) {
                string dayName;
                int dayOfWeek = i % 7; 
                switch (dayNameFormat) {
                    case DayNameFormat.FirstLetter: 
                        dayName = dtf.GetDayName((DayOfWeek)dayOfWeek).Substring(0, 1); 
                        break;
                    case DayNameFormat.FirstTwoLetters: 
                        dayName = dtf.GetDayName((DayOfWeek)dayOfWeek).Substring(0, 2);
                        break;
                    case DayNameFormat.Full:
                        dayName = dtf.GetDayName((DayOfWeek)dayOfWeek); 
                        break;
                    case DayNameFormat.Short: 
                        dayName = dtf.GetAbbreviatedDayName((DayOfWeek)dayOfWeek); 
                        break;
                    case DayNameFormat.Shortest: 
                        dayName = dtf.GetShortestDayName((DayOfWeek)dayOfWeek);
                        break;
                    default:
                        Debug.Assert(false, "Unknown DayNameFormat value!"); 
                        goto case DayNameFormat.Short;
                } 
 
                if (useAccessibleHeader) {
                    string fullDayName = dtf.GetDayName((DayOfWeek)dayOfWeek); 
                    RenderCalendarHeaderCell(writer, dayNameStyle, dayName, fullDayName);
                }
                else {
                    RenderCalendarCell(writer, dayNameStyle, dayName, null, false, null); 
                }
            } 
            writer.Write(ROWENDTAG); 
        }
 

        /// 
        /// 
        private void RenderDays(HtmlTextWriter writer, DateTime firstDay, DateTime visibleDate, CalendarSelectionMode selectionMode, bool buttonsActive, bool useAccessibleHeader) { 
            // Now add the rows for the actual days
 
            DateTime d = firstDay; 
            TableItemStyle weekSelectorStyle = null;
            Unit defaultWidth; 
            bool hasWeekSelectors = HasWeekSelectors(selectionMode);
            if (hasWeekSelectors) {
                weekSelectorStyle = new TableItemStyle();
                weekSelectorStyle.Width = Unit.Percentage(12); 
                weekSelectorStyle.HorizontalAlign = HorizontalAlign.Center;
                weekSelectorStyle.CopyFrom(SelectorStyle); 
                defaultWidth = Unit.Percentage(12); 
            }
            else { 
                defaultWidth = Unit.Percentage(14);
            }

            // This determines whether we need to call DateTime.ToString for each day. The only culture/calendar 
            // that requires this for now is the HebrewCalendar.
            bool usesStandardDayDigits = !(threadCalendar is HebrewCalendar); 
 
            // This determines whether we can write out cells directly, or whether we have to create whole
            // TableCell objects for each day. 
            bool hasRenderEvent = (this.GetType() != typeof(Calendar)
                                   || Events[EventDayRender] != null);

            TableItemStyle [] cellStyles = new TableItemStyle[16]; 
            int definedStyleMask = GetDefinedStyleMask();
            DateTime todaysDate = TodaysDate; 
            string selectWeekText = SelectWeekText; 
            bool daysSelectable = buttonsActive && (selectionMode != CalendarSelectionMode.None);
            int visibleDateMonth = threadCalendar.GetMonth(visibleDate); 
            int absoluteDay = firstDay.Subtract(baseDate).Days;

            // VSWhidbey 480155: flag to indicate if forecolor needs to be set
            // explicitly in design mode to mimic runtime rendering with the 
            // limitation of not supporting CSS class color setting.
            bool inDesignSelectionMode = (DesignMode && SelectionMode != CalendarSelectionMode.None); 
 
            //-----------------------------------------------------------------
            // VSWhidbey 366243: The following variables are for boundary cases 
            // such as the current visible month is the first or the last
            // supported month.  They are used in the 'for' loops below.

            // For the first supported month, calculate how many days to 
            // skip at the beginning of the first month.  E.g. JapaneseCalendar
            // starts at Sept 8. 
            int numOfFirstDaysToSkip = 0; 
            if (IsMinSupportedYearMonth(visibleDate)) {
                numOfFirstDaysToSkip = (int)threadCalendar.GetDayOfWeek(firstDay) - NumericFirstDayOfWeek(); 
                // If negative, it simply means the the index of the starting
                // day name is greater than the day name of the first supported
                // date.  We add back 7 to get the number of days to skip.
                if (numOfFirstDaysToSkip < 0) { 
                    numOfFirstDaysToSkip += 7;
                } 
            } 
            Debug.Assert(numOfFirstDaysToSkip < 7);
 
            // For the last or second last supported month, initialize variables
            // to identify the last supported date of the current calendar.
            // e.g. The last supported date of HijriCalendar is April 3.  When
            // the second last monthh is shown, it can be the case that not all 
            // cells will be filled up.
            bool passedLastSupportedDate = false; 
            DateTime secondLastMonth = threadCalendar.AddMonths(maxSupportedDate, -1); 
            bool lastOrSecondLastMonth = (IsMaxSupportedYearMonth(visibleDate) ||
                                IsTheSameYearMonth(secondLastMonth, visibleDate)); 
            //-----------------------------------------------------------------

            for (int iRow = 0; iRow < 6; iRow++) {
                if (passedLastSupportedDate) { 
                    break;
                } 
 
                writer.Write(ROWBEGINTAG);
 
                // add week selector column and button if required
                if (hasWeekSelectors) {
                    // Range selection. The command starts with an "R". The remainder is an integer. When divided by 100
                    // the result is the day difference from the base date of the first day, and the remainder is the 
                    // number of days to select.
                    int dayDiffParameter = (absoluteDay * 100) + 7; 
 
                    // Adjust the dayDiff for the first or the last supported month
                    if (numOfFirstDaysToSkip > 0) { 
                        dayDiffParameter -= numOfFirstDaysToSkip;
                    }
                    else if (lastOrSecondLastMonth) {
                        int daysFromLastDate = maxSupportedDate.Subtract(d).Days; 
                        if (daysFromLastDate < 6) {
                            dayDiffParameter -= (6 - daysFromLastDate); 
                        } 
                    }
                    string weekSelectKey = SELECT_RANGE_COMMAND + dayDiffParameter.ToString(CultureInfo.InvariantCulture); 

                    string selectWeekTitle = null;
                    if (useAccessibleHeader) {
                        int weekOfMonth = iRow + 1; 
                        selectWeekTitle = SR.GetString(SR.Calendar_SelectWeekTitle, weekOfMonth.ToString(CultureInfo.InvariantCulture));
                    } 
                    RenderCalendarCell(writer, weekSelectorStyle, selectWeekText, selectWeekTitle, buttonsActive, weekSelectKey); 
                }
 
                for (int iDay = 0; iDay < 7; iDay++) {

                    // Render empty cells for special cases to handle the first
                    // or last supported month. 
                    if (numOfFirstDaysToSkip > 0) {
                        iDay += numOfFirstDaysToSkip; 
                        for ( ; numOfFirstDaysToSkip > 0; numOfFirstDaysToSkip--) { 
                            writer.RenderBeginTag(HtmlTextWriterTag.Td);
                            writer.RenderEndTag(); 
                        }
                    }
                    else if (passedLastSupportedDate) {
                        for ( ; iDay < 7; iDay++) { 
                            writer.RenderBeginTag(HtmlTextWriterTag.Td);
                            writer.RenderEndTag(); 
                        } 
                        break;
                    } 

                    int dayOfWeek = (int)threadCalendar.GetDayOfWeek(d);
                    int dayOfMonth = threadCalendar.GetDayOfMonth(d);
                    string dayNumberText; 
                    if ((dayOfMonth <= cachedNumberMax) && usesStandardDayDigits) {
                        dayNumberText = cachedNumbers[dayOfMonth]; 
                    } 
                    else {
                        dayNumberText = d.ToString("dd", CultureInfo.CurrentCulture); 
                    }

                    CalendarDay day = new CalendarDay(d,
                                                      (dayOfWeek == 0 || dayOfWeek == 6), // IsWeekend 
                                                      d.Equals(todaysDate), // IsToday
                                                      (selectedDates != null) && selectedDates.Contains(d), // IsSelected 
                                                      threadCalendar.GetMonth(d) != visibleDateMonth, // IsOtherMonth 
                                                      dayNumberText // Number Text
                                                      ); 

                    int styleMask = STYLEMASK_DAY;
                    if (day.IsSelected)
                        styleMask |= STYLEMASK_SELECTED; 
                    if (day.IsOtherMonth)
                        styleMask |= STYLEMASK_OTHERMONTH; 
                    if (day.IsToday) 
                        styleMask |= STYLEMASK_TODAY;
                    if (day.IsWeekend) 
                        styleMask |= STYLEMASK_WEEKEND;
                    int dayStyleMask = definedStyleMask  & styleMask;
                    // determine the unique portion of the mask for the current calendar,
                    // which will strip out the day style bit 
                    int dayStyleID = dayStyleMask & STYLEMASK_UNIQUE;
 
                    TableItemStyle cellStyle = cellStyles[dayStyleID]; 
                    if (cellStyle == null) {
                        cellStyle = new TableItemStyle(); 
                        SetDayStyles(cellStyle, dayStyleMask, defaultWidth);
                        cellStyles[dayStyleID] = cellStyle;
                    }
 

                    string dayTitle = null; 
                    if (useAccessibleHeader) { 
                        dayTitle = d.ToString("m", CultureInfo.CurrentCulture);
                    } 

                    if (hasRenderEvent) {

                        TableCell cdc = new TableCell(); 
                        cdc.ApplyStyle(cellStyle);
 
                        LiteralControl dayContent = new LiteralControl(dayNumberText); 
                        cdc.Controls.Add(dayContent);
 
                        day.IsSelectable = daysSelectable;

                        OnDayRender(cdc, day);
 
                        // refresh the day content
                        dayContent.Text = GetCalendarButtonText(absoluteDay.ToString(CultureInfo.InvariantCulture), 
                                                                dayNumberText, 
                                                                dayTitle,
                                                                buttonsActive && day.IsSelectable, 
                                                                cdc.ForeColor);
                        cdc.RenderControl(writer);

                    } 
                    else {
                        // VSWhidbey 480155: In design mode we render days as 
                        // texts instead of links so CSS class color setting is 
                        // supported.  But this differs in runtime rendering
                        // where CSS class color setting is not supported.  To 
                        // correctly mimic the forecolor of runtime rendering in
                        // design time, the default color, which is used in
                        // runtime rendering, is explicitly set in this case.
                        if (inDesignSelectionMode && cellStyle.ForeColor.IsEmpty) { 
                            cellStyle.ForeColor = defaultForeColor;
                        } 
 
                        RenderCalendarCell(writer, cellStyle, dayNumberText, dayTitle, daysSelectable, absoluteDay.ToString(CultureInfo.InvariantCulture));
                    } 

                    Debug.Assert(!passedLastSupportedDate);
                    if (lastOrSecondLastMonth && d.Month == maxSupportedDate.Month && d.Day == maxSupportedDate.Day) {
                        passedLastSupportedDate = true; 
                    }
                    else { 
                        d = threadCalendar.AddDays(d, 1); 
                        absoluteDay++;
                    } 
                }
                writer.Write(ROWENDTAG);
            }
        } 

 
        ///  
        /// 
        private void RenderTitle(HtmlTextWriter writer, DateTime visibleDate, CalendarSelectionMode selectionMode, bool buttonsActive, bool useAccessibleHeader) { 
            writer.Write(ROWBEGINTAG);

            TableCell titleCell = new TableCell();
            Table titleTable = new Table(); 

            // default title table/cell styles 
            titleCell.ColumnSpan = HasWeekSelectors(selectionMode) ? 8 : 7; 
            titleCell.BackColor = Color.Silver;
            titleTable.GridLines = GridLines.None; 
            titleTable.Width = Unit.Percentage(100);
            titleTable.CellSpacing = 0;

            TableItemStyle titleStyle = TitleStyle; 
            ApplyTitleStyle(titleCell, titleTable, titleStyle);
 
            titleCell.RenderBeginTag(writer); 
            titleTable.RenderBeginTag(writer);
            writer.Write(ROWBEGINTAG); 

            NextPrevFormat nextPrevFormat = NextPrevFormat;

            TableItemStyle nextPrevStyle = new TableItemStyle(); 
            nextPrevStyle.Width = Unit.Percentage(15);
            nextPrevStyle.CopyFrom(NextPrevStyle); 
            if (ShowNextPrevMonth) { 
                if (IsMinSupportedYearMonth(visibleDate)) {
                    writer.RenderBeginTag(HtmlTextWriterTag.Td); 
                    writer.RenderEndTag();
                }
                else {
                    string prevMonthText; 
                    if (nextPrevFormat == NextPrevFormat.ShortMonth || nextPrevFormat == NextPrevFormat.FullMonth) {
                        int monthNo = threadCalendar.GetMonth(threadCalendar.AddMonths(visibleDate, - 1)); 
                        prevMonthText = GetMonthName(monthNo, (nextPrevFormat == NextPrevFormat.FullMonth)); 
                    }
                    else { 
                        prevMonthText = PrevMonthText;
                    }
                    // Month navigation. The command starts with a "V" and the remainder is day difference from the
                    // base date. 
                    DateTime prevMonthDate;
 
                    // VSWhidbey 366243: Some calendar's min supported date is 
                    // not the first day of the month (e.g. JapaneseCalendar.
                    // So if we are setting the second supported month, the prev 
                    // month link should always point to the first supported
                    // date instead of the first day of the previous month.
                    DateTime secondSupportedMonth = threadCalendar.AddMonths(minSupportedDate, 1);
                    if (IsTheSameYearMonth(secondSupportedMonth, visibleDate)) { 
                        prevMonthDate = minSupportedDate;
                    } 
                    else { 
                        prevMonthDate = threadCalendar.AddMonths(visibleDate, -1);
                    } 

                    string prevMonthKey = NAVIGATE_MONTH_COMMAND + (prevMonthDate.Subtract(baseDate)).Days.ToString(CultureInfo.InvariantCulture);

                    string previousMonthTitle = null; 
                    if (useAccessibleHeader) {
                        previousMonthTitle = SR.GetString(SR.Calendar_PreviousMonthTitle); 
                    } 
                    RenderCalendarCell(writer, nextPrevStyle, prevMonthText, previousMonthTitle, buttonsActive, prevMonthKey);
                } 
            }


            TableItemStyle cellMainStyle = new TableItemStyle(); 

            if (titleStyle.HorizontalAlign != HorizontalAlign.NotSet) { 
                cellMainStyle.HorizontalAlign = titleStyle.HorizontalAlign; 
            }
            else { 
                cellMainStyle.HorizontalAlign = HorizontalAlign.Center;
            }
            cellMainStyle.Wrap = titleStyle.Wrap;
            cellMainStyle.Width = Unit.Percentage(70); 

            string titleText; 
 
            switch (TitleFormat) {
                case TitleFormat.Month: 
                    titleText = visibleDate.ToString("MMMM", CultureInfo.CurrentCulture);
                    break;
                case TitleFormat.MonthYear:
                    string titlePattern = DateTimeFormatInfo.CurrentInfo.YearMonthPattern; 
                    // Some cultures have a comma in their YearMonthPattern, which does not look
                    // right in a calendar. Use a fixed pattern for those. 
                    if (titlePattern.IndexOf(',') >= 0) { 
                        titlePattern = "MMMM yyyy";
                    } 
                    titleText = visibleDate.ToString(titlePattern, CultureInfo.CurrentCulture);
                    break;
                default:
                    Debug.Assert(false, "Unknown TitleFormat value!"); 
                    goto case TitleFormat.MonthYear;
            } 
            RenderCalendarCell(writer, cellMainStyle, titleText, null, false, null); 

            if (ShowNextPrevMonth) { 
                if (IsMaxSupportedYearMonth(visibleDate)) {
                    writer.RenderBeginTag(HtmlTextWriterTag.Td);
                    writer.RenderEndTag();
                } 
                else {
                    // Style for this one is identical bar 
                    nextPrevStyle.HorizontalAlign = HorizontalAlign.Right; 
                    string nextMonthText;
                    if (nextPrevFormat == NextPrevFormat.ShortMonth || nextPrevFormat == NextPrevFormat.FullMonth) { 
                        int monthNo = threadCalendar.GetMonth(threadCalendar.AddMonths(visibleDate, 1));
                        nextMonthText = GetMonthName(monthNo, (nextPrevFormat == NextPrevFormat.FullMonth));
                    }
                    else { 
                        nextMonthText = NextMonthText;
                    } 
                    // Month navigation. The command starts with a "V" and the remainder is day difference from the 
                    // base date.
                    DateTime nextMonthDate = threadCalendar.AddMonths(visibleDate, 1); 
                    string nextMonthKey = NAVIGATE_MONTH_COMMAND + (nextMonthDate.Subtract(baseDate)).Days.ToString(CultureInfo.InvariantCulture);

                    string nextMonthTitle = null;
                    if (useAccessibleHeader) { 
                        nextMonthTitle = SR.GetString(SR.Calendar_NextMonthTitle);
                    } 
                    RenderCalendarCell(writer, nextPrevStyle, nextMonthText, nextMonthTitle, buttonsActive, nextMonthKey); 
                }
            } 
            writer.Write(ROWENDTAG);
            titleTable.RenderEndTag(writer);
            titleCell.RenderEndTag(writer);
            writer.Write(ROWENDTAG); 

        } 
 

        ///  
        /// 
        /// Stores the state of the System.Web.UI.WebControls.Calender.
        /// 
        protected override object SaveViewState() { 
            if (SelectedDates.Count > 0)
                ViewState["SD"] = dateList; 
 
            object[] myState = new object[10];
 
            myState[0] = base.SaveViewState();
            myState[1] = (titleStyle != null) ? ((IStateManager)titleStyle).SaveViewState() : null;
            myState[2] = (nextPrevStyle != null) ? ((IStateManager)nextPrevStyle).SaveViewState() : null;
            myState[3] = (dayStyle != null) ? ((IStateManager)dayStyle).SaveViewState() : null; 
            myState[4] = (dayHeaderStyle != null) ? ((IStateManager)dayHeaderStyle).SaveViewState() : null;
            myState[5] = (todayDayStyle != null) ? ((IStateManager)todayDayStyle).SaveViewState() : null; 
            myState[6] = (weekendDayStyle != null) ? ((IStateManager)weekendDayStyle).SaveViewState() : null; 
            myState[7] = (otherMonthDayStyle != null) ? ((IStateManager)otherMonthDayStyle).SaveViewState() : null;
            myState[8] = (selectedDayStyle != null) ? ((IStateManager)selectedDayStyle).SaveViewState() : null; 
            myState[9] = (selectorStyle != null) ? ((IStateManager)selectorStyle).SaveViewState() : null;

            for (int i = 0; i 
        /// 
        private void SetDayStyles(TableItemStyle style, int styleMask, Unit defaultWidth) {

            // default day styles 
            style.Width = defaultWidth;
            style.HorizontalAlign = HorizontalAlign.Center; 
 
            if ((styleMask & STYLEMASK_DAY) != 0) {
                style.CopyFrom(DayStyle); 
            }
            if ((styleMask & STYLEMASK_WEEKEND) != 0) {
                style.CopyFrom(WeekendDayStyle);
            } 
            if ((styleMask & STYLEMASK_OTHERMONTH) != 0) {
                style.CopyFrom(OtherMonthDayStyle); 
            } 
            if ((styleMask & STYLEMASK_TODAY) != 0) {
                style.CopyFrom(TodayDayStyle); 
            }

            if ((styleMask & STYLEMASK_SELECTED) != 0) {
                // default selected day style 
                style.ForeColor = Color.White;
                style.BackColor = Color.Silver; 
 
                style.CopyFrom(SelectedDayStyle);
            } 
        }
    }
}
 


// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Web.UI.WebControls { 
    using System.Threading; 
    using System.Globalization;
    using System.ComponentModel; 
    using System;
    using System.Web;
    using System.Web.UI;
    using System.Web.Util; 
    using System.Collections;
    using System.ComponentModel.Design; 
    using System.Drawing; 
    using System.Text;
 
    using System.IO;
    using System.Reflection;

 

    ///  
    ///    Displays a one-month calendar and allows the user to 
    ///       view and select a specific day, week, or month.
    ///  
    [
    ControlValueProperty("SelectedDate", typeof(DateTime), "1/1/0001"),
    DataBindingHandler("System.Web.UI.Design.WebControls.CalendarDataBindingHandler, " + AssemblyRef.SystemDesign),
    DefaultEvent("SelectionChanged"), 
    DefaultProperty("SelectedDate"),
    Designer("System.Web.UI.Design.WebControls.CalendarDesigner, " + AssemblyRef.SystemDesign), 
    SupportsEventValidation 
    ]
    public class Calendar : WebControl, IPostBackEventHandler { 

        private static readonly object EventDayRender = new object();
        private static readonly object EventSelectionChanged = new object();
        private static readonly object EventVisibleMonthChanged = new object(); 

        private TableItemStyle titleStyle; 
        private TableItemStyle nextPrevStyle; 
        private TableItemStyle dayHeaderStyle;
        private TableItemStyle selectorStyle; 
        private TableItemStyle dayStyle;
        private TableItemStyle otherMonthDayStyle;
        private TableItemStyle todayDayStyle;
        private TableItemStyle selectedDayStyle; 
        private TableItemStyle weekendDayStyle;
        private string defaultButtonColorText; 
 
        private static readonly Color DefaultForeColor = Color.Black;
        private Color defaultForeColor; 

        private ArrayList dateList;
        private SelectedDatesCollection selectedDates;
        private Globalization.Calendar threadCalendar; 
        private DateTime minSupportedDate;
        private DateTime maxSupportedDate; 
#if DEBUG 
        private bool threadCalendarInitialized;
#endif 

        private const string SELECT_RANGE_COMMAND = "R";
        private const string NAVIGATE_MONTH_COMMAND = "V";
 
        private static DateTime baseDate = new DateTime(2000, 1, 1);
 
        private const int STYLEMASK_DAY = 16; 
        private const int STYLEMASK_UNIQUE = 15;
        private const int STYLEMASK_SELECTED = 8; 
        private const int STYLEMASK_TODAY = 4;
        private const int STYLEMASK_OTHERMONTH = 2;
        private const int STYLEMASK_WEEKEND = 1;
        private const string ROWBEGINTAG = ""; 
        private const string ROWENDTAG = "";
 
        // Cache commonly used strings. This improves performance and memory usage. 
        private const int cachedNumberMax = 31;
        private static readonly string[] cachedNumbers = new string [] { 
                  "0",  "1",   "2",   "3",   "4",   "5",   "6",
                  "7",  "8",   "9",  "10",  "11",  "12",  "13",
                 "14", "15",  "16",  "17",  "18",  "19",  "20",
                 "21", "22",  "23",  "24",  "25",  "26",  "27", 
                 "28", "29",  "30",  "31",
        }; 
 

        ///  
        /// Initializes a new instance of the  class.
        /// 
        public Calendar() : base(HtmlTextWriterTag.Table) {
        } 

 
        [ 
        Localizable(true),
        DefaultValue(""), 
        WebCategory("Accessibility"),
        WebSysDescription(SR.Calendar_Caption)
        ]
        public virtual string Caption { 
            get {
                string s = (string)ViewState["Caption"]; 
                return (s != null) ? s : String.Empty; 
            }
            set { 
                ViewState["Caption"] = value;
            }
        }
 

        [ 
        DefaultValue(TableCaptionAlign.NotSet), 
        WebCategory("Accessibility"),
        WebSysDescription(SR.WebControl_CaptionAlign) 
        ]
        public virtual TableCaptionAlign CaptionAlign {
            get {
                object o = ViewState["CaptionAlign"]; 
                return (o != null) ? (TableCaptionAlign)o : TableCaptionAlign.NotSet;
            } 
            set { 
                if ((value < TableCaptionAlign.NotSet) ||
                    (value > TableCaptionAlign.Right)) { 
                    throw new ArgumentOutOfRangeException("value");
                }
                ViewState["CaptionAlign"] = value;
            } 
        }
 
 
        /// 
        ///    Gets or sets the amount of space between cells. 
        /// 
        [
        WebCategory("Layout"),
        DefaultValue(2), 
        WebSysDescription(SR.Calendar_CellPadding)
        ] 
        public int CellPadding { 
            get {
                object o = ViewState["CellPadding"]; 
                return((o == null) ? 2 : (int)o);
            }
            set {
                if (value < - 1 ) { 
                    throw new ArgumentOutOfRangeException("value");
                } 
                ViewState["CellPadding"] = value; 
            }
        } 


        /// 
        ///    Gets or sets the amount of space between the contents of a cell 
        ///       and the cell's border.
        ///  
        [ 
        WebCategory("Layout"),
        DefaultValue(0), 
        WebSysDescription(SR.Calendar_CellSpacing)
        ]
        public int CellSpacing {
            get { 
                object o = ViewState["CellSpacing"];
                return((o == null) ?  0 : (int)o); 
            } 
            set {
                if (value < -1 ) { 
                    throw new ArgumentOutOfRangeException("value");
                }
                ViewState["CellSpacing"] = (int)value;
            } 
        }
 
 
        /// 
        ///     Gets the style property of the day-of-the-week header. This property is read-only. 
        /// 
        [
        WebCategory("Styles"),
        WebSysDescription(SR.Calendar_DayHeaderStyle), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
        NotifyParentProperty(true), 
        PersistenceMode(PersistenceMode.InnerProperty) 
        ]
        public TableItemStyle DayHeaderStyle { 
            get {
                if (dayHeaderStyle == null) {
                    dayHeaderStyle = new TableItemStyle();
                    if (IsTrackingViewState) 
                        ((IStateManager)dayHeaderStyle).TrackViewState();
                } 
                return dayHeaderStyle; 
            }
        } 


        /// 
        ///    Gets or sets 
        ///       the format for the names of days.
        ///  
        [ 
        WebCategory("Appearance"),
        DefaultValue(DayNameFormat.Short), 
        WebSysDescription(SR.Calendar_DayNameFormat)
        ]
        public DayNameFormat DayNameFormat {
            get { 
                object dnf = ViewState["DayNameFormat"];
                return((dnf == null) ? DayNameFormat.Short : (DayNameFormat)dnf); 
            } 
            set {
                if (value < DayNameFormat.Full || value > DayNameFormat.Shortest) { 
                    throw new ArgumentOutOfRangeException("value");
                }
                ViewState["DayNameFormat"] = value;
            } 
        }
 
 
        /// 
        ///     Gets the style properties for the days. This property is read-only. 
        /// 
        [
        WebCategory("Styles"),
        DefaultValue(null), 
        WebSysDescription(SR.Calendar_DayStyle),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content), 
        NotifyParentProperty(true), 
        PersistenceMode(PersistenceMode.InnerProperty)
        ] 
        public TableItemStyle DayStyle {
            get {
                if (dayStyle == null) {
                    dayStyle = new TableItemStyle(); 
                    if (IsTrackingViewState)
                        ((IStateManager)dayStyle).TrackViewState(); 
                } 
                return dayStyle;
            } 
        }


        ///  
        ///     Gets
        ///       or sets the day of the week to display in the calendar's first 
        ///       column. 
        /// 
        [ 
        WebCategory("Appearance"),
        DefaultValue(FirstDayOfWeek.Default),
        WebSysDescription(SR.Calendar_FirstDayOfWeek)
        ] 
        public FirstDayOfWeek FirstDayOfWeek {
            get { 
                object o = ViewState["FirstDayOfWeek"]; 
                return((o == null) ? FirstDayOfWeek.Default : (FirstDayOfWeek)o);
            } 
            set {
                if (value < FirstDayOfWeek.Sunday || value > FirstDayOfWeek.Default) {
                    throw new ArgumentOutOfRangeException("value");
                } 

                ViewState["FirstDayOfWeek"] = value; 
            } 
        }
 

        /// 
        ///    Gets or sets the text shown for the next month
        ///       navigation hyperlink if the  property is set to 
        ///    .
        ///  
        [ 
        Localizable(true),
        WebCategory("Appearance"), 
        DefaultValue(">"),
        WebSysDescription(SR.Calendar_NextMonthText)
        ]
        public string NextMonthText { 
            get {
                object s = ViewState["NextMonthText"]; 
                return((s == null) ? ">" : (String) s); 
            }
            set { 
                ViewState["NextMonthText"] = value;
            }
        }
 

        ///  
        ///    Gets or sets the format of the next and previous month hyperlinks in the 
        ///       title.
        ///  
        [
        WebCategory("Appearance"),
        DefaultValue(NextPrevFormat.CustomText),
        WebSysDescription(SR.Calendar_NextPrevFormat) 
        ]
        public NextPrevFormat NextPrevFormat { 
            get { 
                object npf = ViewState["NextPrevFormat"];
                return((npf == null) ? NextPrevFormat.CustomText : (NextPrevFormat)npf); 
            }
            set {
                if (value < NextPrevFormat.CustomText || value > NextPrevFormat.FullMonth) {
                    throw new ArgumentOutOfRangeException("value"); 
                }
                ViewState["NextPrevFormat"] = value; 
            } 
        }
 

        /// 
        ///     Gets the style properties for the next/previous month navigators. This property is
        ///       read-only. 
        /// 
        [ 
        WebCategory("Styles"), 
        WebSysDescription(SR.Calendar_NextPrevStyle),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content), 
        NotifyParentProperty(true),
        PersistenceMode(PersistenceMode.InnerProperty)
        ]
        public TableItemStyle NextPrevStyle { 
            get {
                if (nextPrevStyle == null) { 
                    nextPrevStyle = new TableItemStyle(); 
                    if (IsTrackingViewState)
                        ((IStateManager)nextPrevStyle).TrackViewState(); 
                }
                return nextPrevStyle;
            }
        } 

 
 
        /// 
        ///    Gets the style properties for the days from the months preceding and following the current month. 
        ///       This property is read-only.
        /// 
        [
        WebCategory("Styles"), 
        DefaultValue(null),
        WebSysDescription(SR.Calendar_OtherMonthDayStyle), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content), 
        NotifyParentProperty(true),
        PersistenceMode(PersistenceMode.InnerProperty) 
        ]
        public TableItemStyle OtherMonthDayStyle {
            get {
                if (otherMonthDayStyle == null) { 
                    otherMonthDayStyle = new TableItemStyle();
                    if (IsTrackingViewState) 
                        ((IStateManager)otherMonthDayStyle).TrackViewState(); 

                } 
                return otherMonthDayStyle;
            }
        }
 

        ///  
        ///    Gets or sets the text shown for the previous month 
        ///       navigation hyperlink if the  property is set to
        ///     
        ///    .
        /// 
        [
        Localizable(true), 
        WebCategory("Appearance"),
        DefaultValue("<"), 
        WebSysDescription(SR.Calendar_PrevMonthText) 
        ]
        public string PrevMonthText { 
            get {
                object s = ViewState["PrevMonthText"];
                return((s == null) ? "<" : (String) s);
            } 
            set {
                ViewState["PrevMonthText"] = value; 
            } 
        }
 
        public override bool SupportsDisabledAttribute {
            get {
                return RenderingCompatibility < VersionUtil.Framework40;
            } 
        }
 
        ///  
        ///    Gets or sets the date that is currently selected
        ///       date. 
        /// 
        [
        Bindable(true, BindingDirection.TwoWay),
        DefaultValue(typeof(DateTime), "1/1/0001"), 
        WebSysDescription(SR.Calendar_SelectedDate)
        ] 
        public DateTime SelectedDate { 
            get {
                if (SelectedDates.Count == 0) { 
                    return DateTime.MinValue;
                }
                return SelectedDates[0];
            } 
            set {
                if (value == DateTime.MinValue) { 
                    SelectedDates.Clear(); 
                }
                else { 
                    SelectedDates.SelectRange(value, value);
                }
            }
        } 

 
        ///  
        /// Gets a collection of  objects representing days selected on the . This
        ///    property is read-only. 
        /// 
        [
        Browsable(false),
        WebSysDescription(SR.Calendar_SelectedDates), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ] 
        public SelectedDatesCollection SelectedDates { 
            get {
                if (selectedDates == null) { 
                    if (dateList == null) {
                        dateList = new ArrayList();
                    }
                    selectedDates = new SelectedDatesCollection(dateList); 
                }
                return selectedDates; 
            } 
        }
 

        /// 
        ///    Gets the style properties for the selected date. This property is read-only.
        ///  
        [
        WebCategory("Styles"), 
        DefaultValue(null), 
        WebSysDescription(SR.Calendar_SelectedDayStyle),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content), 
        NotifyParentProperty(true),
        PersistenceMode(PersistenceMode.InnerProperty)
        ]
        public TableItemStyle SelectedDayStyle { 
            get {
                if (selectedDayStyle == null) { 
                    selectedDayStyle = new TableItemStyle(); 
                    if (IsTrackingViewState)
                        ((IStateManager)selectedDayStyle).TrackViewState(); 
                }
                return selectedDayStyle;
            }
        } 

 
        ///  
        ///    Gets or sets the date selection capabilities on the
        ///     
        ///    to allow the user to select a day, week, or month.
        /// 
        [
        WebCategory("Behavior"), 
        DefaultValue(CalendarSelectionMode.Day),
        WebSysDescription(SR.Calendar_SelectionMode) 
        ] 
        public CalendarSelectionMode SelectionMode {
            get { 
                object csm = ViewState["SelectionMode"];
                return((csm == null) ? CalendarSelectionMode.Day : (CalendarSelectionMode)csm);
            }
            set { 
                if (value < CalendarSelectionMode.None || value > CalendarSelectionMode.DayWeekMonth) {
                    throw new ArgumentOutOfRangeException("value"); 
                } 
                ViewState["SelectionMode"] = value;
            } 
        }


        ///  
        ///    Gets or sets the text shown for the month selection in
        ///       the selector column if  is 
        ///    . 
        /// 
        [ 
        Localizable(true),
        WebCategory("Appearance"),
        DefaultValue(">>"),
        WebSysDescription(SR.Calendar_SelectMonthText) 
        ]
        public string SelectMonthText { 
            get { 
                object s = ViewState["SelectMonthText"];
                return((s == null) ? ">>" : (String) s); 
            }
            set {
                ViewState["SelectMonthText"] = value;
            } 
        }
 
 
        /// 
        ///     Gets the style properties for the week and month selectors. This property is read-only. 
        /// 
        [
        WebCategory("Styles"),
        WebSysDescription(SR.Calendar_SelectorStyle), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
        NotifyParentProperty(true), 
        PersistenceMode(PersistenceMode.InnerProperty) 
        ]
        public TableItemStyle SelectorStyle { 
            get {
                if (selectorStyle == null) {
                    selectorStyle = new TableItemStyle();
                    if (IsTrackingViewState) 
                        ((IStateManager)selectorStyle).TrackViewState();
                } 
                return selectorStyle; 
            }
        } 

        /// 
        ///    Gets or sets the text shown for the week selection in
        ///       the selector column if  is 
        ///    or
        ///    . 
        ///  
        [
        Localizable(true), 
        WebCategory("Appearance"),
        DefaultValue(">"),
        WebSysDescription(SR.Calendar_SelectWeekText)
        ] 
        public string SelectWeekText {
            get { 
                object s = ViewState["SelectWeekText"]; 
                return((s == null) ? ">" : (String) s);
            } 
            set {
                ViewState["SelectWeekText"] = value;
            }
        } 

 
        ///  
        ///    Gets or sets
        ///       a value indicating whether the days of the week are displayed. 
        /// 
        [
        WebCategory("Appearance"),
        DefaultValue(true), 
        WebSysDescription(SR.Calendar_ShowDayHeader)
        ] 
        public bool ShowDayHeader { 
            get {
                object b = ViewState["ShowDayHeader"]; 
                return((b == null) ? true : (bool)b);
            }
            set {
                ViewState["ShowDayHeader"] = value; 
            }
        } 
 

        ///  
        ///    Gets or set
        ///       a value indicating whether days on the calendar are displayed with a border.
        /// 
        [ 
        WebCategory("Appearance"),
        DefaultValue(false), 
        WebSysDescription(SR.Calendar_ShowGridLines) 
        ]
        public bool ShowGridLines { 
            get {
                object b= ViewState["ShowGridLines"];
                return((b == null) ? false : (bool)b);
            } 
            set {
                ViewState["ShowGridLines"] = value; 
            } 
        }
 

        /// 
        /// Gets or sets a value indicating whether the 
        /// displays the next and pervious month 
        /// hyperlinks in the title.
        ///  
        [ 
        WebCategory("Appearance"),
        DefaultValue(true), 
        WebSysDescription(SR.Calendar_ShowNextPrevMonth)
        ]
        public bool ShowNextPrevMonth {
            get { 
                object b = ViewState["ShowNextPrevMonth"];
                return((b == null) ? true : (bool)b); 
            } 
            set {
                ViewState["ShowNextPrevMonth"] = value; 
            }
        }

 
        /// 
        ///     Gets or 
        ///       sets a value indicating whether the title is displayed. 
        /// 
        [ 
        WebCategory("Appearance"),
        DefaultValue(true),
        WebSysDescription(SR.Calendar_ShowTitle)
        ] 
        public bool ShowTitle {
            get { 
                object b = ViewState["ShowTitle"]; 
                return((b == null) ? true : (bool)b);
            } 
            set {
                ViewState["ShowTitle"] = value;
            }
        } 

 
        ///  
        ///    Gets or sets how the month name is formatted in the title
        ///       bar. 
        /// 
        [
        WebCategory("Appearance"),
        DefaultValue(TitleFormat.MonthYear), 
        WebSysDescription(SR.Calendar_TitleFormat)
        ] 
        public TitleFormat TitleFormat { 
            get {
                object tf = ViewState["TitleFormat"]; 
                return((tf == null) ? TitleFormat.MonthYear : (TitleFormat)tf);
            }
            set {
                if (value < TitleFormat.Month || value > TitleFormat.MonthYear) { 
                    throw new ArgumentOutOfRangeException("value");
                } 
                ViewState["TitleFormat"] = value; 
            }
        } 


        /// 
        /// Gets the style properties of the  title. This property is 
        ///    read-only.
        ///  
        [ 
        WebCategory("Styles"),
        WebSysDescription(SR.Calendar_TitleStyle), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
        NotifyParentProperty(true),
        PersistenceMode(PersistenceMode.InnerProperty),
        ] 
        public TableItemStyle TitleStyle {
            get { 
                if (titleStyle == null) { 
                    titleStyle = new TableItemStyle();
                    if (IsTrackingViewState) 
                        ((IStateManager)titleStyle).TrackViewState();
                }
                return titleStyle;
            } 
        }
 
 
        /// 
        ///    Gets the style properties for today's date on the 
        ///    . This
        ///       property is read-only.
        /// 
        [ 
        WebCategory("Styles"),
        DefaultValue(null), 
        WebSysDescription(SR.Calendar_TodayDayStyle), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
        NotifyParentProperty(true), 
        PersistenceMode(PersistenceMode.InnerProperty)
        ]
        public TableItemStyle TodayDayStyle {
            get { 
                if (todayDayStyle == null) {
                    todayDayStyle = new TableItemStyle(); 
                    if (IsTrackingViewState) 
                        ((IStateManager)todayDayStyle).TrackViewState();
                } 
                return todayDayStyle;
            }
        }
 

        ///  
        ///    Gets or sets the value to use as today's date. 
        /// 
        [ 
        Browsable(false),
        WebSysDescription(SR.Calendar_TodaysDate),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ] 
        public DateTime TodaysDate {
            get { 
                object o = ViewState["TodaysDate"]; 
                return((o == null) ? DateTime.Today : (DateTime)o);
            } 
            set {
                ViewState["TodaysDate"] = value.Date;
            }
        } 

 
        [ 
        DefaultValue(true),
        WebCategory("Accessibility"), 
        WebSysDescription(SR.Table_UseAccessibleHeader)
        ]
        public virtual bool UseAccessibleHeader {
            get { 
                object o = ViewState["UseAccessibleHeader"];
                return (o != null) ? (bool)o : true; 
            } 
            set {
                ViewState["UseAccessibleHeader"] = value; 
            }
        }

 
        /// 
        ///    Gets or sets the date that specifies what month to display. The date can be 
        ///       be any date within the month. 
        /// 
        [ 
        Bindable(true),
        DefaultValue(typeof(DateTime), "1/1/0001"),
        WebSysDescription(SR.Calendar_VisibleDate)
        ] 
        public DateTime VisibleDate {
            get { 
                object o = ViewState["VisibleDate"]; 
                return((o == null) ? DateTime.MinValue : (DateTime)o);
            } 
            set {
                ViewState["VisibleDate"] = value.Date;
            }
        } 

 
        ///  
        ///    Gets the style properties for the displaying weekend dates. This property is
        ///       read-only. 
        /// 
        [
        WebCategory("Styles"),
        WebSysDescription(SR.Calendar_WeekendDayStyle), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
        NotifyParentProperty(true), 
        PersistenceMode(PersistenceMode.InnerProperty) 
        ]
        public TableItemStyle WeekendDayStyle { 
            get {
                if (weekendDayStyle == null) {
                    weekendDayStyle = new TableItemStyle();
                    if (IsTrackingViewState) 
                        ((IStateManager)weekendDayStyle).TrackViewState();
                } 
                return weekendDayStyle; 
            }
        } 



        ///  
        /// Occurs when each day is created in teh control hierarchy for the .
        ///  
        [ 
        WebCategory("Action"),
        WebSysDescription(SR.Calendar_OnDayRender) 
        ]
        public event DayRenderEventHandler DayRender {
            add {
                Events.AddHandler(EventDayRender, value); 
            }
            remove { 
                Events.RemoveHandler(EventDayRender, value); 
            }
        } 



 
        /// 
        ///    Occurs when the user clicks on a day, week, or month 
        ///       selector and changes the . 
        /// 
        [ 
        WebCategory("Action"),
        WebSysDescription(SR.Calendar_OnSelectionChanged)
        ]
        public event EventHandler SelectionChanged { 
            add {
                Events.AddHandler(EventSelectionChanged, value); 
            } 
            remove {
                Events.RemoveHandler(EventSelectionChanged, value); 
            }
        }

 

        ///  
        ///    Occurs when the 
        ///       user clicks on the next or previous month  controls on the title.
        ///  
        [
        WebCategory("Action"),
        WebSysDescription(SR.Calendar_OnVisibleMonthChanged)
        ] 
        public event MonthChangedEventHandler VisibleMonthChanged {
            add { 
                Events.AddHandler(EventVisibleMonthChanged, value); 
            }
            remove { 
                Events.RemoveHandler(EventVisibleMonthChanged, value);
            }
        }
 
        // Methods
 
 
        /// 
        ///  
        private void ApplyTitleStyle(TableCell titleCell, Table titleTable, TableItemStyle titleStyle) {
            // apply affects that affect the whole background to the cell
            if (titleStyle.BackColor != Color.Empty) {
                titleCell.BackColor = titleStyle.BackColor; 
            }
            if (titleStyle.BorderColor != Color.Empty) { 
                titleCell.BorderColor = titleStyle.BorderColor; 
            }
            if (titleStyle.BorderWidth != Unit.Empty) { 
                titleCell.BorderWidth= titleStyle.BorderWidth;
            }
            if (titleStyle.BorderStyle != BorderStyle.NotSet) {
                titleCell.BorderStyle = titleStyle.BorderStyle; 
            }
            if (titleStyle.Height != Unit.Empty) { 
                titleCell.Height = titleStyle.Height; 
            }
            if (titleStyle.VerticalAlign != VerticalAlign.NotSet) { 
                titleCell.VerticalAlign = titleStyle.VerticalAlign;
            }

            // apply affects that affect everything else to the table 
            if (titleStyle.CssClass.Length > 0) {
                titleTable.CssClass = titleStyle.CssClass; 
            } 
            else if (CssClass.Length > 0) {
                titleTable.CssClass = CssClass; 
            }

            if (titleStyle.ForeColor != Color.Empty) {
                titleTable.ForeColor = titleStyle.ForeColor; 
            }
            else if (ForeColor != Color.Empty) { 
                titleTable.ForeColor = ForeColor; 
            }
            titleTable.Font.CopyFrom(titleStyle.Font); 
            titleTable.Font.MergeWith(this.Font);

        }
 

        ///  
        ///  
        /// 
        protected override ControlCollection CreateControlCollection() { 
            return new InternalControlCollection(this);
        }

 

        ///  
        ///  
        private DateTime EffectiveVisibleDate() {
            DateTime visDate = VisibleDate; 
            if (visDate.Equals(DateTime.MinValue)) {
                visDate = TodaysDate;
            }
 
            // VSWhidbey 366243
            if (IsMinSupportedYearMonth(visDate)) { 
                return minSupportedDate; 
            }
            else { 
                return threadCalendar.AddDays(visDate, -(threadCalendar.GetDayOfMonth(visDate) - 1));
            }
        }
 

        ///  
        ///  
        private DateTime FirstCalendarDay(DateTime visibleDate) {
            DateTime firstDayOfMonth = visibleDate; 

            // VSWhidbey 366243
            if (IsMinSupportedYearMonth(firstDayOfMonth)) {
                return firstDayOfMonth; 
            }
 
            int daysFromLastMonth = ((int)threadCalendar.GetDayOfWeek(firstDayOfMonth)) - NumericFirstDayOfWeek(); 
            // Always display at least one day from the previous month
            if (daysFromLastMonth <= 0) { 
                daysFromLastMonth += 7;
            }
            return threadCalendar.AddDays(firstDayOfMonth, -daysFromLastMonth);
        } 

 
        ///  
        /// 
        private string GetCalendarButtonText(string eventArgument, string buttonText, string title, bool showLink, Color foreColor) { 
            if (showLink) {
                StringBuilder sb = new StringBuilder();
                sb.Append("");
                sb.Append(buttonText); 
                sb.Append("");
                return sb.ToString();
            }
            else { 
                return buttonText;
            } 
        } 

 
        /// 
        /// 
        private int GetDefinedStyleMask() {
 
            // Selected is always defined because it has default effects
            int styleMask = STYLEMASK_SELECTED; 
 
            if (dayStyle != null && !dayStyle.IsEmpty)
                styleMask |= STYLEMASK_DAY; 
            if (todayDayStyle != null && !todayDayStyle.IsEmpty)
                styleMask |= STYLEMASK_TODAY;
            if (otherMonthDayStyle != null && !otherMonthDayStyle.IsEmpty)
                styleMask |= STYLEMASK_OTHERMONTH; 
            if (weekendDayStyle != null && !weekendDayStyle.IsEmpty)
                styleMask |= STYLEMASK_WEEKEND; 
            return styleMask; 
        }
 

        /// 
        /// 
        private string GetMonthName(int m, bool bFull) { 
            if (bFull) {
                return DateTimeFormatInfo.CurrentInfo.GetMonthName(m); 
            } 
            else {
                return DateTimeFormatInfo.CurrentInfo.GetAbbreviatedMonthName(m); 
            }
        }

 
        /// 
        /// Determines if a  
        /// contains week selectors. 
        /// 
        protected bool HasWeekSelectors(CalendarSelectionMode selectionMode) { 
            return(selectionMode == CalendarSelectionMode.DayWeek
                   || selectionMode == CalendarSelectionMode.DayWeekMonth);
        }
 
        private bool IsTheSameYearMonth(DateTime date1, DateTime date2) {
#if DEBUG 
            Debug.Assert(threadCalendarInitialized); 
#endif
            return (threadCalendar.GetEra(date1) == threadCalendar.GetEra(date2) && 
                    threadCalendar.GetYear(date1) == threadCalendar.GetYear(date2) &&
                    threadCalendar.GetMonth(date1) == threadCalendar.GetMonth(date2));
        }
 
        private bool IsMinSupportedYearMonth(DateTime date) {
#if DEBUG 
            Debug.Assert(threadCalendarInitialized); 
#endif
            return IsTheSameYearMonth(minSupportedDate, date); 
        }

        private bool IsMaxSupportedYearMonth(DateTime date) {
#if DEBUG 
            Debug.Assert(threadCalendarInitialized);
#endif 
            return IsTheSameYearMonth(maxSupportedDate, date); 
        }
 
        /// 
        /// 
        /// Loads a saved state of the . 
        ///  
        protected override void LoadViewState(object savedState) {
            if (savedState != null) { 
                object[] myState = (object[])savedState; 

                if (myState[0] != null) 
                    base.LoadViewState(myState[0]);
                if (myState[1] != null)
                    ((IStateManager)TitleStyle).LoadViewState(myState[1]);
                if (myState[2] != null) 
                    ((IStateManager)NextPrevStyle).LoadViewState(myState[2]);
                if (myState[3] != null) 
                    ((IStateManager)DayStyle).LoadViewState(myState[3]); 
                if (myState[4] != null)
                    ((IStateManager)DayHeaderStyle).LoadViewState(myState[4]); 
                if (myState[5] != null)
                    ((IStateManager)TodayDayStyle).LoadViewState(myState[5]);
                if (myState[6] != null)
                    ((IStateManager)WeekendDayStyle).LoadViewState(myState[6]); 
                if (myState[7] != null)
                    ((IStateManager)OtherMonthDayStyle).LoadViewState(myState[7]); 
                if (myState[8] != null) 
                    ((IStateManager)SelectedDayStyle).LoadViewState(myState[8]);
                if (myState[9] != null) 
                    ((IStateManager)SelectorStyle).LoadViewState(myState[9]);

                ArrayList selDates = (ArrayList)ViewState["SD"];
                if (selDates != null) { 
                    dateList = selDates;
                    selectedDates = null;   // reset wrapper collection 
                } 

            } 
        }


        ///  
        /// 
        ///    Marks the starting point to begin tracking and saving changes to the 
        ///       control as part of the control viewstate. 
        /// 
        protected override void TrackViewState() { 
            base.TrackViewState();

            if (titleStyle != null)
                ((IStateManager)titleStyle).TrackViewState(); 
            if (nextPrevStyle != null)
                ((IStateManager)nextPrevStyle).TrackViewState(); 
            if (dayStyle != null) 
                ((IStateManager)dayStyle).TrackViewState();
            if (dayHeaderStyle != null) 
                ((IStateManager)dayHeaderStyle).TrackViewState();
            if (todayDayStyle != null)
                ((IStateManager)todayDayStyle).TrackViewState();
            if (weekendDayStyle != null) 
                ((IStateManager)weekendDayStyle).TrackViewState();
            if (otherMonthDayStyle != null) 
                ((IStateManager)otherMonthDayStyle).TrackViewState(); 
            if (selectedDayStyle != null)
                ((IStateManager)selectedDayStyle).TrackViewState(); 
            if (selectorStyle != null)
                ((IStateManager)selectorStyle).TrackViewState();
        }
 

        ///  
        ///  
        private int NumericFirstDayOfWeek() {
            // Used globalized value by default 
            return(FirstDayOfWeek == FirstDayOfWeek.Default)
            ? (int) DateTimeFormatInfo.CurrentInfo.FirstDayOfWeek
            : (int) FirstDayOfWeek;
        } 

 
        ///  
        /// Raises the event for a .
        ///  
        protected virtual void OnDayRender(TableCell cell, CalendarDay day) {
            DayRenderEventHandler handler = (DayRenderEventHandler)Events[EventDayRender];
            if (handler != null) {
                int absoluteDay = day.Date.Subtract(baseDate).Days; 

                // VSWhidbey 215383: We return null for selectUrl if a control is not in 
                // the page control tree. 
                string selectUrl = null;
                Page page = Page; 
                if (page != null) {
                    string eventArgument = absoluteDay.ToString(CultureInfo.InvariantCulture);
                    selectUrl = Page.ClientScript.GetPostBackClientHyperlink(this, eventArgument, true);
                } 
                handler(this, new DayRenderEventArgs(cell, day, selectUrl));
            } 
        } 

        ///  
        /// Raises the event for a .
        /// 
        protected virtual void OnSelectionChanged() {
            EventHandler handler = (EventHandler)Events[EventSelectionChanged]; 
            if (handler != null) {
                handler(this, EventArgs.Empty); 
            } 
        }
 

        /// 
        /// Raises the event for a .
        ///  
        protected virtual void OnVisibleMonthChanged(DateTime newDate, DateTime previousDate) {
            MonthChangedEventHandler handler = (MonthChangedEventHandler)Events[EventVisibleMonthChanged]; 
            if (handler != null) { 
                handler(this, new MonthChangedEventArgs(newDate, previousDate));
            } 
        }


        ///  
        /// 
        /// Raises events on post back for the  control. 
        ///  
        protected virtual void RaisePostBackEvent(string eventArgument) {
 
            ValidateEvent(UniqueID, eventArgument);

            if (AdapterInternal != null) {
                IPostBackEventHandler pbeh = AdapterInternal as IPostBackEventHandler; 
                if (pbeh != null) {
                    pbeh.RaisePostBackEvent(eventArgument); 
                } 
            } else {
 
                if (String.Compare(eventArgument, 0, NAVIGATE_MONTH_COMMAND, 0, NAVIGATE_MONTH_COMMAND.Length, StringComparison.Ordinal) == 0) {
                    // Month navigation. The command starts with a "V" and the remainder is day difference from the
                    // base date.
                    DateTime oldDate = VisibleDate; 
                    if (oldDate.Equals(DateTime.MinValue)) {
                        oldDate = TodaysDate; 
                    } 
                    int newDateDiff = Int32.Parse(eventArgument.Substring(NAVIGATE_MONTH_COMMAND.Length), CultureInfo.InvariantCulture);
                    VisibleDate = baseDate.AddDays(newDateDiff); 
                    if (VisibleDate == DateTime.MinValue) {
                        // MinValue would make the calendar shows today's month instead because it
                        // is the default value of VisibleDate property, so we add a day to keep
                        // showing the first supported month. 
                        // We assume the first supported month has more than one day.
                        VisibleDate = DateTimeFormatInfo.CurrentInfo.Calendar.AddDays(VisibleDate, 1); 
                    } 
                    OnVisibleMonthChanged(VisibleDate, oldDate);
                } 
                else if (String.Compare(eventArgument, 0, SELECT_RANGE_COMMAND, 0, SELECT_RANGE_COMMAND.Length, StringComparison.Ordinal) == 0) {
                    // Range selection. The command starts with an "R". The remainder is an integer. When divided by 100
                    // the result is the day difference from the base date of the first day, and the remainder is the
                    // number of days to select. 
                    int rangeValue = Int32.Parse(eventArgument.Substring(SELECT_RANGE_COMMAND.Length), CultureInfo.InvariantCulture);
                    int dayDiff = rangeValue / 100; 
                    int dayRange = rangeValue % 100; 
                    if (dayRange < 1) {
                        dayRange = 100 + dayRange; 
                        dayDiff -= 1;
                    }
                    DateTime dt = baseDate.AddDays(dayDiff);
                    SelectRange(dt, dt.AddDays(dayRange - 1)); 
                }
                else { 
                    // Single day selection. This is just a number which is the day difference from the base date. 
                    int dayDiff = Int32.Parse(eventArgument, CultureInfo.InvariantCulture);
                    DateTime dt = baseDate.AddDays(dayDiff); 
                    SelectRange(dt, dt);
                }
            }
        } 

 
        void IPostBackEventHandler.RaisePostBackEvent(string eventArgument) { 
            RaisePostBackEvent(eventArgument);
        } 


        /// 
        protected internal override void OnPreRender(EventArgs e) { 
            base.OnPreRender(e);
            if (Page != null) { 
                Page.RegisterPostBackScript(); 
            }
        } 


        /// 
        ///  
        /// Displays the  control on the client.
        ///  
        protected internal override void Render(HtmlTextWriter writer) { 
            threadCalendar = DateTimeFormatInfo.CurrentInfo.Calendar;
            minSupportedDate = threadCalendar.MinSupportedDateTime; 
            maxSupportedDate = threadCalendar.MaxSupportedDateTime;
#if DEBUG
            threadCalendarInitialized = true;
#endif 
            DateTime visibleDate = EffectiveVisibleDate();
            DateTime firstDay = FirstCalendarDay(visibleDate); 
            CalendarSelectionMode selectionMode = SelectionMode; 

            // Make sure we are in a form tag with runat=server. 
            if (Page != null) {
                Page.VerifyRenderingInServerForm(this);
            }
 
            // We only want to display the link if we have a page, or if we are on the design surface
            // If we can stops links being active on the Autoformat dialog, then we can remove this these checks. 
            Page page = Page; 
            bool buttonsActive;
            if (page == null || DesignMode) { 
                buttonsActive = false;
            }
            else {
                buttonsActive = IsEnabled; 
            }
 
            defaultForeColor = ForeColor; 
            if (defaultForeColor == Color.Empty) {
                defaultForeColor = DefaultForeColor; 
            }
            defaultButtonColorText = ColorTranslator.ToHtml(defaultForeColor);

            Table table = new Table(); 

            if (ID != null) { 
                table.ID = ClientID; 
            }
            table.CopyBaseAttributes(this); 
            if (ControlStyleCreated) {
                table.ApplyStyle(ControlStyle);
            }
            table.Width = Width; 
            table.Height = Height;
            table.CellPadding = CellPadding; 
            table.CellSpacing = CellSpacing; 

            // default look 
            if ((ControlStyleCreated == false) ||
                (ControlStyle.IsSet(System.Web.UI.WebControls.Style.PROP_BORDERWIDTH) == false) ||
                BorderWidth.Equals(Unit.Empty)) {
                table.BorderWidth = Unit.Pixel(1); 
            }
 
            if (ShowGridLines) { 
                table.GridLines = GridLines.Both;
            } 
            else {
                table.GridLines = GridLines.None;
            }
 
            bool useAccessibleHeader = UseAccessibleHeader;
            if (useAccessibleHeader) { 
                if (table.Attributes["title"] == null) { 
                    table.Attributes["title"] = SR.GetString(SR.Calendar_TitleText);
                } 
            }

            string caption = Caption;
            if (caption.Length > 0) { 
                table.Caption = caption;
                table.CaptionAlign = CaptionAlign; 
            } 

            table.RenderBeginTag(writer); 

            if (ShowTitle) {
                RenderTitle(writer, visibleDate, selectionMode, buttonsActive, useAccessibleHeader);
            } 

            if (ShowDayHeader) { 
                RenderDayHeader(writer, visibleDate, selectionMode, buttonsActive, useAccessibleHeader); 
            }
 
            RenderDays(writer, firstDay, visibleDate, selectionMode, buttonsActive, useAccessibleHeader);

            table.RenderEndTag(writer);
        } 

        private void RenderCalendarCell(HtmlTextWriter writer, TableItemStyle style, string text, string title, bool hasButton, string eventArgument) { 
            style.AddAttributesToRender(writer, this); 
            writer.RenderBeginTag(HtmlTextWriterTag.Td);
 
            if (hasButton) {

                // render the button
                Color foreColor = style.ForeColor; 
                writer.Write("");
                writer.Write(text);
                writer.Write("");
            } 
            else {
                writer.Write(text); 
            } 

            writer.RenderEndTag(); 
        }

        private void RenderCalendarHeaderCell(HtmlTextWriter writer, TableItemStyle style, string text, string abbrText) {
            style.AddAttributesToRender(writer, this); 
            writer.AddAttribute("abbr", abbrText);
            writer.AddAttribute("scope", "col"); 
            writer.RenderBeginTag(HtmlTextWriterTag.Th); 
            writer.Write(text);
            writer.RenderEndTag(); 
        }


        ///  
        /// 
        private void RenderDayHeader(HtmlTextWriter writer, DateTime visibleDate, CalendarSelectionMode selectionMode, bool buttonsActive, bool useAccessibleHeader) { 
 
            writer.Write(ROWBEGINTAG);
 
            DateTimeFormatInfo dtf = DateTimeFormatInfo.CurrentInfo;

            if (HasWeekSelectors(selectionMode)) {
                TableItemStyle monthSelectorStyle = new TableItemStyle(); 
                monthSelectorStyle.HorizontalAlign = HorizontalAlign.Center;
                // add the month selector button if required; 
                if (selectionMode == CalendarSelectionMode.DayWeekMonth) { 

                    // Range selection. The command starts with an "R". The remainder is an integer. When divided by 100 
                    // the result is the day difference from the base date of the first day, and the remainder is the
                    // number of days to select.
                    int startOffset = visibleDate.Subtract(baseDate).Days;
                    int monthLength = threadCalendar.GetDaysInMonth(threadCalendar.GetYear(visibleDate), threadCalendar.GetMonth(visibleDate), threadCalendar.GetEra(visibleDate)); 
                    if (IsMinSupportedYearMonth(visibleDate)) {
                        // The first supported month might not start with day 1 
                        // (e.g. Sept 8 is the first supported date of JapaneseCalendar) 
                        monthLength = monthLength - threadCalendar.GetDayOfMonth(visibleDate) + 1;
                    } 
                    else if (IsMaxSupportedYearMonth(visibleDate)) {
                        // The last supported month might not have all days supported in that calendar month
                        // (e.g. April 3 is the last supported date of HijriCalendar)
                        monthLength = threadCalendar.GetDayOfMonth(maxSupportedDate); 
                    }
 
                    string monthSelectKey = SELECT_RANGE_COMMAND + ((startOffset * 100) + monthLength).ToString(CultureInfo.InvariantCulture); 
                    monthSelectorStyle.CopyFrom(SelectorStyle);
 
                    string selectMonthTitle = null;
                    if (useAccessibleHeader) {
                        selectMonthTitle = SR.GetString(SR.Calendar_SelectMonthTitle);
                    } 
                    RenderCalendarCell(writer, monthSelectorStyle, SelectMonthText, selectMonthTitle, buttonsActive, monthSelectKey);
                } 
                else { 
                    // otherwise make it look like the header row
                    monthSelectorStyle.CopyFrom(DayHeaderStyle); 
                    RenderCalendarCell(writer, monthSelectorStyle, string.Empty, null, false, null);
                }
            }
 
            TableItemStyle dayNameStyle = new TableItemStyle();
            dayNameStyle.HorizontalAlign = HorizontalAlign.Center; 
            dayNameStyle.CopyFrom(DayHeaderStyle); 
            DayNameFormat dayNameFormat = DayNameFormat;
 
            int numericFirstDay = NumericFirstDayOfWeek();
            for (int i = numericFirstDay; i < numericFirstDay + 7; i++) {
                string dayName;
                int dayOfWeek = i % 7; 
                switch (dayNameFormat) {
                    case DayNameFormat.FirstLetter: 
                        dayName = dtf.GetDayName((DayOfWeek)dayOfWeek).Substring(0, 1); 
                        break;
                    case DayNameFormat.FirstTwoLetters: 
                        dayName = dtf.GetDayName((DayOfWeek)dayOfWeek).Substring(0, 2);
                        break;
                    case DayNameFormat.Full:
                        dayName = dtf.GetDayName((DayOfWeek)dayOfWeek); 
                        break;
                    case DayNameFormat.Short: 
                        dayName = dtf.GetAbbreviatedDayName((DayOfWeek)dayOfWeek); 
                        break;
                    case DayNameFormat.Shortest: 
                        dayName = dtf.GetShortestDayName((DayOfWeek)dayOfWeek);
                        break;
                    default:
                        Debug.Assert(false, "Unknown DayNameFormat value!"); 
                        goto case DayNameFormat.Short;
                } 
 
                if (useAccessibleHeader) {
                    string fullDayName = dtf.GetDayName((DayOfWeek)dayOfWeek); 
                    RenderCalendarHeaderCell(writer, dayNameStyle, dayName, fullDayName);
                }
                else {
                    RenderCalendarCell(writer, dayNameStyle, dayName, null, false, null); 
                }
            } 
            writer.Write(ROWENDTAG); 
        }
 

        /// 
        /// 
        private void RenderDays(HtmlTextWriter writer, DateTime firstDay, DateTime visibleDate, CalendarSelectionMode selectionMode, bool buttonsActive, bool useAccessibleHeader) { 
            // Now add the rows for the actual days
 
            DateTime d = firstDay; 
            TableItemStyle weekSelectorStyle = null;
            Unit defaultWidth; 
            bool hasWeekSelectors = HasWeekSelectors(selectionMode);
            if (hasWeekSelectors) {
                weekSelectorStyle = new TableItemStyle();
                weekSelectorStyle.Width = Unit.Percentage(12); 
                weekSelectorStyle.HorizontalAlign = HorizontalAlign.Center;
                weekSelectorStyle.CopyFrom(SelectorStyle); 
                defaultWidth = Unit.Percentage(12); 
            }
            else { 
                defaultWidth = Unit.Percentage(14);
            }

            // This determines whether we need to call DateTime.ToString for each day. The only culture/calendar 
            // that requires this for now is the HebrewCalendar.
            bool usesStandardDayDigits = !(threadCalendar is HebrewCalendar); 
 
            // This determines whether we can write out cells directly, or whether we have to create whole
            // TableCell objects for each day. 
            bool hasRenderEvent = (this.GetType() != typeof(Calendar)
                                   || Events[EventDayRender] != null);

            TableItemStyle [] cellStyles = new TableItemStyle[16]; 
            int definedStyleMask = GetDefinedStyleMask();
            DateTime todaysDate = TodaysDate; 
            string selectWeekText = SelectWeekText; 
            bool daysSelectable = buttonsActive && (selectionMode != CalendarSelectionMode.None);
            int visibleDateMonth = threadCalendar.GetMonth(visibleDate); 
            int absoluteDay = firstDay.Subtract(baseDate).Days;

            // VSWhidbey 480155: flag to indicate if forecolor needs to be set
            // explicitly in design mode to mimic runtime rendering with the 
            // limitation of not supporting CSS class color setting.
            bool inDesignSelectionMode = (DesignMode && SelectionMode != CalendarSelectionMode.None); 
 
            //-----------------------------------------------------------------
            // VSWhidbey 366243: The following variables are for boundary cases 
            // such as the current visible month is the first or the last
            // supported month.  They are used in the 'for' loops below.

            // For the first supported month, calculate how many days to 
            // skip at the beginning of the first month.  E.g. JapaneseCalendar
            // starts at Sept 8. 
            int numOfFirstDaysToSkip = 0; 
            if (IsMinSupportedYearMonth(visibleDate)) {
                numOfFirstDaysToSkip = (int)threadCalendar.GetDayOfWeek(firstDay) - NumericFirstDayOfWeek(); 
                // If negative, it simply means the the index of the starting
                // day name is greater than the day name of the first supported
                // date.  We add back 7 to get the number of days to skip.
                if (numOfFirstDaysToSkip < 0) { 
                    numOfFirstDaysToSkip += 7;
                } 
            } 
            Debug.Assert(numOfFirstDaysToSkip < 7);
 
            // For the last or second last supported month, initialize variables
            // to identify the last supported date of the current calendar.
            // e.g. The last supported date of HijriCalendar is April 3.  When
            // the second last monthh is shown, it can be the case that not all 
            // cells will be filled up.
            bool passedLastSupportedDate = false; 
            DateTime secondLastMonth = threadCalendar.AddMonths(maxSupportedDate, -1); 
            bool lastOrSecondLastMonth = (IsMaxSupportedYearMonth(visibleDate) ||
                                IsTheSameYearMonth(secondLastMonth, visibleDate)); 
            //-----------------------------------------------------------------

            for (int iRow = 0; iRow < 6; iRow++) {
                if (passedLastSupportedDate) { 
                    break;
                } 
 
                writer.Write(ROWBEGINTAG);
 
                // add week selector column and button if required
                if (hasWeekSelectors) {
                    // Range selection. The command starts with an "R". The remainder is an integer. When divided by 100
                    // the result is the day difference from the base date of the first day, and the remainder is the 
                    // number of days to select.
                    int dayDiffParameter = (absoluteDay * 100) + 7; 
 
                    // Adjust the dayDiff for the first or the last supported month
                    if (numOfFirstDaysToSkip > 0) { 
                        dayDiffParameter -= numOfFirstDaysToSkip;
                    }
                    else if (lastOrSecondLastMonth) {
                        int daysFromLastDate = maxSupportedDate.Subtract(d).Days; 
                        if (daysFromLastDate < 6) {
                            dayDiffParameter -= (6 - daysFromLastDate); 
                        } 
                    }
                    string weekSelectKey = SELECT_RANGE_COMMAND + dayDiffParameter.ToString(CultureInfo.InvariantCulture); 

                    string selectWeekTitle = null;
                    if (useAccessibleHeader) {
                        int weekOfMonth = iRow + 1; 
                        selectWeekTitle = SR.GetString(SR.Calendar_SelectWeekTitle, weekOfMonth.ToString(CultureInfo.InvariantCulture));
                    } 
                    RenderCalendarCell(writer, weekSelectorStyle, selectWeekText, selectWeekTitle, buttonsActive, weekSelectKey); 
                }
 
                for (int iDay = 0; iDay < 7; iDay++) {

                    // Render empty cells for special cases to handle the first
                    // or last supported month. 
                    if (numOfFirstDaysToSkip > 0) {
                        iDay += numOfFirstDaysToSkip; 
                        for ( ; numOfFirstDaysToSkip > 0; numOfFirstDaysToSkip--) { 
                            writer.RenderBeginTag(HtmlTextWriterTag.Td);
                            writer.RenderEndTag(); 
                        }
                    }
                    else if (passedLastSupportedDate) {
                        for ( ; iDay < 7; iDay++) { 
                            writer.RenderBeginTag(HtmlTextWriterTag.Td);
                            writer.RenderEndTag(); 
                        } 
                        break;
                    } 

                    int dayOfWeek = (int)threadCalendar.GetDayOfWeek(d);
                    int dayOfMonth = threadCalendar.GetDayOfMonth(d);
                    string dayNumberText; 
                    if ((dayOfMonth <= cachedNumberMax) && usesStandardDayDigits) {
                        dayNumberText = cachedNumbers[dayOfMonth]; 
                    } 
                    else {
                        dayNumberText = d.ToString("dd", CultureInfo.CurrentCulture); 
                    }

                    CalendarDay day = new CalendarDay(d,
                                                      (dayOfWeek == 0 || dayOfWeek == 6), // IsWeekend 
                                                      d.Equals(todaysDate), // IsToday
                                                      (selectedDates != null) && selectedDates.Contains(d), // IsSelected 
                                                      threadCalendar.GetMonth(d) != visibleDateMonth, // IsOtherMonth 
                                                      dayNumberText // Number Text
                                                      ); 

                    int styleMask = STYLEMASK_DAY;
                    if (day.IsSelected)
                        styleMask |= STYLEMASK_SELECTED; 
                    if (day.IsOtherMonth)
                        styleMask |= STYLEMASK_OTHERMONTH; 
                    if (day.IsToday) 
                        styleMask |= STYLEMASK_TODAY;
                    if (day.IsWeekend) 
                        styleMask |= STYLEMASK_WEEKEND;
                    int dayStyleMask = definedStyleMask  & styleMask;
                    // determine the unique portion of the mask for the current calendar,
                    // which will strip out the day style bit 
                    int dayStyleID = dayStyleMask & STYLEMASK_UNIQUE;
 
                    TableItemStyle cellStyle = cellStyles[dayStyleID]; 
                    if (cellStyle == null) {
                        cellStyle = new TableItemStyle(); 
                        SetDayStyles(cellStyle, dayStyleMask, defaultWidth);
                        cellStyles[dayStyleID] = cellStyle;
                    }
 

                    string dayTitle = null; 
                    if (useAccessibleHeader) { 
                        dayTitle = d.ToString("m", CultureInfo.CurrentCulture);
                    } 

                    if (hasRenderEvent) {

                        TableCell cdc = new TableCell(); 
                        cdc.ApplyStyle(cellStyle);
 
                        LiteralControl dayContent = new LiteralControl(dayNumberText); 
                        cdc.Controls.Add(dayContent);
 
                        day.IsSelectable = daysSelectable;

                        OnDayRender(cdc, day);
 
                        // refresh the day content
                        dayContent.Text = GetCalendarButtonText(absoluteDay.ToString(CultureInfo.InvariantCulture), 
                                                                dayNumberText, 
                                                                dayTitle,
                                                                buttonsActive && day.IsSelectable, 
                                                                cdc.ForeColor);
                        cdc.RenderControl(writer);

                    } 
                    else {
                        // VSWhidbey 480155: In design mode we render days as 
                        // texts instead of links so CSS class color setting is 
                        // supported.  But this differs in runtime rendering
                        // where CSS class color setting is not supported.  To 
                        // correctly mimic the forecolor of runtime rendering in
                        // design time, the default color, which is used in
                        // runtime rendering, is explicitly set in this case.
                        if (inDesignSelectionMode && cellStyle.ForeColor.IsEmpty) { 
                            cellStyle.ForeColor = defaultForeColor;
                        } 
 
                        RenderCalendarCell(writer, cellStyle, dayNumberText, dayTitle, daysSelectable, absoluteDay.ToString(CultureInfo.InvariantCulture));
                    } 

                    Debug.Assert(!passedLastSupportedDate);
                    if (lastOrSecondLastMonth && d.Month == maxSupportedDate.Month && d.Day == maxSupportedDate.Day) {
                        passedLastSupportedDate = true; 
                    }
                    else { 
                        d = threadCalendar.AddDays(d, 1); 
                        absoluteDay++;
                    } 
                }
                writer.Write(ROWENDTAG);
            }
        } 

 
        ///  
        /// 
        private void RenderTitle(HtmlTextWriter writer, DateTime visibleDate, CalendarSelectionMode selectionMode, bool buttonsActive, bool useAccessibleHeader) { 
            writer.Write(ROWBEGINTAG);

            TableCell titleCell = new TableCell();
            Table titleTable = new Table(); 

            // default title table/cell styles 
            titleCell.ColumnSpan = HasWeekSelectors(selectionMode) ? 8 : 7; 
            titleCell.BackColor = Color.Silver;
            titleTable.GridLines = GridLines.None; 
            titleTable.Width = Unit.Percentage(100);
            titleTable.CellSpacing = 0;

            TableItemStyle titleStyle = TitleStyle; 
            ApplyTitleStyle(titleCell, titleTable, titleStyle);
 
            titleCell.RenderBeginTag(writer); 
            titleTable.RenderBeginTag(writer);
            writer.Write(ROWBEGINTAG); 

            NextPrevFormat nextPrevFormat = NextPrevFormat;

            TableItemStyle nextPrevStyle = new TableItemStyle(); 
            nextPrevStyle.Width = Unit.Percentage(15);
            nextPrevStyle.CopyFrom(NextPrevStyle); 
            if (ShowNextPrevMonth) { 
                if (IsMinSupportedYearMonth(visibleDate)) {
                    writer.RenderBeginTag(HtmlTextWriterTag.Td); 
                    writer.RenderEndTag();
                }
                else {
                    string prevMonthText; 
                    if (nextPrevFormat == NextPrevFormat.ShortMonth || nextPrevFormat == NextPrevFormat.FullMonth) {
                        int monthNo = threadCalendar.GetMonth(threadCalendar.AddMonths(visibleDate, - 1)); 
                        prevMonthText = GetMonthName(monthNo, (nextPrevFormat == NextPrevFormat.FullMonth)); 
                    }
                    else { 
                        prevMonthText = PrevMonthText;
                    }
                    // Month navigation. The command starts with a "V" and the remainder is day difference from the
                    // base date. 
                    DateTime prevMonthDate;
 
                    // VSWhidbey 366243: Some calendar's min supported date is 
                    // not the first day of the month (e.g. JapaneseCalendar.
                    // So if we are setting the second supported month, the prev 
                    // month link should always point to the first supported
                    // date instead of the first day of the previous month.
                    DateTime secondSupportedMonth = threadCalendar.AddMonths(minSupportedDate, 1);
                    if (IsTheSameYearMonth(secondSupportedMonth, visibleDate)) { 
                        prevMonthDate = minSupportedDate;
                    } 
                    else { 
                        prevMonthDate = threadCalendar.AddMonths(visibleDate, -1);
                    } 

                    string prevMonthKey = NAVIGATE_MONTH_COMMAND + (prevMonthDate.Subtract(baseDate)).Days.ToString(CultureInfo.InvariantCulture);

                    string previousMonthTitle = null; 
                    if (useAccessibleHeader) {
                        previousMonthTitle = SR.GetString(SR.Calendar_PreviousMonthTitle); 
                    } 
                    RenderCalendarCell(writer, nextPrevStyle, prevMonthText, previousMonthTitle, buttonsActive, prevMonthKey);
                } 
            }


            TableItemStyle cellMainStyle = new TableItemStyle(); 

            if (titleStyle.HorizontalAlign != HorizontalAlign.NotSet) { 
                cellMainStyle.HorizontalAlign = titleStyle.HorizontalAlign; 
            }
            else { 
                cellMainStyle.HorizontalAlign = HorizontalAlign.Center;
            }
            cellMainStyle.Wrap = titleStyle.Wrap;
            cellMainStyle.Width = Unit.Percentage(70); 

            string titleText; 
 
            switch (TitleFormat) {
                case TitleFormat.Month: 
                    titleText = visibleDate.ToString("MMMM", CultureInfo.CurrentCulture);
                    break;
                case TitleFormat.MonthYear:
                    string titlePattern = DateTimeFormatInfo.CurrentInfo.YearMonthPattern; 
                    // Some cultures have a comma in their YearMonthPattern, which does not look
                    // right in a calendar. Use a fixed pattern for those. 
                    if (titlePattern.IndexOf(',') >= 0) { 
                        titlePattern = "MMMM yyyy";
                    } 
                    titleText = visibleDate.ToString(titlePattern, CultureInfo.CurrentCulture);
                    break;
                default:
                    Debug.Assert(false, "Unknown TitleFormat value!"); 
                    goto case TitleFormat.MonthYear;
            } 
            RenderCalendarCell(writer, cellMainStyle, titleText, null, false, null); 

            if (ShowNextPrevMonth) { 
                if (IsMaxSupportedYearMonth(visibleDate)) {
                    writer.RenderBeginTag(HtmlTextWriterTag.Td);
                    writer.RenderEndTag();
                } 
                else {
                    // Style for this one is identical bar 
                    nextPrevStyle.HorizontalAlign = HorizontalAlign.Right; 
                    string nextMonthText;
                    if (nextPrevFormat == NextPrevFormat.ShortMonth || nextPrevFormat == NextPrevFormat.FullMonth) { 
                        int monthNo = threadCalendar.GetMonth(threadCalendar.AddMonths(visibleDate, 1));
                        nextMonthText = GetMonthName(monthNo, (nextPrevFormat == NextPrevFormat.FullMonth));
                    }
                    else { 
                        nextMonthText = NextMonthText;
                    } 
                    // Month navigation. The command starts with a "V" and the remainder is day difference from the 
                    // base date.
                    DateTime nextMonthDate = threadCalendar.AddMonths(visibleDate, 1); 
                    string nextMonthKey = NAVIGATE_MONTH_COMMAND + (nextMonthDate.Subtract(baseDate)).Days.ToString(CultureInfo.InvariantCulture);

                    string nextMonthTitle = null;
                    if (useAccessibleHeader) { 
                        nextMonthTitle = SR.GetString(SR.Calendar_NextMonthTitle);
                    } 
                    RenderCalendarCell(writer, nextPrevStyle, nextMonthText, nextMonthTitle, buttonsActive, nextMonthKey); 
                }
            } 
            writer.Write(ROWENDTAG);
            titleTable.RenderEndTag(writer);
            titleCell.RenderEndTag(writer);
            writer.Write(ROWENDTAG); 

        } 
 

        ///  
        /// 
        /// Stores the state of the System.Web.UI.WebControls.Calender.
        /// 
        protected override object SaveViewState() { 
            if (SelectedDates.Count > 0)
                ViewState["SD"] = dateList; 
 
            object[] myState = new object[10];
 
            myState[0] = base.SaveViewState();
            myState[1] = (titleStyle != null) ? ((IStateManager)titleStyle).SaveViewState() : null;
            myState[2] = (nextPrevStyle != null) ? ((IStateManager)nextPrevStyle).SaveViewState() : null;
            myState[3] = (dayStyle != null) ? ((IStateManager)dayStyle).SaveViewState() : null; 
            myState[4] = (dayHeaderStyle != null) ? ((IStateManager)dayHeaderStyle).SaveViewState() : null;
            myState[5] = (todayDayStyle != null) ? ((IStateManager)todayDayStyle).SaveViewState() : null; 
            myState[6] = (weekendDayStyle != null) ? ((IStateManager)weekendDayStyle).SaveViewState() : null; 
            myState[7] = (otherMonthDayStyle != null) ? ((IStateManager)otherMonthDayStyle).SaveViewState() : null;
            myState[8] = (selectedDayStyle != null) ? ((IStateManager)selectedDayStyle).SaveViewState() : null; 
            myState[9] = (selectorStyle != null) ? ((IStateManager)selectorStyle).SaveViewState() : null;

            for (int i = 0; i 
        /// 
        private void SetDayStyles(TableItemStyle style, int styleMask, Unit defaultWidth) {

            // default day styles 
            style.Width = defaultWidth;
            style.HorizontalAlign = HorizontalAlign.Center; 
 
            if ((styleMask & STYLEMASK_DAY) != 0) {
                style.CopyFrom(DayStyle); 
            }
            if ((styleMask & STYLEMASK_WEEKEND) != 0) {
                style.CopyFrom(WeekendDayStyle);
            } 
            if ((styleMask & STYLEMASK_OTHERMONTH) != 0) {
                style.CopyFrom(OtherMonthDayStyle); 
            } 
            if ((styleMask & STYLEMASK_TODAY) != 0) {
                style.CopyFrom(TodayDayStyle); 
            }

            if ((styleMask & STYLEMASK_SELECTED) != 0) {
                // default selected day style 
                style.ForeColor = Color.White;
                style.BackColor = Color.Silver; 
 
                style.CopyFrom(SelectedDayStyle);
            } 
        }
    }
}
 


// File provided for Reference Use Only by Microsoft Corporation (c) 2007.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK