/**
 * Normalize an array of zones:
 * - ensure than from < to
 * - merge overlapping zones
 * - deal with exclusions zones
 * - if no zones is specified add one between -Infinity and +Infinity
 * @param zones - array of zones
 * @param options - options
 * @returns array of zones
 */
export function zonesNormalize(zones = [], options = {}) {
    const { exclusions = [] } = options;
    let { from = Number.NEGATIVE_INFINITY, to = Number.POSITIVE_INFINITY } = options;
    if (from > to)
        [from, to] = [to, from];
    zones = zones.map((zone) => zone.from > zone.to ? { from: zone.to, to: zone.from } : { ...zone });
    zones.sort((a, b) => {
        if (a.from !== b.from)
            return a.from - b.from;
        return a.to - b.to;
    });
    if (zones.length === 0) {
        zones.push({ from, to });
    }
    for (const zone of zones) {
        if (from > zone.from)
            zone.from = from;
        if (to < zone.to)
            zone.to = to;
    }
    zones = zones.filter((zone) => zone.from <= zone.to);
    if (zones.length === 0)
        return [];
    let currentZone = zones[0];
    const beforeExclusionsZones = [currentZone];
    for (let i = 1; i < zones.length; i++) {
        const zone = zones[i];
        if (zone.from <= currentZone.to) {
            if (currentZone.to < zone.to) {
                currentZone.to = zone.to;
            }
        }
        else {
            currentZone = zone;
            beforeExclusionsZones.push(currentZone);
        }
    }
    if (exclusions.length === 0)
        return beforeExclusionsZones;
    const normalizedExclusions = zonesNormalize(exclusions);
    let currentExclusionIndex = 0;
    const results = [];
    for (let zoneIndex = 0; zoneIndex < beforeExclusionsZones.length; zoneIndex++) {
        const zone = beforeExclusionsZones[zoneIndex];
        if (currentExclusionIndex === normalizedExclusions.length) {
            // we analysed all the exclusion zones
            results.push(zone);
            continue;
        }
        while (currentExclusionIndex < normalizedExclusions.length &&
            normalizedExclusions[currentExclusionIndex].to <= zone.from) {
            currentExclusionIndex++;
        }
        if (currentExclusionIndex === normalizedExclusions.length) {
            // we analysed all the exclusion zones
            results.push(zone);
            continue;
        }
        if (zone.to < normalizedExclusions[currentExclusionIndex].from) {
            // no problems, not yet in exclusion
            results.push(zone);
            continue;
        }
        if (normalizedExclusions[currentExclusionIndex].to >= zone.to) {
            // could be totally excluded
            if (normalizedExclusions[currentExclusionIndex].from <= zone.from) {
                continue;
            }
            results.push({
                from: normalizedExclusions[currentExclusionIndex].to,
                to: zone.to,
            });
        }
        // we cut in the middle, we need to create more zones, annoying !
        if (normalizedExclusions[currentExclusionIndex].from > zone.from) {
            results.push({
                from: zone.from,
                to: normalizedExclusions[currentExclusionIndex].from,
            });
        }
        zone.from = normalizedExclusions[currentExclusionIndex].to;
        zoneIndex--;
    }
    return results;
}
//# sourceMappingURL=zonesNormalize.js.map