"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.HorizontalAlignment = exports.VerticalAlignments = exports.DASH = exports.SPACE = exports.ELLIPSIS = exports.TEXT_BASELINE = exports.TEXT_ALIGNS = exports.FONT_STYLES = exports.FONT_VARIANTS = exports.FONT_WEIGHTS = void 0;
exports.cssFontShorthand = cssFontShorthand;
exports.measureOneBoxWidth = measureOneBoxWidth;
exports.cutToLength = cutToLength;
exports.fitText = fitText;
exports.maximiseFontSize = maximiseFontSize;
const monotonic_hill_climb_1 = require("../solvers/monotonic_hill_climb");
const FONT_WEIGHTS_NUMERIC = [100, 200, 300, 400, 450, 500, 600, 700, 800, 900];
const FONT_WEIGHTS_ALPHA = ['normal', 'bold', 'lighter', 'bolder', 'inherit', 'initial', 'unset'];
exports.FONT_WEIGHTS = Object.freeze([...FONT_WEIGHTS_NUMERIC, ...FONT_WEIGHTS_ALPHA]);
exports.FONT_VARIANTS = Object.freeze(['normal', 'small-caps']);
exports.FONT_STYLES = Object.freeze(['normal', 'italic', 'oblique', 'inherit', 'initial', 'unset']);
exports.TEXT_ALIGNS = Object.freeze(['start', 'end', 'left', 'right', 'center']);
exports.TEXT_BASELINE = Object.freeze([
    'top',
    'hanging',
    'middle',
    'alphabetic',
    'ideographic',
    'bottom',
]);
exports.ELLIPSIS = '…';
exports.SPACE = ' ';
exports.DASH = '-';
function cssFontShorthand({ fontStyle, fontVariant, fontWeight, fontFamily }, fontSize) {
    return `${fontStyle} ${fontVariant} ${fontWeight} ${fontSize}px ${fontFamily}`;
}
exports.VerticalAlignments = Object.freeze({
    top: 'top',
    middle: 'middle',
    bottom: 'bottom',
    alphabetic: 'alphabetic',
    hanging: 'hanging',
    ideographic: 'ideographic',
});
exports.HorizontalAlignment = Object.freeze({
    left: 'left',
    center: 'center',
    right: 'right',
});
function measureOneBoxWidth(measure, fontSize, box) {
    return measure(box.text, box, fontSize).width;
}
function cutToLength(s, maxLength) {
    return s.length <= maxLength ? s : `${s.slice(0, Math.max(0, maxLength - 1))}…`;
}
function truncate(measure, desiredText, allottedWidth, fontSize, font, build, min) {
    if (desiredText.length === 0)
        return { width: measure('', font, fontSize).width, text: '' };
    const fullWidth = measure(desiredText, font, fontSize).width;
    if (fullWidth <= allottedWidth)
        return { width: fullWidth, text: desiredText };
    const response = (k) => measure(build(k), font, fontSize).width;
    const visible = (0, monotonic_hill_climb_1.monotonicHillClimb)(response, desiredText.length, allottedWidth, monotonic_hill_climb_1.integerSnap, min);
    if (!Number.isFinite(visible) || visible < min)
        return { width: measure('', font, fontSize).width, text: '' };
    const text = build(visible);
    const { width } = measure(text, font, fontSize);
    return { width, text };
}
function fitText(measure, desiredText, allottedWidth, fontSize, font, position = 'end') {
    const truncateText = (build, min) => {
        return truncate(measure, desiredText, allottedWidth, fontSize, font, build, min);
    };
    if (position === 'start') {
        return truncateText((k) => `${exports.ELLIPSIS}${desiredText.slice(desiredText.length - k)}`, 1);
    }
    if (position === 'middle') {
        return truncateText((k) => {
            const left = desiredText.slice(0, Math.ceil(k / 2));
            const right = desiredText.slice(desiredText.length - Math.floor(k / 2));
            return `${left}${exports.ELLIPSIS}${right}`;
        }, 2);
    }
    return truncateText((v) => cutToLength(desiredText, v), desiredText.length < 2 ? 1 : 2);
}
function maximiseFontSize(measure, text, font, minFontSize, maxFontSize, boxWidth, boxHeight) {
    const response = (fontSize) => {
        const { width } = measure(text, font, fontSize);
        const widthDiff = boxWidth - width;
        const heightDiff = boxHeight - fontSize;
        return -Math.min(widthDiff, heightDiff);
    };
    return (0, monotonic_hill_climb_1.monotonicHillClimb)(response, maxFontSize, 0, monotonic_hill_climb_1.integerSnap, minFontSize);
}
//# sourceMappingURL=text_utils.js.map