/// <summary>
        /// Get the event that should be triggered next in the queue
        /// based on the curent DateTime or startDate
        /// </summary>
        /// <param name="startDate">Date on which the recurrence begins</param>
        /// <returns></returns>
        private WeeklySchedule GetNextEventInQueue(DateTime?startDate)
        {
            if (_scheduleQueue.Count == 1)
            {
                return(_scheduleQueue.Peek());
            }

            DateTime  baseDate = startDate ?? DateTime.Now;
            DayOfWeek today    = baseDate.DayOfWeek;
            TimeSpan  now      = new TimeSpan(0, baseDate.Hour, baseDate.Minute, baseDate.Second, baseDate.Millisecond);

            int i = 0;

            while (i < _scheduleQueue.Count)
            {
                WeeklySchedule schedule = _scheduleQueue.Peek();
                if (schedule.DayOfWeek < today || (schedule.DayOfWeek == today && schedule.TimeOfDay < now))
                {
                    //Push first element at end
                    _scheduleQueue.Enqueue(_scheduleQueue.Dequeue());
                    i++;
                }
                else
                {
                    return(schedule);
                }
            }

            return(_scheduleQueue.Peek());
        }
        /// <summary>
        /// Return the date of the next occurence to schedule
        /// </summary>
        /// <param name="startDate">Date on which the recurrence begins</param>
        /// <returns></returns>
        private DateTime GetNextScheduleDate(DateTime?startDate)
        {
            if (startDate < DateTime.Now)
            {
                startDate = DateTime.Now;
            }

            WeeklySchedule schedule     = GetNextEventInQueue(startDate);
            DateTime       scheduleDate = startDate?.Date ?? DateTime.Now;

            while (scheduleDate.DayOfWeek != schedule.DayOfWeek)
            {
                scheduleDate = scheduleDate.AddDays(1);
            }

            TimeSpan time = schedule.TimeOfDay;

            scheduleDate = new DateTime(scheduleDate.Year, scheduleDate.Month, scheduleDate.Day, time.Hours, time.Minutes, time.Seconds);

            if (scheduleDate < DateTime.Now)
            {
                scheduleDate = scheduleDate.AddDays(7);
            }

            return(scheduleDate);
        }
        /// <summary>
        /// Initializes a new instance of WeeklyEvent for a specific day / time, starting at a given date,
        /// providing an action delegate to invoke on trigger.
        /// The event will trigger every week at the provided day and time.
        /// </summary>
        /// <param name="dayOfWeek">Trigger day</param>
        /// <param name="timeOfDay">Trigger time</param>
        /// <param name="startDate">Date on which the recurrence begins</param>
        /// <param name="action">The action to invoke</param>
        public WeeklyEvent(DayOfWeek dayOfWeek, TimeSpan timeOfDay, DateTime startDate, Action action)
        {
            var schedule = new WeeklySchedule(dayOfWeek, timeOfDay);

            _scheduleQueue = new Queue <WeeklySchedule>();
            _scheduleQueue.Enqueue(schedule);

            ScheduledTime = GetNextScheduleDate(startDate);

            if (action != null)
            {
                _action = action;
            }
        }