"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.GpsLocationTagNames = void 0;
exports.parseGPSLocation = parseGPSLocation;
const CoordinateParser_1 = require("./CoordinateParser");
const Lazy_1 = require("./Lazy");
const Number_1 = require("./Number");
const StrEnum_1 = require("./StrEnum");
const String_1 = require("./String");
exports.GpsLocationTagNames = (0, StrEnum_1.strEnum)("GPSLatitude", "GPSLatitudeRef", "GPSLongitude", "GPSLongitudeRef", "GPSPosition", "GeolocationPosition");
// local function that handles more input types:
function _parseCoordinate(v) {
    return (0, String_1.blank)(v) ? undefined : (0, Number_1.isNumber)(v) ? v : (0, CoordinateParser_1.parseCoordinate)(v).decimal;
}
function _parseCoordinates(v) {
    return (0, String_1.blank)(v) ? undefined : (0, CoordinateParser_1.parseCoordinates)(v);
}
function parseGPSLocation(tags, opts) {
    const warnings = [];
    try {
        // Parse primary coordinates with error capturing
        let latitude = undefined;
        let longitude = undefined;
        try {
            latitude = _parseCoordinate(tags.GPSLatitude);
        }
        catch (e) {
            warnings.push(`Error parsing GPSLatitude: ${e}`);
        }
        try {
            longitude = _parseCoordinate(tags.GPSLongitude);
        }
        catch (e) {
            warnings.push(`Error parsing GPSLongitude: ${e}`);
        }
        // If either coordinate is missing, try GPSPosition
        if (latitude == null || longitude == null) {
            const gpsPos = (0, Lazy_1.lazy)(() => {
                try {
                    return _parseCoordinates(tags.GPSPosition);
                }
                catch (e) {
                    warnings.push(`Error parsing GPSPosition: ${e}`);
                    return undefined;
                }
            });
            latitude ??= gpsPos()?.latitude;
            longitude ??= gpsPos()?.longitude;
        }
        // If we still don't have both coordinates, return early
        if (latitude == null || longitude == null) {
            return { invalid: false, warnings };
        }
        // Check for zero coordinates if configured
        if (opts.ignoreZeroZeroLatLon && latitude === 0 && longitude === 0) {
            warnings.push("Ignoring zero coordinates from GPSLatitude/GPSLongitude");
            return { invalid: true, warnings };
        }
        // Get geolocation reference values for sign validation
        let geoPos = undefined;
        try {
            geoPos = _parseCoordinates(tags.GeolocationPosition);
        }
        catch (e) {
            warnings.push(`Error parsing GeolocationPosition: ${e}`);
        }
        // Process coordinates with validation and sign correction
        const latResult = (0, CoordinateParser_1.processCoordinate)({
            value: latitude,
            ref: tags.GPSLatitudeRef,
            geoValue: geoPos?.latitude,
            expectedRefPositive: "N",
            expectedRefNegative: "S",
            max: 90,
            coordinateType: "Latitude",
        }, warnings);
        const lonResult = (0, CoordinateParser_1.processCoordinate)({
            value: longitude,
            ref: tags.GPSLongitudeRef,
            geoValue: geoPos?.longitude,
            expectedRefPositive: "E",
            expectedRefNegative: "W",
            max: 180,
            coordinateType: "Longitude",
        }, warnings);
        if (latResult.isInvalid || lonResult.isInvalid) {
            return { invalid: true, warnings };
        }
        return {
            result: {
                GPSLatitude: latResult.value,
                GPSLongitude: lonResult.value,
                GPSLatitudeRef: latResult.ref,
                GPSLongitudeRef: lonResult.ref,
            },
            invalid: false,
            warnings,
        };
    }
    catch (e) {
        warnings.push(`Error parsing coordinates: ${e}`);
        return { invalid: true, warnings };
    }
}
//# sourceMappingURL=GPS.js.map