using Nonemm.Core; namespace Nonemm.Contests.Rules; /// One line of WAE QTC traffic: a contact one station reports to the other. /// Ten of them make a series, and the series is written `3/10` — the third /// series, ten lines in it. /// /// A QTC lives in the log as an ordinary row with `Exchange1` set to `SQTC` or /// `RQTC`, which is where N1MM keeps it: the time goes in the sent report /// column, the callsign in the received report column, and the serial number in /// the sent number column. Reading it back out is `From`. public sealed record WaeQtc( Callsign Station, bool IsSent, int Series, int CountInSeries, string TimeUtc, Callsign Call, int Number, int OwnNumber = 0) { public const string Contact = "QSO"; public const string Sent = "SQTC"; public const string Received = "RQTC"; /// `Number` is the serial that station sent us in the contact being /// reported, and it is what goes out on the air. `OwnNumber` is the serial /// we sent them, kept only so the same contact is not reported twice; /// N1MM keeps it in the `NR` column for the same reason. /// /// Ten lines to a series, and ten to any one station for the whole contest. public const int MostPerSeries = 10; public const int MostPerStation = 10; public string SeriesText => $"{Series}/{CountInSeries}"; public static bool IsQtc(Qso qso) => qso.Exchange1.Equals(Sent, StringComparison.OrdinalIgnoreCase) || qso.Exchange1.Equals(Received, StringComparison.OrdinalIgnoreCase); /// Null for a row that is an ordinary contact. public static WaeQtc? From(Qso qso) { if (!IsQtc(qso)) { return null; } (int series, int count) = ParseSeries(qso.MiscText); return new WaeQtc( qso.Call, qso.Exchange1.Equals(Sent, StringComparison.OrdinalIgnoreCase), series, count, qso.SentReport, Callsign.Parse(qso.ReceivedReport), qso.SentNumber, qso.ReceivedNumber); } /// Fills this QTC into a log row. The caller supplies the row so the /// frequency, mode and time of the traffic come from wherever it happened. public Qso ApplyTo(Qso qso) => qso with { Call = Station, Exchange1 = IsSent ? Sent : Received, MiscText = SeriesText, SentReport = TimeUtc, ReceivedReport = Call.Text, SentNumber = Number, ReceivedNumber = OwnNumber, }; private static (int Series, int Count) ParseSeries(string text) { string[] parts = text.Split('/', StringSplitOptions.TrimEntries); return parts.Length == 2 && int.TryParse(parts[0], out int series) && int.TryParse(parts[1], out int count) ? (series, count) : (0, 0); } }