File: RoutePart.cs
Web Access
Project: ..\..\..\src\Iot.Device.Bindings\Iot.Device.Bindings.csproj (Iot.Device.Bindings)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using UnitsNet;
 
namespace Iot.Device.Nmea0183.Sentences
{
    /// <summary>
    /// RTE sentence: Identifiers of waypoints of current route
    /// </summary>
    public class RoutePart : NmeaSentence
    {
        /// <summary>
        /// This sentence's id
        /// </summary>
        public static SentenceId Id => new SentenceId("RTE");
        private static bool Matches(SentenceId sentence) => Id == sentence;
        private static bool Matches(TalkerSentence sentence) => Matches(sentence.Id);
 
        /// <summary>
        /// Constructs a new RTE sentence
        /// </summary>
        public RoutePart(string routeName, int totalSequences, int sequence, List<string> waypointNames)
            : base(OwnTalkerId, Id, DateTimeOffset.UtcNow)
        {
            RouteName = routeName;
            // Sequence number is 1-based.
            if (sequence < 1 || totalSequences < sequence)
            {
                throw new ArgumentOutOfRangeException(nameof(sequence), "Current sequence number must be smaller than total sequences");
            }
 
            TotalSequences = totalSequences;
            Sequence = sequence;
            WaypointNames = waypointNames ?? throw new ArgumentNullException(nameof(waypointNames));
            Valid = true;
        }
 
        /// <summary>
        /// False, since multiple messages belong to a packet
        /// </summary>
        public override bool ReplacesOlderInstance => false;
 
        /// <summary>
        /// Internal constructor
        /// </summary>
        public RoutePart(TalkerSentence sentence, DateTimeOffset time)
            : this(sentence.TalkerId, Matches(sentence) ? sentence.Fields : throw new ArgumentException($"SentenceId does not match expected id '{Id}'"), time)
        {
        }
 
        /// <summary>
        /// Date and time message (ZDA). This should not normally need the last time as argument, because it defines it.
        /// </summary>
        public RoutePart(TalkerId talkerId, IEnumerable<string> fields, DateTimeOffset time)
            : base(talkerId, Id, time)
        {
            IEnumerator<string> field = fields.GetEnumerator();
 
            RouteName = string.Empty;
            int? numberOfSequences = ReadInt(field);
            int? numberOfSequence = ReadInt(field);
 
            string sentenceMode = ReadString(field);
            string routeName = ReadString(field);
 
            // SentenceMode "w" not yet supported
            if (numberOfSequences.HasValue && numberOfSequence.HasValue && sentenceMode == "c")
            {
                Valid = true;
                RouteName = routeName;
                TotalSequences = numberOfSequences.Value;
                Sequence = numberOfSequence.Value;
                WaypointNames = new List<string>();
                while (field.MoveNext())
                {
                    WaypointNames.Add(field.Current);
                }
            }
            else
            {
                // Empty list
                WaypointNames = new List<string>();
                TotalSequences = 1;
                Sequence = 1;
            }
        }
 
        /// <summary>
        /// Name of the route
        /// </summary>
        public string RouteName
        {
            get;
        }
 
        /// <summary>
        /// Number of the sequence (which part of the route this is). The total number of sequences in the route is
        /// specified by <see cref="TotalSequences"/>
        /// </summary>
        public int Sequence
        {
            get;
        }
 
        /// <summary>
        /// Total sequences in this route
        /// </summary>
        public int TotalSequences
        {
            get;
        }
 
        /// <summary>
        /// List of waypoint names in this sequence
        /// </summary>
        public List<string> WaypointNames
        {
            get;
        }
 
        /// <summary>
        /// Presents this message as output
        /// </summary>
        public override string ToNmeaParameterList()
        {
            if (Valid)
            {
                StringBuilder b = new StringBuilder();
                b.AppendFormat(CultureInfo.InvariantCulture, "{0},{1},c,", TotalSequences, Sequence);
                b.Append(RouteName + ",");
                b.Append(string.Join(",", WaypointNames));
                return b.ToString();
            }
 
            return string.Empty;
        }
 
        /// <inheritdoc />
        public override string ToReadableContent()
        {
            if (Valid)
            {
                return $"Route {RouteName}, Sequence {Sequence}/{TotalSequences}, Waypoints: {string.Join(",", WaypointNames)}";
            }
 
            return "Not a valid route segment";
        }
    }
}