using System; using System.Collections.Generic; using StrixMusic.Helpers.TimeSpanRules; namespace StrixMusic.Helpers { /// /// A class for loading localized quips, with time based context. /// public class QuipLoader { /// /// A set of quips for a languauge and time. /// private struct QuipGroup { public QuipGroup( string name, int count, ITimeSpanRule? rule, int weight = 1) { Name = name; Count = count; Rule = rule; Weight = weight; Generic = Name == "Generic"; } /// /// Gets whether or not the quips apply at this time. /// /// The time to for. /// Whether or not now is in the time range. public bool Applies(DateTime now) { if (Rule == null) return true; return Rule.IsNow(now); } public string Name { get; } public int Count { get; } public ITimeSpanRule? Rule { get; } public int Weight { get; } public bool Generic { get; } } private static Dictionary holidayQuips = new Dictionary() { { "GroundhogDay", new QuipGroup("GroundhogDay", count:2, rule:new AnnualRangeRule(new DateTime(1, 2, 2), new DateTime(1, 2, 3)), weight:10) }, { "Halloween", new QuipGroup("Halloween", count:4, rule:new AnnualRangeRule(new DateTime(1, 10, 31), new DateTime(1, 11, 1)), weight:10) }, { "DrWhoAniversary", new QuipGroup("DrWhoAniversary", count:13, rule:new AnnualRangeRule(new DateTime(1, 7, 23), new DateTime(1, 7, 24)), weight:20) }, }; private static Dictionary _languageSpecialDayMap = new Dictionary { // en { "en", new QuipGroup[] { // Generic English new QuipGroup("Generic", count:13, rule:null), // Holidays new QuipGroup("Christmas", count:4, rule:new AnnualRangeRule(new DateTime(1, 12, 24), new DateTime(1, 12, 26)), weight:10), new QuipGroup("NewYears", count:1, rule:new AnnualRangeRule(new DateTime(1, 12, 31), new DateTime(1, 1, 2)), weight:10), new QuipGroup("NewYearsEve", count:1, rule:new AnnualRangeRule(new DateTime(1, 12, 31), new DateTime(1, 1, 1))), new QuipGroup("May4th", count:4, rule:new AnnualRangeRule(new DateTime(1, 5, 4), new DateTime(1, 5, 5)), weight:10), new QuipGroup("StParticks", count:3, rule:new AnnualRangeRule(new DateTime(1, 3, 17), new DateTime(1, 3, 18, 5, 0, 0)), weight:10), new QuipGroup("April1st", count:3, rule:new AnnualRangeRule(new DateTime(1, 4, 1), new DateTime(1, 4, 2)), weight:10), holidayQuips["Halloween"], // Time of day new QuipGroup("Dawn", count:2, rule:new DailyRangeRule(TimeSpan.FromHours(4), TimeSpan.FromHours(7)), weight:2), new QuipGroup("Morning", count:2, rule:new DailyRangeRule(TimeSpan.FromHours(7), TimeSpan.FromHours(12)), weight:2), new QuipGroup("Afternoon", count:2, rule:new DailyRangeRule(TimeSpan.FromHours(12), TimeSpan.FromHours(15)), weight:2), new QuipGroup("Evening", count:1, rule:new DailyRangeRule(TimeSpan.FromHours(15), TimeSpan.FromHours(21)), weight:2), new QuipGroup("Night", count:1, rule:new DailyRangeRule(TimeSpan.FromHours(21), TimeSpan.FromHours(0)), weight:2), // Seasonal // TODO: Overrule Seasonal quips in Southern hemisphere new QuipGroup("Autumn", count:3, rule:new AnnualRangeRule(new DateTime(1, 9, 22), new DateTime(1, 12, 21)), weight:2), // TODO: Compute seasonal times new QuipGroup("Winter", count:3, rule:new AnnualRangeRule(new DateTime(1, 12, 21), new DateTime(1, 3, 20)), weight:2), // TODO: Compute seasonal times new QuipGroup("Sprint", count:1, rule:new AnnualRangeRule(new DateTime(1, 3, 20), new DateTime(1, 6, 21)), weight:2), // TODO: Compute seasonal times new QuipGroup("Summer", count:1, rule:new AnnualRangeRule(new DateTime(1, 6, 21), new DateTime(1, 9, 22)), weight:2), // TODO: Compute seasonal times } }, // en-us { "en-us", new QuipGroup[] { new QuipGroup("US-StParticks", count:1, rule:new AnnualRangeRule(new DateTime(1, 3, 17), new DateTime(1, 3, 18, 5, 0, 0)), weight:2), new QuipGroup("July4th", count:2, rule:new AnnualRangeRule(new DateTime(1, 7, 4), new DateTime(1, 7, 5)), weight:10), new QuipGroup("VoteRegister", count:1, rule:new AnnualRangeRule(new DateTime(1, 10, 7), new DateTime(1, 11, 1)), weight:2), holidayQuips["DrWhoAniversary"], holidayQuips["GroundhogDay"], } }, // en-gb { "en-gb", new QuipGroup[] { new QuipGroup("November5th", count:2, rule:new AnnualRangeRule(new DateTime(1, 11, 5), new DateTime(1,11, 6)), weight:10), holidayQuips["DrWhoAniversary"], } }, // en-ca { "en-ca", new QuipGroup[] { holidayQuips["GroundhogDay"], } }, // he { "he", new QuipGroup[] { new QuipGroup("Generic", count:4, rule:null), new QuipGroup("Saturday", count:1, rule:new WeeklyRule(DayOfWeek.Saturday)), new QuipGroup("Sunday", count:1, rule:new WeeklyRule(DayOfWeek.Sunday)), new QuipGroup("Morning", count:1, rule:new DailyRangeRule(TimeSpan.FromHours(7), TimeSpan.FromHours(12)), weight:2), new QuipGroup("Afternoon", count:1, rule:new DailyRangeRule(TimeSpan.FromHours(12), TimeSpan.FromHours(15)), weight:2), new QuipGroup("Evening", count:1, rule:new DailyRangeRule(TimeSpan.FromHours(15), TimeSpan.FromHours(21)), weight:2), new QuipGroup("Night", count:1, rule:new DailyRangeRule(TimeSpan.FromHours(21), TimeSpan.FromHours(0)), weight:2), } }, }; private int _sumWeight; private List _activeQuipGroups = new List(); /// /// Initializes a new instance of the class. /// /// The language code for quips to get. public QuipLoader(string languageCode) { QuipGroup[] groups = _languageSpecialDayMap[languageCode.Substring(0, 2)]; QuipGroup[] regionalGroup = Array.Empty(); if (_languageSpecialDayMap.ContainsKey(languageCode)) { regionalGroup = _languageSpecialDayMap[languageCode]; } DateTime now = DateTime.Now; LoadGroupList(groups, now); if (regionalGroup.Length != 0) LoadGroupList(regionalGroup, now); } private void LoadGroupList(QuipGroup[] groups, DateTime now) { foreach (var group in groups) { if (group.Applies(now)) { _sumWeight += group.Weight * group.Count; _activeQuipGroups.Add(group); } } } /// /// Gets the Group and index in the group of a quip to load. /// /// (Group, index) of the group to load. public (string, int) GetGroupIndexQuip() { Random rand = new Random(); int i = rand.Next(_sumWeight); foreach (var group in _activeQuipGroups) { if (i <= (group.Weight * group.Count) - 1) { i /= group.Weight; return (group.Name, i); } else { i -= group.Weight * group.Count; } } return ("Generic", 0); } } }