"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.hueInterpolator = hueInterpolator;
exports.arrayToLookup = arrayToLookup;
exports.combineColors = combineColors;
exports.highContrastColor = highContrastColor;
exports.getContrastRecommendation = getContrastRecommendation;
const apca_color_contrast_1 = require("./apca_color_contrast");
const color_library_wrappers_1 = require("./color_library_wrappers");
const colors_1 = require("./colors");
const wcag2_color_contrast_1 = require("./wcag2_color_contrast");
function hueInterpolator(colors) {
    return (d) => (0, color_library_wrappers_1.RGBATupleToString)(colors[Math.round(d * 255)] ?? colors_1.Colors.White.rgba);
}
function arrayToLookup(keyFun, array) {
    return Object.assign({}, ...array.map((d) => ({ [keyFun(d)]: d })));
}
function combineColors([fgR, fgG, fgB, fgA], [bgR, bgG, bgB, bgA]) {
    if (fgA === 1) {
        return [fgR, fgG, fgB, fgA];
    }
    const alpha = fgA + bgA * (1 - fgA);
    if (alpha === 0) {
        return colors_1.Colors.Transparent.rgba;
    }
    const r = Math.round((fgR * fgA + bgR * bgA * (1 - fgA)) / alpha);
    const g = Math.round((fgG * fgA + bgG * bgA * (1 - fgA)) / alpha);
    const b = Math.round((fgB * fgA + bgB * bgA * (1 - fgA)) / alpha);
    return [r, g, b, alpha];
}
const getOptionWithDefaults = (options = {}) => ({
    darkColor: colors_1.Colors.Black.rgba,
    lightColor: colors_1.Colors.White.rgba,
    ...options,
});
function getHighContrastColorWCAG2(background, options = {}) {
    const { lightColor, darkColor } = getOptionWithDefaults(options);
    const wLight = (0, wcag2_color_contrast_1.getWCAG2ContrastRatio)(lightColor, background);
    const wDark = (0, wcag2_color_contrast_1.getWCAG2ContrastRatio)(darkColor, background);
    return wLight >= wDark
        ? {
            color: {
                rgba: lightColor,
                keyword: (0, color_library_wrappers_1.RGBATupleToString)(lightColor),
            },
            ratio: wLight,
            shade: 'light',
        }
        : {
            color: {
                rgba: darkColor,
                keyword: (0, color_library_wrappers_1.RGBATupleToString)(darkColor),
            },
            ratio: wDark,
            shade: 'dark',
        };
}
function getHighContrastColorAPCA(background, options = {}) {
    const { lightColor, darkColor } = getOptionWithDefaults(options);
    const wLightText = Math.abs((0, apca_color_contrast_1.APCAContrast)(background, lightColor));
    const wDarkText = Math.abs((0, apca_color_contrast_1.APCAContrast)(background, darkColor));
    return wLightText > wDarkText
        ? {
            color: {
                rgba: lightColor,
                keyword: (0, color_library_wrappers_1.RGBATupleToString)(lightColor),
            },
            ratio: wLightText,
            shade: 'light',
        }
        : {
            color: {
                rgba: darkColor,
                keyword: (0, color_library_wrappers_1.RGBATupleToString)(darkColor),
            },
            ratio: wDarkText,
            shade: 'dark',
        };
}
const HIGH_CONTRAST_FN = {
    WCAG2: getHighContrastColorWCAG2,
    WCAG3: getHighContrastColorAPCA,
};
function highContrastColor(background, mode = 'WCAG2', options) {
    return HIGH_CONTRAST_FN[mode](background, options);
}
function getContrastRecommendation(colorA, colorB, options = {}) {
    const { contrastMode = 'WCAG2', contrastThreshold = 4.5, borderOptions, } = options;
    const rgbA = (0, color_library_wrappers_1.colorToRgba)(colorA).slice(0, 3);
    const rgbB = (0, color_library_wrappers_1.colorToRgba)(colorB).slice(0, 3);
    const contrastRatio = contrastMode === 'WCAG2' ? (0, wcag2_color_contrast_1.getWCAG2ContrastRatio)(rgbA, rgbB) : Math.abs((0, apca_color_contrast_1.APCAContrast)(rgbA, rgbB));
    if (contrastRatio >= contrastThreshold) {
        return {
            needsBorder: false,
            contrastRatio,
            borderColor: undefined,
            shade: undefined,
            color1Contrast: undefined,
            color2Contrast: undefined,
        };
    }
    const color1Result = highContrastColor(rgbA, contrastMode, borderOptions);
    const color2Result = highContrastColor(rgbB, contrastMode, borderOptions);
    const selectedShade = color1Result.shade === color2Result.shade
        ? color1Result.shade
        : color1Result.ratio > color2Result.ratio
            ? color1Result.shade
            : color2Result.shade;
    const borderColor = color1Result.shade === color2Result.shade
        ? color1Result.color.keyword
        : color1Result.ratio > color2Result.ratio
            ? color1Result.color.keyword
            : color2Result.color.keyword;
    return {
        needsBorder: true,
        contrastRatio,
        borderColor,
        shade: selectedShade,
        color1Contrast: color1Result.ratio,
        color2Contrast: color2Result.ratio,
    };
}
//# sourceMappingURL=color_calcs.js.map