/// <summary>
        /// Based on the MPH/KMPH settings round the current speed to the nearest STEP and
        /// then increase by STEP.
        /// </summary>
        /// <param name="speed">Ingame speed</param>
        /// <returns>Ingame speed increased by the increment for MPH or KMPH</returns>
        public static SpeedValue GetNext(SpeedValue speed)
        {
            if (speed.GameUnits < 0f)
            {
                return(new SpeedValue(-1f));
            }

            if (GlobalConfig.Instance.Main.DisplaySpeedLimitsMph)
            {
                MphValue rounded = speed.ToMphRounded(MPH_STEP);
                rounded += MPH_STEP;

                if (rounded.Mph > UPPER_MPH)
                {
                    rounded = new MphValue(0);
                }

                return(SpeedValue.FromMph(rounded));
            }
            else
            {
                KmphValue rounded = speed.ToKmphRounded(KMPH_STEP);
                rounded += KMPH_STEP;

                if (rounded.Kmph > UPPER_KMPH)
                {
                    rounded = new KmphValue(0);
                }

                return(SpeedValue.FromKmph(rounded));
            }
        }
        /// <summary>
        /// Produces list of speed limits to offer user in the palette
        /// </summary>
        /// <param name="unit">What kind of speed limit list is required</param>
        /// <returns>List from smallest to largest speed with the given unit. Zero (no limit) is not added to the list.
        /// The values are in-game speeds as float.</returns>
        public static List <SpeedValue> EnumerateSpeedLimits(SpeedUnit unit)
        {
            var result = new List <SpeedValue>();

            switch (unit)
            {
            case SpeedUnit.Kmph:
                for (var km = LOWER_KMPH; km <= UPPER_KMPH; km += KMPH_STEP)
                {
                    result.Add(SpeedValue.FromKmph(km));
                }

                break;

            case SpeedUnit.Mph:
                for (var mi = LOWER_MPH; mi <= UPPER_MPH; mi += MPH_STEP)
                {
                    result.Add(SpeedValue.FromMph(mi));
                }

                break;

            case SpeedUnit.CurrentlyConfigured:
                // Automatically choose from the config
                return(GlobalConfig.Instance.Main.DisplaySpeedLimitsMph
                               ? EnumerateSpeedLimits(SpeedUnit.Mph)
                               : EnumerateSpeedLimits(SpeedUnit.Kmph));
            }

            return(result);
        }
        /// <summary>Produces list of speed limits to offer user in the palette.</summary>
        /// <param name="unit">What kind of speed limit list is required.</param>
        /// <returns>
        ///     List from smallest to largest speed with the given unit. Zero (no limit) is
        ///     not added to the list. The values are in-game speeds as float.
        /// </returns>
        public static List <SetSpeedLimitAction> AllSpeedLimits(SpeedUnit unit)
        {
            var result = new List <SetSpeedLimitAction>();

            // SpeedLimitTextures textures = TMPELifecycle.Instance.Textures.SpeedLimits;

            switch (unit)
            {
            case SpeedUnit.Kmph:
                for (var km = RoadSignThemes.KMPH_STEP;
                     km <= RoadSignThemes.UPPER_KMPH;
                     km += RoadSignThemes.KMPH_STEP)
                {
                    result.Add(SetSpeedLimitAction.SetOverride(SpeedValue.FromKmph(km)));
                }

                break;

            case SpeedUnit.Mph:
                for (var mi = RoadSignThemes.MPH_STEP;
                     mi <= RoadSignThemes.UPPER_MPH;
                     mi += RoadSignThemes.MPH_STEP)
                {
                    result.Add(SetSpeedLimitAction.SetOverride(SpeedValue.FromMph(mi)));
                }

                break;

            case SpeedUnit.CurrentlyConfigured:
                // Automatically choose from the config
                return(AllSpeedLimits(GlobalConfig.Instance.Main.GetDisplaySpeedUnit()));
            }

            return(result);
        }
        /// <summary>
        /// Based on the MPH/KMPH settings round the current speed to the nearest STEP and
        /// then decrease by STEP.
        /// </summary>
        /// <param name="speed">Ingame speed</param>
        /// <returns>Ingame speed decreased by the increment for MPH or KMPH</returns>
        public static SpeedValue GetPrevious(SpeedValue speed)
        {
            if (speed.GameUnits < 0f)
            {
                return(new SpeedValue(-1f));
            }

            if (GlobalConfig.Instance.Main.DisplaySpeedLimitsMph)
            {
                MphValue rounded = speed.ToMphRounded(MPH_STEP);
                if (rounded.Mph == LOWER_MPH)
                {
                    return(new SpeedValue(0));
                }

                if (rounded.Mph == 0)
                {
                    return(SpeedValue.FromMph(UPPER_MPH));
                }

                return(SpeedValue.FromMph(rounded.Mph > LOWER_MPH
                                              ? (ushort)(rounded.Mph - MPH_STEP)
                                              : LOWER_MPH));
            }
            else
            {
                KmphValue rounded = speed.ToKmphRounded(KMPH_STEP);
                if (rounded.Kmph == LOWER_KMPH)
                {
                    return(new SpeedValue(0));
                }

                if (rounded.Kmph == 0)
                {
                    return(SpeedValue.FromKmph(UPPER_KMPH));
                }

                return(SpeedValue.FromKmph(rounded.Kmph > LOWER_KMPH
                                               ? (ushort)(rounded.Kmph - KMPH_STEP)
                                               : LOWER_KMPH));
            }
        }