/// <summary>
        /// The get available dates.
        /// </summary>
        /// <param name="availableDates">
        /// The available dates.
        /// </param>
        /// <param name="recurringItem">
        /// The recurring item.
        /// </param>
        /// <param name="startDayOfWeek">
        /// The start day of week.
        /// </param>
        /// <param name="dayOfWeek">
        /// The target day of week.
        /// </param>
        /// <returns>
        /// The list of available dates with week number.
        /// </returns>
        private Dictionary <DateTime, int> GetAvailableDates(
            Dictionary <DateTime, int> availableDates,
            RecurrenceWeeklyModel recurringItem,
            DayOfWeek startDayOfWeek,
            DayOfWeek dayOfWeek)
        {
            if (startDayOfWeek != dayOfWeek)
            {
                var intStartDayOfWeek = startDayOfWeek == DayOfWeek.Sunday ? 7 : (int)startDayOfWeek;
                var intDayOfWeek      = dayOfWeek == DayOfWeek.Sunday ? 7 : (int)dayOfWeek;

                var date = intDayOfWeek - intStartDayOfWeek > 0
                               ? recurringItem.StartDate.Date.AddDays(intDayOfWeek - intStartDayOfWeek)
                               : recurringItem.StartDate.Date.AddDays(intDayOfWeek - intStartDayOfWeek + 7);

                availableDates.Add(date, intDayOfWeek - intStartDayOfWeek > 0 ? 1 : 2);
            }
            else
            {
                if (!availableDates.ContainsKey(recurringItem.StartDate))
                {
                    availableDates.Add(recurringItem.StartDate, 1);
                }
            }

            return(availableDates);
        }
        /// <summary>
        /// IF THE USER SELECTED WEEK, AT LEAST ONE DAY OF WEEK IS SELECTED.
        /// </summary>
        /// <param name="recurringItem">
        /// The recurring item.
        /// </param>
        /// <returns>
        /// The <see cref="DateTime"/>.
        /// </returns>
        public Dictionary <DateTime, int> AdjustRecurringDate(RecurrenceWeeklyModel recurringItem)
        {
            var availableDates = new Dictionary <DateTime, int>();

            var startDayOfWeek = recurringItem.StartDate.DayOfWeek;

            // Monday
            if (recurringItem.Monday)
            {
                availableDates = this.GetAvailableDates(availableDates, recurringItem, startDayOfWeek, DayOfWeek.Monday);
            }

            // Tuesday
            if (recurringItem.Tuesday)
            {
                availableDates = this.GetAvailableDates(availableDates, recurringItem, startDayOfWeek, DayOfWeek.Tuesday);
            }

            // Wednesday
            if (recurringItem.Wednesday)
            {
                availableDates = this.GetAvailableDates(availableDates, recurringItem, startDayOfWeek, DayOfWeek.Wednesday);
            }

            // Thursday
            if (recurringItem.Thursday)
            {
                availableDates = this.GetAvailableDates(availableDates, recurringItem, startDayOfWeek, DayOfWeek.Thursday);
            }

            // Friday
            if (recurringItem.Friday)
            {
                availableDates = this.GetAvailableDates(availableDates, recurringItem, startDayOfWeek, DayOfWeek.Friday);
            }

            // Saturday
            if (recurringItem.Saturday)
            {
                availableDates = this.GetAvailableDates(availableDates, recurringItem, startDayOfWeek, DayOfWeek.Saturday);
            }

            // Sunday
            if (recurringItem.Sunday)
            {
                availableDates = this.GetAvailableDates(availableDates, recurringItem, startDayOfWeek, DayOfWeek.Sunday);
            }

            return(availableDates);
        }
        public bool TestCheckAvailabilityForWeeklyEvents(string currentDate, int frequency)
        {
            var service = new RecurrenceService();

            var model = new RecurrenceWeeklyModel
            {
                StartDate  = DateTime.Parse("1/11/2016"),
                EndDate    = DateTime.Parse("31/1/2017"),
                NumOfWeeks = frequency,
                Monday     = true,
                Tuesday    = false,
                Wednesday  = false,
                Thursday   = true,
                Friday     = true,
                Saturday   = false,
                Sunday     = true
            };

            var result = service.CheckAvailability(DateTime.Parse(currentDate), model);

            return(result);
        }
        public string TestAdjustRecurringDate(string startDate)
        {
            var service = new RecurrenceService();

            var model = new RecurrenceWeeklyModel
            {
                StartDate  = DateTime.Parse(startDate),
                EndDate    = DateTime.Parse("31/1/2017"),
                NumOfWeeks = 1,
                Monday     = true,
                Tuesday    = false,
                Wednesday  = false,
                Thursday   = true,
                Friday     = true,
                Saturday   = false,
                Sunday     = true
            };

            var availableDates = service.AdjustRecurringDate(model);

            var result = availableDates.Keys.Min(x => x.Date);

            return(result.Date.ToString("d/MM/yyyy"));
        }
        /// <summary>
        /// The check availability for weekly events.
        /// </summary>
        /// <param name="currentDate">
        /// The date.
        /// </param>
        /// <param name="recurringItem">
        /// The recurring item.
        /// </param>
        /// <returns>
        /// Check whether or not the event is available on the given date.
        /// </returns>
        public bool CheckAvailability(DateTime currentDate, RecurrenceWeeklyModel recurringItem)
        {
            int result1 = DateTime.Compare(currentDate, recurringItem.StartDate);
            int result2 = DateTime.Compare(currentDate, recurringItem.EndDate);

            // check whether or not current date is in recurring period.
            if (result1 >= 0 && result2 <= 0)
            {
                // frequency can't be empty/0
                if (recurringItem.NumOfWeeks == 0)
                {
                    return(false);
                }

                var adjustedStarDates = this.AdjustRecurringDate(recurringItem);

                DateTime adjustedStarDate = DateTime.MinValue;
                var      initialWeek      = 1;


                foreach (var starDate in adjustedStarDates.Where(starDate => starDate.Key.DayOfWeek == currentDate.DayOfWeek))
                {
                    adjustedStarDate = starDate.Key;
                    initialWeek      = starDate.Value;
                    break;
                }

                if (adjustedStarDate == DateTime.MinValue)
                {
                    return(false);
                }

                var daysDiff = (currentDate - adjustedStarDate).Days;

                if (initialWeek == 2)
                {
                    daysDiff = daysDiff + 7;
                }

                var weekNumber = daysDiff / 7;

                bool isRecurrentDay = daysDiff % (7 * recurringItem.NumOfWeeks) == 0 && weekNumber % recurringItem.NumOfWeeks == 0;

                switch (currentDate.DayOfWeek)
                {
                case DayOfWeek.Monday:
                    return(recurringItem.Monday && isRecurrentDay);

                case DayOfWeek.Tuesday:
                    return(recurringItem.Tuesday && isRecurrentDay);

                case DayOfWeek.Wednesday:
                    return(recurringItem.Wednesday && isRecurrentDay);

                case DayOfWeek.Thursday:
                    return(recurringItem.Thursday && isRecurrentDay);

                case DayOfWeek.Friday:
                    return(recurringItem.Friday && isRecurrentDay);

                case DayOfWeek.Saturday:
                    return(recurringItem.Saturday && isRecurrentDay);

                case DayOfWeek.Sunday:
                    return(recurringItem.Sunday && isRecurrentDay);
                }
            }
            else
            {
                return(false);
            }

            return(true);
        }