public BroadcastManager(SecondRounding rounding = SecondRounding.Round)
 {
     Rounding    = rounding;
     _stack      = new PlayerDictionary <SortedDictionary <int, BroadcastMessage> >();
     _ticker     = new Ticker(4);
     _dirtySlots = new HashSet <int>();
 }
        /// <summary>
        /// Generates a random <see cref="DateTime"></see> object based on the specified date range
        /// </summary>
        /// <param name="start">DateTime range start</param>
        /// <param name="end">DateTime range end</param>
        /// <param name="minuteRounding">Rounds time to the specified minute rounding</param>
        /// <param name="secondRounding">Rounds time to the specified second rounding</param>
        /// <param name="workingHours">Limits the time range between 8am and 6pm - Monday to Friday</param>
        /// <returns></returns>
        public static DateTime WithinRange(DateTime start, DateTime end, MinuteRounding minuteRounding = MinuteRounding.None, SecondRounding secondRounding = SecondRounding.None, bool workingHours = false)
        {
            // Assertions

            if (start > end)
                throw new ArgumentException("End date must be greater than Start");

            if (minuteRounding == MinuteRounding.HalfHour && (end - start) < TimeSpan.FromMinutes(30))
                throw new ArgumentException("Range must be greater than 30 minutes");

            if (minuteRounding == MinuteRounding.QuarterHour && (end - start) < TimeSpan.FromMinutes(15))
                throw new ArgumentException("Range must be greater than 15 minutes");

            // If the range falls outside of working hours, then throw an error
            if (workingHours && end - start < TimeSpan.FromDays(1) && start.Intersects(start.Date.Add(WorkingDayStart), start.Date.Add(WorkingDayEnd), end - start))
                throw new ArgumentException("Range falls outside of working hours");

            // Create random date
            DateTime date;
            int counter = 0;
            do
            {
                date = new DateTime(LongRandom(start.Ticks, end.Ticks));

                if (minuteRounding != MinuteRounding.None)
                    date = date.RoundMinutes(minuteRounding);

                if (secondRounding != SecondRounding.None)
                    date = date.RoundSeconds(secondRounding);

                if (workingHours)
                    date = LimitToWorkingHours(date);

                counter++;
                if (counter > 100)
                    throw new Exception("Could not create a DateTime within the specified range. Try using a larger range.");

            } while (date < start || date > end);

            return date;
        }
        public void SendMessage(Player player, SecondRounding rounding = SecondRounding.Round)
        {
            uint time = 0;

            switch (rounding)
            {
            case SecondRounding.Round:
                time = (uint)Math.Round(Duration.TotalSeconds);
                break;

            case SecondRounding.Floor:
                time = (uint)Math.Floor(Duration.TotalSeconds);
                break;

            case SecondRounding.Ceil:
                time = (uint)Math.Ceiling(Duration.TotalSeconds);
                break;
            }

            player.PersonalBroadcast(time, Message, Monospaced);
        }
 /// <summary>
 /// Rounds the second component to the nearest specified time. Defaults to 1 second
 /// </summary>
 /// <param name="source"></param>
 /// <param name="rounding"></param>
 /// <returns></returns>
 public static DateTime RoundSeconds(this DateTime source, SecondRounding rounding = SecondRounding.Second)
 {
     switch (rounding)
     {
         case SecondRounding.Second:
             if (source.Second >= 30)
                 return source.AddMinutes(1).TrimSeconds();
             return source.AddSeconds(-source.Second).AddMilliseconds(-source.Millisecond);
         case SecondRounding.HalfSecond:
             if (source.Second < 15)
                 return source.TrimSeconds();
             if (source.Second >= 15 && source.Minute < 45)
                 return source.TrimSeconds().AddSeconds(30);
             return source.AddMinutes(1).TrimSeconds();
         default:
             throw new ArgumentOutOfRangeException("rounding");
     }
 }