"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getLayout = void 0;
const get_bullet_spec_1 = require("./get_bullet_spec");
const get_chart_size_1 = require("./get_chart_size");
const create_selector_1 = require("../../../state/create_selector");
const get_chart_theme_1 = require("../../../state/selectors/get_chart_theme");
const get_settings_spec_1 = require("../../../state/selectors/get_settings_spec");
const canvas_text_bbox_calculator_1 = require("../../../utils/bbox/canvas_text_bbox_calculator");
const wrap_1 = require("../../../utils/text/wrap");
const spec_1 = require("../spec");
const theme_1 = require("../theme");
const minChartHeights = {
    [spec_1.BulletSubtype.horizontal]: 50,
    [spec_1.BulletSubtype.vertical]: 100,
    [spec_1.BulletSubtype.circle]: 160,
    [spec_1.BulletSubtype.halfCircle]: 160,
    [spec_1.BulletSubtype.twoThirdsCircle]: 160,
};
const minChartWidths = {
    [spec_1.BulletSubtype.horizontal]: 140,
    [spec_1.BulletSubtype.vertical]: 140,
    [spec_1.BulletSubtype.circle]: 160,
    [spec_1.BulletSubtype.halfCircle]: 160,
    [spec_1.BulletSubtype.twoThirdsCircle]: 160,
};
exports.getLayout = (0, create_selector_1.createCustomCachedSelector)([get_bullet_spec_1.getBulletSpec, get_chart_size_1.getChartSize, get_settings_spec_1.getSettingsSpecSelector, get_chart_theme_1.getChartThemeSelector], (spec, chartSize, { locale }, { bulletGraph }) => {
    const { data } = spec;
    const rows = data.length;
    const columns = data.reduce((acc, row) => {
        return Math.max(acc, row.length);
    }, 0);
    const panel = { width: chartSize.width / columns, height: chartSize.height / rows };
    const headerSize = {
        width: panel.width - theme_1.HEADER_PADDING.left - theme_1.HEADER_PADDING.right,
        height: panel.height - theme_1.HEADER_PADDING.top - theme_1.HEADER_PADDING.bottom,
    };
    const titleFont = (0, theme_1.getTitleFont)(bulletGraph.fontFamily);
    const subtitleFont = (0, theme_1.getSubtitleFont)(bulletGraph.fontFamily);
    const valueFont = (0, theme_1.getValueFont)(bulletGraph.fontFamily);
    const targetFont = (0, theme_1.getTargetFont)(bulletGraph.fontFamily);
    return (0, canvas_text_bbox_calculator_1.withTextMeasure)((textMeasurer) => {
        const header = data.map((row) => row.map((cell) => {
            if (!cell)
                return null;
            const content = {
                title: cell.title.trim(),
                subtitle: cell.subtitle?.trim(),
                value: `${cell.valueFormatter(cell.value)}${cell.target ? ' ' : ''}`,
                target: cell.target ? `/ ${(cell.targetFormatter ?? cell.valueFormatter)(cell.target)}` : '',
                datum: cell,
            };
            const widths = {
                title: textMeasurer(content.title.trim(), titleFont, theme_1.TITLE_FONT_SIZE).width,
                subtitle: content.subtitle ? textMeasurer(content.subtitle, subtitleFont, theme_1.SUBTITLE_FONT_SIZE).width : 0,
                value: textMeasurer(content.value, valueFont, theme_1.VALUE_FONT_SIZE).width,
                target: textMeasurer(content.target, targetFont, theme_1.TARGET_FONT_SIZE).width,
            };
            return { content, widths };
        }));
        const valueIsBelowTitles = header.some((row) => {
            return row.some((cell) => {
                if (!cell)
                    return false;
                const valuesWidth = cell.widths.value + cell.widths.target;
                const availableWidth = 0.95 * (headerSize.width - valuesWidth);
                if (availableWidth < 0.5 * headerSize.width &&
                    (cell.widths.title > availableWidth || cell.widths.subtitle > availableWidth)) {
                    return true;
                }
                const titleTruncated = (0, wrap_1.wrapText)(cell.content.title, titleFont, theme_1.TITLE_FONT_SIZE, availableWidth, 2, textMeasurer, locale).meta.truncated;
                const subtitleTruncated = cell.content.subtitle
                    ? (0, wrap_1.wrapText)(cell.content.subtitle, subtitleFont, theme_1.SUBTITLE_FONT_SIZE, availableWidth, 1, textMeasurer, locale)
                        .meta.truncated
                    : false;
                return titleTruncated || subtitleTruncated;
            });
        });
        const headerLayout = header.map((row) => {
            return row.map((cell) => {
                if (!cell)
                    return null;
                const valuesWidth = cell.widths.value + cell.widths.target;
                const availableWidth = 0.95 * (headerSize.width - valuesWidth);
                if (valueIsBelowTitles) {
                    return {
                        panel,
                        header: headerSize,
                        title: (0, wrap_1.wrapText)(cell.content.title, titleFont, theme_1.TITLE_FONT_SIZE, headerSize.width, 2, textMeasurer, locale),
                        subtitle: cell.content.subtitle
                            ? (0, wrap_1.wrapText)(cell.content.subtitle, subtitleFont, theme_1.SUBTITLE_FONT_SIZE, headerSize.width, 1, textMeasurer, locale)[0]
                            : undefined,
                        value: cell.content.value,
                        target: cell.content.target,
                        multiline: true,
                        valueWidth: cell.widths.value,
                        targetWidth: cell.widths.target,
                        sizes: cell.widths,
                        datum: cell.content.datum,
                    };
                }
                return {
                    panel,
                    header: headerSize,
                    title: (0, wrap_1.wrapText)(cell.content.title, titleFont, theme_1.TITLE_FONT_SIZE, availableWidth, 2, textMeasurer, locale),
                    subtitle: cell.content.subtitle
                        ? (0, wrap_1.wrapText)(cell.content.subtitle, subtitleFont, theme_1.SUBTITLE_FONT_SIZE, availableWidth, 1, textMeasurer, locale)[0]
                        : undefined,
                    value: cell.content.value,
                    target: cell.content.target,
                    multiline: false,
                    valueWidth: cell.widths.value,
                    targetWidth: cell.widths.target,
                    sizes: cell.widths,
                    datum: cell.content.datum,
                };
            });
        });
        const layoutAlignment = headerLayout.map((curr) => {
            return curr.reduce((rowStats, cell) => {
                const MAX_TARGET_VALUE_ASCENT = (0, theme_1.getMaxTargetValueAssent)(cell?.target);
                const multiline = cell?.multiline ?? false;
                const maxTitleRows = Math.max(rowStats.maxTitleRows, cell?.title.length ?? 0);
                const maxSubtitleRows = Math.max(rowStats.maxSubtitleRows, cell?.subtitle ? 1 : 0);
                const leftHeaderHeight = (0, theme_1.getTextAscentHeight)(theme_1.TITLE_FONT_SIZE, maxTitleRows, theme_1.TITLE_LINE_SPACING) +
                    (maxSubtitleRows > 0 ? theme_1.FONT_PADDING : 0) +
                    (0, theme_1.getTextAscentHeight)(theme_1.SUBTITLE_FONT_SIZE, maxSubtitleRows) +
                    (cell?.multiline ? MAX_TARGET_VALUE_ASCENT + theme_1.FONT_PADDING : 0);
                const rightHeaderHeight = cell?.multiline ? 0 : MAX_TARGET_VALUE_ASCENT;
                const headerHeight = Math.max(leftHeaderHeight, rightHeaderHeight) + theme_1.HEADER_PADDING.top + theme_1.HEADER_PADDING.bottom;
                return {
                    multiline,
                    maxTitleRows,
                    maxSubtitleRows,
                    headerHeight,
                    minHeight: headerHeight + minChartHeights[spec.subtype],
                    minWidth: minChartWidths[spec.subtype],
                };
            }, { maxTitleRows: 0, maxSubtitleRows: 0, multiline: false, headerHeight: 0, minHeight: 0, minWidth: 0 });
        });
        const totalHeight = layoutAlignment.reduce((acc, curr) => {
            return acc + curr.minHeight;
        }, 0);
        const totalWidth = layoutAlignment.reduce((acc, curr) => {
            return Math.max(acc, curr.minWidth);
        }, 0);
        const shouldRenderMetric = chartSize.height <= totalHeight || chartSize.width <= totalWidth * columns;
        return {
            panel,
            headerLayout,
            layoutAlignment,
            shouldRenderMetric,
        };
    });
});
//# sourceMappingURL=get_layout.js.map