"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;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var chroma_js_1 = __importDefault(require("chroma-js"));
var color_library_wrappers_1 = require("./color_library_wrappers");
function hueInterpolator(colors) {
    return function (d) {
        var index = Math.round(d * 255);
        var _a = __read(colors[index], 4), r = _a[0], g = _a[1], b = _a[2], a = _a[3];
        return colors[index].length === 3 ? "rgb(" + r + "," + g + "," + b + ")" : "rgba(" + r + "," + g + "," + b + "," + a + ")";
    };
}
exports.hueInterpolator = hueInterpolator;
function addOpacity(hexColorString, opacity) {
    return opacity === 1
        ? hexColorString
        : hexColorString.slice(0, 7) +
            (hexColorString.slice(7).length === 0 || parseInt(hexColorString.slice(7, 2), 16) === 255
                ? ("00" + Math.round(opacity * 255).toString(16)).slice(-2)
                : ("00" + Math.round((parseInt(hexColorString.slice(7, 2), 16) / 255) * opacity * 255).toString(16)).slice(-2));
}
exports.addOpacity = addOpacity;
function arrayToLookup(keyFun, array) {
    return Object.assign.apply(Object, __spread([{}], array.map(function (d) {
        var _a;
        return (_a = {}, _a[keyFun(d)] = d, _a);
    })));
}
exports.arrayToLookup = arrayToLookup;
function combineColors(foregroundColor, backgroundColor) {
    var _a = __read(chroma_js_1.default(foregroundColor).rgba(), 4), red1 = _a[0], green1 = _a[1], blue1 = _a[2], alpha1 = _a[3];
    var _b = __read(chroma_js_1.default(backgroundColor).rgba(), 4), red2 = _b[0], green2 = _b[1], blue2 = _b[2], alpha2 = _b[3];
    var combinedAlpha = alpha1 + alpha2 * (1 - alpha1);
    if (combinedAlpha === 0) {
        return 'rgba(0,0,0,0)';
    }
    var combinedRed = Math.round((red1 * alpha1 + red2 * alpha2 * (1 - alpha1)) / combinedAlpha);
    var combinedGreen = Math.round((green1 * alpha1 + green2 * alpha2 * (1 - alpha1)) / combinedAlpha);
    var combinedBlue = Math.round((blue1 * alpha1 + blue2 * alpha2 * (1 - alpha1)) / combinedAlpha);
    var rgba = [combinedRed, combinedGreen, combinedBlue, combinedAlpha];
    return color_library_wrappers_1.RGBATupleToString(rgba);
}
exports.combineColors = combineColors;
function isColorValid(color) {
    return Boolean(color) && chroma_js_1.default.valid(color);
}
exports.isColorValid = isColorValid;
function makeHighContrastColor(foreground, background, ratio) {
    if (ratio === void 0) { ratio = 4.5; }
    var lightness = chroma_js_1.default(background).get('hsl.l');
    var highContrastTextColor = foreground;
    var isBackgroundDark = colorIsDark(background);
    if (isBackgroundDark && chroma_js_1.default.deltaE('black', foreground) === 0) {
        highContrastTextColor = '#fff';
    }
    else if (lightness > 0.5 && chroma_js_1.default.deltaE('white', foreground) === 0) {
        highContrastTextColor = '#000';
    }
    var precision = 1e8;
    var contrast = getContrast(highContrastTextColor, background);
    while (contrast < ratio) {
        if (isBackgroundDark) {
            highContrastTextColor = chroma_js_1.default(highContrastTextColor)
                .brighten()
                .toString();
        }
        else {
            highContrastTextColor = chroma_js_1.default(highContrastTextColor)
                .darken()
                .toString();
        }
        var scaledOldContrast = Math.round(contrast * precision) / precision;
        contrast = getContrast(highContrastTextColor, background);
        var scaledContrast = Math.round(contrast * precision) / precision;
        if (scaledOldContrast === scaledContrast) {
            break;
        }
    }
    return highContrastTextColor.toString();
}
exports.makeHighContrastColor = makeHighContrastColor;
function getContrast(foregroundColor, backgroundColor) {
    return chroma_js_1.default.contrast(foregroundColor, backgroundColor);
}
exports.getContrast = getContrast;
function colorIsDark(color) {
    var luminance = chroma_js_1.default(color).luminance();
    return luminance < 0.2;
}
exports.colorIsDark = colorIsDark;
function getTextColorIfTextInvertible(specifiedTextColorIsDark, backgroundIsDark, textColor, textContrast, backgroundColor) {
    var inverseForContrast = specifiedTextColorIsDark === backgroundIsDark;
    var _a = color_library_wrappers_1.stringToRGB(textColor), tr = _a.r, tg = _a.g, tb = _a.b, to = _a.opacity;
    if (!textContrast) {
        return inverseForContrast
            ? to === undefined
                ? "rgb(" + (255 - tr) + ", " + (255 - tg) + ", " + (255 - tb) + ")"
                : "rgba(" + (255 - tr) + ", " + (255 - tg) + ", " + (255 - tb) + ", " + to + ")"
            : textColor;
    }
    if (textContrast === true && typeof textContrast !== 'number') {
        return inverseForContrast
            ? to === undefined
                ? makeHighContrastColor("rgb(" + (255 - tr) + ", " + (255 - tg) + ", " + (255 - tb) + ")", backgroundColor)
                : makeHighContrastColor("rgba(" + (255 - tr) + ", " + (255 - tg) + ", " + (255 - tb) + ", " + to + ")", backgroundColor)
            : makeHighContrastColor(textColor, backgroundColor);
    }
    if (typeof textContrast === 'number') {
        return inverseForContrast
            ? to === undefined
                ? makeHighContrastColor("rgb(" + (255 - tr) + ", " + (255 - tg) + ", " + (255 - tb) + ")", backgroundColor, textContrast)
                : makeHighContrastColor("rgba(" + (255 - tr) + ", " + (255 - tg) + ", " + (255 - tb) + ", " + to + ")", backgroundColor, textContrast)
            : makeHighContrastColor(textColor, backgroundColor, textContrast);
    }
}
exports.getTextColorIfTextInvertible = getTextColorIfTextInvertible;
function integerSnap(n) {
    return Math.floor(n);
}
exports.integerSnap = integerSnap;
function monotonicHillClimb(getResponse, maxVar, responseUpperConstraint, domainSnap, minVar) {
    if (domainSnap === void 0) { domainSnap = function (n) { return n; }; }
    if (minVar === void 0) { minVar = 0; }
    var loVar = domainSnap(minVar);
    var loResponse = getResponse(loVar);
    var hiVar = domainSnap(maxVar);
    var hiResponse = getResponse(hiVar);
    if (loResponse > responseUpperConstraint || loVar > hiVar) {
        return NaN;
    }
    if (hiResponse <= responseUpperConstraint) {
        return hiVar;
    }
    var pivotVar = NaN;
    var pivotResponse = NaN;
    var lastPivotResponse = NaN;
    while (loVar < hiVar) {
        var newPivotVar = (loVar + hiVar) / 2;
        var newPivotResponse = getResponse(domainSnap(newPivotVar));
        if (newPivotResponse === pivotResponse || newPivotResponse === lastPivotResponse) {
            return domainSnap(loVar);
        }
        pivotVar = newPivotVar;
        lastPivotResponse = pivotResponse;
        pivotResponse = newPivotResponse;
        var pivotIsCompliant = pivotResponse <= responseUpperConstraint;
        if (pivotIsCompliant) {
            loVar = pivotVar;
        }
        else {
            hiVar = pivotVar;
            hiResponse = pivotResponse;
        }
    }
    return domainSnap(pivotVar);
}
exports.monotonicHillClimb = monotonicHillClimb;
//# sourceMappingURL=calcs.js.map