"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ExifDate = void 0;
const luxon_1 = require("luxon");
const DateTime_1 = require("./DateTime");
const Maybe_1 = require("./Maybe");
const String_1 = require("./String");
/**
 * Encodes an ExifDate
 */
class ExifDate {
    static fromISO(text) {
        return this.fromDateTime(luxon_1.DateTime.fromISO(text), text);
    }
    static fromPatterns(text, fmts) {
        if ((0, String_1.blank)(text))
            return;
        text = (0, String_1.toS)(text).trim();
        return (0, Maybe_1.first)(fmts, (fmt) => (0, Maybe_1.map)(luxon_1.DateTime.fromFormat(text, fmt), (dt) => this.fromDateTime(dt, text)));
    }
    // These are all formats I've seen in the wild from exiftool's output.
    // More iterations might make sense, like "d MMM, y" or "MMM d, y", but I
    // want to be constrained in what I consider a valid date to lessen the
    // chance of misinterpreting a given value.
    static fromExifStrict(text) {
        return this.fromPatterns(text, ["y:MM:dd", "y-MM-dd", "y:M:d"]);
    }
    static fromExifLoose(text) {
        return this.fromPatterns(text, ["MMM d y", "MMMM d y"]);
    }
    static fromEXIF(text) {
        return (0, Maybe_1.firstDefinedThunk)([
            () => this.fromExifStrict(text),
            () => this.fromExifLoose(text),
        ]);
    }
    static fromDateTime(dt, rawValue) {
        return (0, DateTime_1.validDateTime)(dt)
            ? new ExifDate(dt.year, dt.month, dt.day, rawValue)
            : undefined;
    }
    constructor(year, // full year (probably 2019-ish, but maybe Japanese 30-ish). See https://ericasadun.com/2018/12/25/iso-8601-yyyy-yyyy-and-why-your-year-may-be-wrong/
    month, // 1-12, (no crazy 0-11 nonsense from Date!)
    day, // 1-31
    rawValue) {
        this.year = year;
        this.month = month;
        this.day = day;
        this.rawValue = rawValue;
    }
    toDate() {
        return new Date(this.year, this.month - 1, this.day);
    }
    /**
     * @return the epoch milliseconds for this day in UTC, plus `deltaMs` milliseconds.
     */
    toMillis(deltaMs = 12 * DateTime_1.HourMs) {
        return this.toDate().getTime() + deltaMs;
    }
    toISOString() {
        return this.toString("-");
    }
    toExifString() {
        return this.toString(":");
    }
    toString(sep = "-") {
        return `${this.year}${sep}${(0, String_1.pad2)(this.month, this.day).join(sep)}`;
    }
    toJSON() {
        return {
            _ctor: "ExifDate",
            year: this.year,
            month: this.month,
            day: this.day,
            rawValue: this.rawValue,
        };
    }
    static fromJSON(json) {
        return new ExifDate(json.year, json.month, json.day, json.rawValue);
    }
}
exports.ExifDate = ExifDate;
//# sourceMappingURL=ExifDate.js.map