using Nonemm.Contests; using Nonemm.Core; using Nonemm.Core.Calls; namespace Nonemm.Session; /// Moving exchange values between the entry boxes, the call history file and a /// contact. public static class ExchangeSlots { public static Qso Apply(Qso qso, ExchangeSlot slot, string value) => slot switch { ExchangeSlot.ReceivedReport => qso with { ReceivedReport = value }, ExchangeSlot.SerialNumber => qso with { ReceivedNumber = Number(value) }, ExchangeSlot.Zone => qso with { Zone = Number(value) }, ExchangeSlot.Section => qso with { Section = value.ToUpperInvariant() }, ExchangeSlot.Check => qso with { Check = Number(value) }, ExchangeSlot.Precedence => qso with { Precedence = value.ToUpperInvariant() }, ExchangeSlot.Exchange1 => qso with { Exchange1 = value.ToUpperInvariant() }, ExchangeSlot.MiscText => qso with { MiscText = value.ToUpperInvariant() }, ExchangeSlot.Name => qso with { Name = value }, ExchangeSlot.Qth => qso with { Qth = value }, ExchangeSlot.GridSquare => qso with { GridSquare = value.ToUpperInvariant() }, ExchangeSlot.Power => qso with { Power = value }, ExchangeSlot.Comment => qso with { Comment = value }, _ => qso, }; /// What a logged contact holds for one exchange box. The inverse of /// `Apply`, used to load a contact back into the entry boxes. public static string ValueOf(Qso qso, ExchangeSlot slot) => slot switch { ExchangeSlot.ReceivedReport => qso.ReceivedReport, ExchangeSlot.SerialNumber => Digits(qso.ReceivedNumber), ExchangeSlot.Zone => Digits(qso.Zone), ExchangeSlot.Section => qso.Section, ExchangeSlot.Check => Digits(qso.Check), ExchangeSlot.Precedence => qso.Precedence, ExchangeSlot.Exchange1 => qso.Exchange1, ExchangeSlot.MiscText => qso.MiscText, ExchangeSlot.Name => qso.Name, ExchangeSlot.Qth => qso.Qth, ExchangeSlot.GridSquare => qso.GridSquare, ExchangeSlot.Power => qso.Power, ExchangeSlot.Comment => qso.Comment, _ => "", }; /// What the call history file says this station sends in one exchange box, /// or an empty string when the file holds nothing for it. public static string ValueFrom(CallHistoryEntry known, ExchangeField field) => field.Slot switch { ExchangeSlot.Name => known.Name, // a file for a section contest often carries the state instead ExchangeSlot.Section => known.Section.Length > 0 ? known.Section : known.State, ExchangeSlot.Check => Digits(known.Check), ExchangeSlot.Zone => field.Kind == ExchangeFieldKind.ItuZone ? Digits(known.ItuZone) : Digits(known.CqZone), ExchangeSlot.Exchange1 => known.Exchange1, ExchangeSlot.MiscText => known.MiscText, ExchangeSlot.GridSquare => known.GridSquare, ExchangeSlot.Power => known.Power, ExchangeSlot.Qth => known.State, _ => "", }; /// Fills the exchange the call history file published for this station into /// a contact. Used where nobody has copied the exchange yet: a spotted /// station the operator has not worked. public static Qso ApplyHistory(Qso qso, CallHistory history, IReadOnlyList exchange) { CallHistoryEntry? known = history.Find(qso.Call.Text); if (known is null) { return qso; } foreach (ExchangeField field in exchange) { string value = ValueFrom(known, field); if (value.Length > 0) { qso = Apply(qso, field.Slot, value); } } return qso; } private static string Digits(int value) => value > 0 ? value.ToString() : ""; private static int Number(string value) => int.TryParse(value, out int parsed) ? parsed : 0; }