"use strict";
var __read = (this && this.__read) || function (o, n) {
    var m = typeof Symbol === "function" && o[Symbol.iterator];
    if (!m) return o;
    var i = m.call(o), r, ar = [], e;
    try {
        while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
    }
    catch (error) { e = { error: error }; }
    finally {
        try {
            if (r && !r.done && (m = i["return"])) m.call(i);
        }
        finally { if (e) throw e.error; }
    }
    return ar;
};
var __spread = (this && this.__spread) || function () {
    for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));
    return ar;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.convertXScaleTypes = exports.findMinInterval = exports.mergeXDomain = void 0;
var constants_1 = require("../../../scales/constants");
var common_1 = require("../../../utils/common");
var domain_1 = require("../../../utils/domain");
var logger_1 = require("../../../utils/logger");
var get_api_scales_1 = require("../scales/get_api_scales");
var axis_type_utils_1 = require("../utils/axis_type_utils");
var specs_1 = require("../utils/specs");
var nice_1 = require("./nice");
function mergeXDomain(_a, xValues, fallbackScale) {
    var type = _a.type, nice = _a.nice, isBandScale = _a.isBandScale, timeZone = _a.timeZone, desiredTickCount = _a.desiredTickCount, customDomain = _a.customDomain;
    var values = __spread(xValues.values());
    var seriesXComputedDomains;
    var minInterval = 0;
    if (type === constants_1.ScaleType.Ordinal || fallbackScale === constants_1.ScaleType.Ordinal) {
        if (type !== constants_1.ScaleType.Ordinal) {
            logger_1.Logger.warn("Each X value in a " + type + " x scale needs be be a number. Using ordinal x scale as fallback.");
        }
        seriesXComputedDomains = domain_1.computeOrdinalDataDomain(values, common_1.identity, false, true);
        if (customDomain) {
            if (Array.isArray(customDomain)) {
                seriesXComputedDomains = customDomain;
            }
            else {
                if (fallbackScale === constants_1.ScaleType.Ordinal) {
                    logger_1.Logger.warn("xDomain ignored for fallback ordinal scale. Options to resolve:\n\n1) Correct data to match " + type + " scale type (see previous warning)\n2) Change xScaleType to ordinal and set xDomain to Domain array");
                }
                else {
                    logger_1.Logger.warn('xDomain for ordinal scale should be an array of values, not a DomainRange object. xDomain is ignored.');
                }
            }
        }
    }
    else {
        seriesXComputedDomains = domain_1.computeContinuousDataDomain(values, common_1.identity, type, {
            fit: true,
        });
        var customMinInterval = void 0;
        if (customDomain) {
            if (Array.isArray(customDomain)) {
                logger_1.Logger.warn('xDomain for continuous scale should be a DomainRange object, not an array');
            }
            else {
                customMinInterval = customDomain.minInterval;
                var _b = __read(seriesXComputedDomains, 2), computedDomainMin = _b[0], computedDomainMax = _b[1];
                if (axis_type_utils_1.isCompleteBound(customDomain)) {
                    if (customDomain.min > customDomain.max) {
                        logger_1.Logger.warn('custom xDomain is invalid, min is greater than max. Custom domain is ignored.');
                    }
                    else {
                        seriesXComputedDomains = [customDomain.min, customDomain.max];
                    }
                }
                else if (axis_type_utils_1.isLowerBound(customDomain)) {
                    if (customDomain.min > computedDomainMax) {
                        logger_1.Logger.warn('custom xDomain is invalid, custom min is greater than computed max. Custom domain is ignored.');
                    }
                    else {
                        seriesXComputedDomains = [customDomain.min, computedDomainMax];
                    }
                }
                else if (axis_type_utils_1.isUpperBound(customDomain)) {
                    if (computedDomainMin > customDomain.max) {
                        logger_1.Logger.warn('custom xDomain is invalid, computed min is greater than custom max. Custom domain is ignored.');
                    }
                    else {
                        seriesXComputedDomains = [computedDomainMin, customDomain.max];
                    }
                }
            }
        }
        var computedMinInterval = findMinInterval(values);
        minInterval = getMinInterval(computedMinInterval, xValues.size, customMinInterval);
    }
    return {
        type: fallbackScale !== null && fallbackScale !== void 0 ? fallbackScale : type,
        nice: nice,
        isBandScale: isBandScale,
        domain: seriesXComputedDomains,
        minInterval: minInterval,
        timeZone: timeZone,
        logBase: customDomain && 'logBase' in customDomain ? customDomain.logBase : undefined,
        desiredTickCount: desiredTickCount,
    };
}
exports.mergeXDomain = mergeXDomain;
function getMinInterval(computedMinInterval, size, customMinInterval) {
    if (customMinInterval == null) {
        return computedMinInterval;
    }
    if (size > 1 && customMinInterval > computedMinInterval) {
        logger_1.Logger.warn('custom xDomain is invalid, custom minInterval is greater than computed minInterval. Using computed minInterval.');
        return computedMinInterval;
    }
    if (customMinInterval < 0) {
        logger_1.Logger.warn('custom xDomain is invalid, custom minInterval is less than 0. Using computed minInterval.');
        return computedMinInterval;
    }
    return customMinInterval;
}
function findMinInterval(xValues) {
    var valuesLength = xValues.length;
    if (valuesLength <= 0) {
        return 0;
    }
    if (valuesLength === 1) {
        return 1;
    }
    var sortedValues = xValues.slice().sort(common_1.compareByValueAsc);
    var i;
    var minInterval = Math.abs(sortedValues[1] - sortedValues[0]);
    for (i = 1; i < valuesLength - 1; i++) {
        var current = sortedValues[i];
        var next = sortedValues[i + 1];
        var interval = Math.abs(next - current);
        minInterval = Math.min(minInterval, interval);
    }
    return minInterval;
}
exports.findMinInterval = findMinInterval;
function convertXScaleTypes(specs) {
    var seriesTypes = new Set();
    var scaleTypes = new Set();
    var timeZones = new Set();
    var niceDomainConfigs = [];
    specs.forEach(function (spec) {
        niceDomainConfigs.push(get_api_scales_1.getXNiceFromSpec(spec.xNice));
        seriesTypes.add(spec.seriesType);
        scaleTypes.add(get_api_scales_1.getXScaleTypeFromSpec(spec.xScaleType));
        if (spec.timeZone) {
            timeZones.add(spec.timeZone.toLowerCase());
        }
    });
    if (specs.length === 0 || seriesTypes.size === 0 || scaleTypes.size === 0) {
        return {
            type: constants_1.ScaleType.Linear,
            nice: true,
            isBandScale: false,
        };
    }
    var nice = nice_1.areAllNiceDomain(niceDomainConfigs);
    var isBandScale = seriesTypes.has(specs_1.SeriesType.Bar);
    if (scaleTypes.size === 1) {
        var scaleType = scaleTypes.values().next().value;
        var timeZone = timeZones.size > 1 ? 'utc' : timeZones.values().next().value;
        return { type: scaleType, nice: nice, isBandScale: isBandScale, timeZone: timeZone };
    }
    if (scaleTypes.size > 1 && scaleTypes.has(constants_1.ScaleType.Ordinal)) {
        return {
            type: constants_1.ScaleType.Ordinal,
            nice: nice,
            isBandScale: isBandScale,
        };
    }
    return {
        type: constants_1.ScaleType.Linear,
        nice: nice,
        isBandScale: isBandScale,
    };
}
exports.convertXScaleTypes = convertXScaleTypes;
//# sourceMappingURL=x_domain.js.map