/*
    Copyright 2025 Roman Lefler

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
import { UnitError } from "./errors.js";
import { displayDirection, displayPressure, displayRainMeasurement, displaySpeed, displayTemp } from "./lang.js";
import { gettext as _g } from "./gettext.js";
export var TempUnits;
(function (TempUnits) {
    TempUnits[TempUnits["Fahrenheit"] = 1] = "Fahrenheit";
    TempUnits[TempUnits["Celsius"] = 2] = "Celsius";
})(TempUnits || (TempUnits = {}));
export class Temp {
    #fahrenheit;
    constructor(fahrenheit) {
        this.#fahrenheit = fahrenheit;
    }
    get(units) {
        switch (units) {
            case TempUnits.Fahrenheit:
                return this.#fahrenheit;
            case TempUnits.Celsius:
                return (this.#fahrenheit - 32.0) / 1.8;
            default:
                throw new UnitError("Temperature unit invalid.");
        }
    }
    display(cfg) {
        return displayTemp(this, cfg);
    }
}
export var SpeedUnits;
(function (SpeedUnits) {
    SpeedUnits[SpeedUnits["Mph"] = 1] = "Mph";
    SpeedUnits[SpeedUnits["Mps"] = 2] = "Mps";
    SpeedUnits[SpeedUnits["Kph"] = 3] = "Kph";
    SpeedUnits[SpeedUnits["Kn"] = 4] = "Kn";
    SpeedUnits[SpeedUnits["Fps"] = 5] = "Fps";
    SpeedUnits[SpeedUnits["Beaufort"] = 6] = "Beaufort";
})(SpeedUnits || (SpeedUnits = {}));
export class Speed {
    #mph;
    constructor(mph) {
        this.#mph = mph;
    }
    get(units) {
        switch (units) {
            case SpeedUnits.Mph:
                return this.#mph;
            case SpeedUnits.Mps:
                return this.#mph * 0.44704;
            case SpeedUnits.Kph:
                return this.#mph * 1.609344;
            case SpeedUnits.Kn:
                return this.#mph * 0.868976;
            case SpeedUnits.Fps:
                return this.#mph * 1.466667;
            case SpeedUnits.Beaufort:
                // The upper end of the scale of each Beaufort number
                // Numbers obtained from Wikipedia
                const maxes = [1, 3, 7, 12, 18, 24, 31, 38, 46, 54, 63, 72];
                for (let i = 0; i < maxes.length; i++) {
                    if (this.#mph <= maxes[i])
                        return i;
                }
                // Anything > 72 mph is a 12
                return 12;
            default:
                throw new UnitError("Speed unit invalid.");
        }
    }
    display(cfg) {
        return displaySpeed(this, cfg);
    }
}
export var DirectionUnits;
(function (DirectionUnits) {
    DirectionUnits[DirectionUnits["Degrees"] = 1] = "Degrees";
    DirectionUnits[DirectionUnits["EightPoint"] = 2] = "EightPoint";
})(DirectionUnits || (DirectionUnits = {}));
export class Direction {
    #degrees;
    constructor(degrees) {
        let deg = degrees % 360;
        if (deg < 0)
            deg += 360;
        this.#degrees = deg;
    }
    get(unit) {
        switch (unit) {
            case DirectionUnits.Degrees:
                return this.#degrees;
            case DirectionUnits.EightPoint:
                const point = Math.round(this.#degrees / (360 / 8));
                // While it's not possible to be exactly 8 (second N),
                // We could round up to 8 since 7.9 and others are valid inputs
                const map = [_g("N"), _g("NE"), _g("E"), _g("SE"), _g("S"), _g("SW"), _g("W"), _g("NW"), _g("N")];
                return map[point];
            default:
                throw new UnitError("Direction unit invalid.");
        }
    }
    display(cfg) {
        return displayDirection(this, cfg);
    }
}
export var PressureUnits;
(function (PressureUnits) {
    PressureUnits[PressureUnits["InHg"] = 1] = "InHg";
    PressureUnits[PressureUnits["HPa"] = 2] = "HPa";
    PressureUnits[PressureUnits["MmHg"] = 3] = "MmHg";
})(PressureUnits || (PressureUnits = {}));
export class Pressure {
    #inHg;
    constructor(inHg) {
        this.#inHg = inHg;
    }
    get(unit) {
        switch (unit) {
            case PressureUnits.InHg:
                return this.#inHg;
            case PressureUnits.HPa:
                return this.#inHg * 33.86389;
            case PressureUnits.MmHg:
                return this.#inHg * 25.4;
            default:
                throw new UnitError("Pressure unit invalid.");
        }
    }
    display(cfg) {
        return displayPressure(this, cfg);
    }
}
export var RainMeasurementUnits;
(function (RainMeasurementUnits) {
    RainMeasurementUnits[RainMeasurementUnits["In"] = 1] = "In";
    RainMeasurementUnits[RainMeasurementUnits["Mm"] = 2] = "Mm";
    RainMeasurementUnits[RainMeasurementUnits["Cm"] = 3] = "Cm";
    RainMeasurementUnits[RainMeasurementUnits["Pt"] = 4] = "Pt";
})(RainMeasurementUnits || (RainMeasurementUnits = {}));
export class RainMeasurement {
    #inches;
    constructor(inches) {
        this.#inches = inches;
    }
    get(unit) {
        switch (unit) {
            case RainMeasurementUnits.In:
                return this.#inches;
            case RainMeasurementUnits.Mm:
                return this.#inches * 25.4;
            case RainMeasurementUnits.Cm:
                return this.#inches * 2.54;
            case RainMeasurementUnits.Pt:
                return this.#inches * 0.01;
            default:
                throw new UnitError("Rain measurement unit invalid.");
        }
    }
    display(cfg) {
        return displayRainMeasurement(this, cfg);
    }
}
export var DistanceUnits;
(function (DistanceUnits) {
    DistanceUnits[DistanceUnits["Mi"] = 1] = "Mi";
    DistanceUnits[DistanceUnits["Km"] = 2] = "Km";
    DistanceUnits[DistanceUnits["Ft"] = 3] = "Ft";
    DistanceUnits[DistanceUnits["M"] = 4] = "M";
})(DistanceUnits || (DistanceUnits = {}));
export class Distance {
    #miles;
    constructor(miles) {
        this.#miles = miles;
    }
    get(unit) {
        switch (unit) {
            case DistanceUnits.Mi:
                return this.#miles;
            case DistanceUnits.Km:
                return this.#miles * 1.609344;
            case DistanceUnits.Ft:
                return this.#miles * 5280;
            case DistanceUnits.M:
                return this.#miles * 1609.344;
            default:
                throw new UnitError("Distance unit invalid.");
        }
    }
    display(cfg) {
        const suffices = ["mi", "km", "ft", "m"];
        const unit = cfg.getDistanceUnit();
        return `${this.get(unit)} ${suffices[unit]}`;
    }
}
export class SpeedAndDir {
    #speed;
    #dir;
    constructor(speed, dir) {
        this.#speed = speed;
        this.#dir = dir;
    }
    display(cfg) {
        return displayDirection(this.#dir, cfg) + ", " +
            displaySpeed(this.#speed, cfg);
    }
}
export class Percentage {
    #percentage;
    constructor(zeroToOneHundred) {
        this.#percentage = zeroToOneHundred;
    }
    get() {
        return this.#percentage;
    }
    display(_cfg) {
        return `${Math.round(this.#percentage)}%`;
    }
}
export class GettextKey {
    #key;
    constructor(key) {
        this.#key = key;
    }
    display(_cfg) {
        return _g(this.#key);
    }
}
export class Countdown {
    #date;
    constructor(date) {
        this.#date = date;
    }
    display(cfg) {
        const now = new Date();
        const diff = this.#date.getTime() - now.getTime();
        const seconds = Math.floor(diff / 1000);
        const minutes = Math.floor(seconds / 60);
        const hours = Math.floor(minutes / 60);
        if (minutes < 1)
            return _g("Now");
        if (hours >= 1)
            return _g("%d h").format(hours % 60);
        else
            return _g("%d min").format(minutes % 60);
    }
}
