/// <summary>
 /// Returns a GlobalCalendarDayButton Style based on whether the day is
 /// a weekday or a weekend.
 /// </summary>
 /// <param name="day">The day to select a Style for.</param>
 /// <param name="container">The GlobalCalendarDayButton.</param>
 /// <returns>A Style for the GlobalCalendarDayButton.</returns>
 public override Style SelectStyle(DateTime day, GlobalCalendarDayButton container)
 {
     DayOfWeek d = day.DayOfWeek;
     return (d == DayOfWeek.Saturday || d == DayOfWeek.Sunday) ?
         WeekendStyle :
         WeekdayStyle;
 }
        /// <summary>
        /// Returns a GlobalCalendarDayButton Style based on whether the day is
        /// a holiday.
        /// </summary>
        /// <param name="day">The day to select a Style for.</param>
        /// <param name="container">The GlobalCalendarDayButton.</param>
        /// <returns>A Style for the GlobalCalendarDayButton.</returns>
        public override Style SelectStyle(DateTime day, GlobalCalendarDayButton container)
        {
            Holiday holiday = Holidays.Where(h => h.FallsOn(day)).FirstOrDefault();

            // Use the Holiday.Title as the Tooltip
            string title = holiday != null ? holiday.Title : null;
            ToolTipService.SetToolTip(container, title);

            return (holiday != null) ?
                HolidayStyle :
                NormalStyle;
        }
        /// <summary>
        /// Apply a Style to a GlobalCalendarDayButton.
        /// </summary>
        /// <param name="button">The button.</param>
        internal void ApplyDayButtonStyle(GlobalCalendarDayButton button)
        {
            Debug.Assert(button != null, "button should not be null!");

            DateTime? date = button.GetDateNullable();
            CalendarDayButtonStyleSelector selector = CalendarDayButtonStyleSelector;
            Style style = CalendarDayButtonStyle;

            button.Style = (selector != null && date != null) ?
                selector.SelectStyle(date.Value, button) ?? style :
                style;
        }
 /// <summary>
 /// When overridden in a derived class, returns a
 /// GlobalCalendarDayButton Style based on custom logic.
 /// </summary>
 /// <param name="day">The day to select a Style for.</param>
 /// <param name="container">The GlobalCalendarDayButton.</param>
 /// <returns>A Style for the GlobalCalendarDayButton.</returns>
 public abstract Style SelectStyle(DateTime day, GlobalCalendarDayButton container);
 /// <summary>
 /// Initializes a new instance of the
 /// <see cref="T:System.Windows.Automation.Peers.GlobalCalendarDayButtonAutomationPeer" />
 /// class.
 /// </summary>
 /// <param name="owner">
 /// The
 /// <see cref="T:System.Windows.Controls.Primitives.GlobalCalendarDayButton" />
 /// instance that is associated with this
 /// <see cref="T:System.Windows.Automation.Peers.GlobalCalendarDayButtonAutomationPeer" />.
 /// </param>
 public GlobalCalendarDayButtonAutomationPeer(GlobalCalendarDayButton owner)
     : base(owner)
 {
 }
        /// <summary>
        /// Inherited code: Requires comment.
        /// </summary>
        /// <param name="childButton">Inherited code: Requires comment 1.</param>
        /// <param name="dateToAdd">Inherited code: Requires comment 2.</param>
        private void SetButtonState(GlobalCalendarDayButton childButton, DateTime dateToAdd)
        {
            if (Owner == null)
            {
                return;
            }

            CalendarInfo info = Info;
            childButton.Opacity = 1;

            // If the day is outside the DisplayDateStart/End boundary, do
            // not show it
            if (info.CompareDays(dateToAdd, Owner.DisplayDateRangeStart) < 0 ||
                info.CompareDays(dateToAdd, Owner.DisplayDateRangeEnd) > 0)
            {
                childButton.IsEnabled = false;
                childButton.Opacity = 0;
            }
            else
            {
                // SET IF THE DAY IS SELECTABLE OR NOT
                childButton.IsBlackout = Owner.BlackoutDates.Contains(dateToAdd);
                childButton.IsEnabled = true;

                // SET IF THE DAY IS INACTIVE OR NOT: set if the day is a
                // trailing day or not
                childButton.IsInactive = info.GetMonthDifference(dateToAdd, Owner.DisplayDateInternal) != 0;

                // SET IF THE DAY IS TODAY OR NOT
                childButton.IsToday = Owner.IsTodayHighlighted && Info.Compare(dateToAdd, DateTime.Today) == 0;

                // SET IF THE DAY IS SELECTED OR NOT
                // (Since we should be comparing the Date values not DateTime
                // values, we can't use Owner.SelectedDates.Contains(dateToAdd)
                // directly)
                bool selected = false;
                foreach (DateTime item in Owner.SelectedDates)
                {
                    if (info.CompareDays(dateToAdd, item) == 0)
                    {
                        selected = true;
                        break;
                    }
                }
                childButton.IsSelected = selected;

                // SET THE FOCUS ELEMENT
                if (Owner.LastSelectedDate != null)
                {
                    if (info.CompareDays(Owner.LastSelectedDate.Value, dateToAdd) == 0)
                    {
                        if (Owner.FocusButton != null)
                        {
                            Owner.FocusButton.IsCurrent = false;
                        }
                        Owner.FocusButton = childButton;
                        if (Owner.HasFocusInternal)
                        {
                            Owner.FocusButton.IsCurrent = true;
                        }
                    }
                    else
                    {
                        childButton.IsCurrent = false;
                    }
                }
            }
        }
        /// <summary>
        /// Inherited code: Requires comment.
        /// </summary>
        private void PopulateGrids()
        {
            if (MonthView != null)
            {
                for (int i = 0; i < GlobalCalendar.RowsPerMonth; i++)
                {
                    if (_dayTitleTemplate != null)
                    {
                        FrameworkElement cell = (FrameworkElement)_dayTitleTemplate.LoadContent();
                        cell.SetValue(Grid.RowProperty, 0);
                        cell.SetValue(Grid.ColumnProperty, i);
                        MonthView.Children.Add(cell);
                    }
                }

                for (int i = 1; i < GlobalCalendar.RowsPerMonth; i++)
                {
                    for (int j = 0; j < GlobalCalendar.ColumnsPerMonth; j++)
                    {
                        GlobalCalendarDayButton cell = new GlobalCalendarDayButton();

                        if (Owner != null)
                        {
                            cell.Owner = Owner;
                            Owner.ApplyDayButtonStyle(cell);
                        }
                        cell.SetValue(Grid.RowProperty, i);
                        cell.SetValue(Grid.ColumnProperty, j);
                        cell.CalendarDayButtonMouseDown += Cell_MouseLeftButtonDown;
                        cell.CalendarDayButtonMouseUp += Cell_MouseLeftButtonUp;
                        cell.MouseEnter += Cell_MouseEnter;
                        cell.MouseLeave += Cell_MouseLeave;
                        cell.Click += Cell_Click;
                        MonthView.Children.Add(cell);
                    }
                }
            }

            if (YearView != null)
            {
                GlobalCalendarButton month;
                int count = 0;
                for (int i = 0; i < GlobalCalendar.RowsPerYear; i++)
                {
                    for (int j = 0; j < GlobalCalendar.ColumnsPerYear; j++)
                    {
                        month = new GlobalCalendarButton();

                        if (Owner != null)
                        {
                            month.Owner = Owner;
                            if (Owner.CalendarButtonStyle != null)
                            {
                                month.Style = Owner.CalendarButtonStyle;
                            }
                        }
                        month.SetValue(Grid.RowProperty, i);
                        month.SetValue(Grid.ColumnProperty, j);
                        month.CalendarButtonMouseDown += Month_CalendarButtonMouseDown;
                        month.CalendarButtonMouseUp += Month_CalendarButtonMouseUp;
                        month.MouseEnter += Month_MouseEnter;
                        month.MouseLeave += Month_MouseLeave;
                        YearView.Children.Add(month);
                        count++;
                    }
                }
            }
        }
        /// <summary>
        /// Inherited code: Requires comment.
        /// </summary>
        /// <param name="b">Inherited code: Requires comment 1.</param>
        private void AddSelection(GlobalCalendarDayButton b)
        {
            if (Owner != null)
            {
                DateTime date = b.GetDate();
                Owner.HoverEndIndex = b.Index;
                Owner.HoverEnd = date;

                if (Owner.HoverEnd != null && Owner.HoverStart != null)
                {
                    // this is selection with Mouse, we do not guarantee the
                    // range does not include BlackOutDates.  AddRange method
                    // will throw away the BlackOutDates based on the
                    // SelectionMode
                    Owner.IsMouseSelection = true;
                    Owner.SelectedDates.AddRange(Owner.HoverStart.Value, Owner.HoverEnd.Value);
                    Owner.OnDayClick(date);
                }
            }
        }
 /// <summary>
 /// Inherited code: Requires comment.
 /// </summary>
 /// <param name="sender">Inherited code: Requires comment 1.</param>
 /// <param name="e">Inherited code: Requires comment 2.</param>
 internal void Cell_MouseLeave(object sender, MouseEventArgs e)
 {
     if (_isMouseLeftButtonDown)
     {
         GlobalCalendarDayButton b = sender as GlobalCalendarDayButton;
         // The button is in Pressed state. Change the state to normal.
         b.ReleaseMouseCapture();
         // null check is added for unit tests
         if (_downEventArg != null)
         {
             b.SendMouseLeftButtonUp(_downEventArg);
         }
         _lastCalendarDayButton = b;
     }
 }