/// Metric or imperial readouts (GO 4's General → Units, plan P6). /// /// The aircraft always reports metres and m/s, and every setting is still /// written in metres; only what the pilot reads changes. enum UnitSystem { metric('Metric (m, m/s)'), imperial('Imperial (ft, mph)'); const UnitSystem(this.label); final String label; } abstract final class Units { static const double feetPerMetre = 3.28084; static const double mphPerMs = 2.23694; static const double kmhPerMs = 3.6; /// A height or short distance: `12 m` / `39 ft`. static String length(double? m, UnitSystem u, {int decimals = 0}) { if (m == null) return '—'; return u == UnitSystem.metric ? '${m.toStringAsFixed(decimals)} m' : '${(m * feetPerMetre).toStringAsFixed(decimals)} ft'; } /// A distance that can run long: metres then km, or feet then miles. static String distance(double? m, UnitSystem u) { if (m == null) return '—'; if (u == UnitSystem.metric) return m < 1000 ? '${m.round()} m' : '${(m / 1000).toStringAsFixed(m < 10000 ? 2 : 1)} km'; final double ft = m * feetPerMetre; return ft < 5280 ? '${ft.round()} ft' : '${(ft / 5280).toStringAsFixed(ft < 52800 ? 2 : 1)} mi'; } /// A speed: `8.2 m/s` / `18.3 mph`. static String speed(double? ms, UnitSystem u, {int decimals = 1}) { if (ms == null) return '—'; return u == UnitSystem.metric ? '${ms.toStringAsFixed(decimals)} m/s' : '${(ms * mphPerMs).toStringAsFixed(decimals)} mph'; } /// The bare number for a HUD readout whose unit is drawn apart. static double lengthValue(double m, UnitSystem u) => u == UnitSystem.metric ? m : m * feetPerMetre; static double speedValue(double ms, UnitSystem u) => u == UnitSystem.metric ? ms : ms * mphPerMs; static String lengthUnit(UnitSystem u) => u == UnitSystem.metric ? 'm' : 'ft'; static String speedUnit(UnitSystem u) => u == UnitSystem.metric ? 'm/s' : 'mph'; /// The other system's equivalent beside a metric setting: `≈ 394 ft` / `≈ 120 m`. static String altHint(int metres, UnitSystem u) => u == UnitSystem.metric ? '≈ ${(metres * feetPerMetre).round()} ft' : '${(metres * feetPerMetre).round()} ft'; }