"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.renderLinearPartitionCanvas2d = renderLinearPartitionCanvas2d;
const color_library_wrappers_1 = require("../../../../common/color_library_wrappers");
const colors_1 = require("../../../../common/colors");
const common_1 = require("../../../../utils/common");
const dimmed_colors_1 = require("../../../../utils/themes/dimmed_colors");
const highlighted_geoms_1 = require("../../layout/utils/highlighted_geoms");
const linear = (x) => x;
const easeInOut = (alpha) => (x) => x ** alpha / (x ** alpha + (1 - x) ** alpha);
const MAX_PADDING_RATIO = 0.25;
function renderLinearPartitionCanvas2d(ctx, dpr, { style: { sectorLineWidth: padding }, quadViewModel, diskCenter, width: panelWidth, height: panelHeight, layers, chartDimensions: { width: containerWidth, height: containerHeight }, animation, }, { currentFocusX0, currentFocusX1, prevFocusX0, prevFocusX1 }, highlightedLegendPath, legendStrategy, flatLegend, partitionStyle, animationState) {
    const highlightedQuadSet = new Set();
    if (highlightedLegendPath.length > 0) {
        const highlighted = (0, highlighted_geoms_1.highlightedGeoms)(legendStrategy, flatLegend, quadViewModel, highlightedLegendPath);
        highlighted.forEach((quad) => highlightedQuadSet.add(quad));
    }
    if (animation?.duration) {
        window.cancelAnimationFrame(animationState.rafId);
        render(0);
        const focusChanged = currentFocusX0 !== prevFocusX0 || currentFocusX1 !== prevFocusX1;
        if (focusChanged) {
            animationState.rafId = window.requestAnimationFrame((epochStartTime) => {
                const anim = (t) => {
                    const unitNormalizedTime = Math.max(0, Math.min(1, (t - epochStartTime) / animation.duration));
                    render(unitNormalizedTime);
                    if (unitNormalizedTime < 1) {
                        animationState.rafId = window.requestAnimationFrame(anim);
                    }
                };
                animationState.rafId = window.requestAnimationFrame(anim);
            });
        }
    }
    else {
        render(1);
    }
    function render(logicalTime, timeFunction = animation?.duration
        ? easeInOut(Math.min(5, animation.duration / 100))
        : linear) {
        const width = containerWidth * panelWidth;
        const height = containerHeight * panelHeight;
        const t = timeFunction(logicalTime);
        const focusX0 = t * currentFocusX0 + (1 - t) * prevFocusX0 || 0;
        const focusX1 = t * currentFocusX1 + (1 - t) * prevFocusX1 || 0;
        const scale = containerWidth / (focusX1 - focusX0);
        ctx.save();
        ctx.textAlign = 'left';
        ctx.textBaseline = 'middle';
        ctx.scale(dpr, dpr);
        ctx.translate(diskCenter.x, diskCenter.y);
        ctx.clearRect(0, 0, width, height);
        quadViewModel.forEach((quad) => {
            const { fillColor, x0, x1, y0px: y0, y1px: y1, dataName, textColor, depth } = quad;
            if (y1 - y0 <= padding)
                return;
            const fx0 = Math.max((x0 - focusX0) * scale, 0);
            const fx1 = Math.min((x1 - focusX0) * scale, width);
            if (fx1 < 0 || fx0 > width)
                return;
            const layer = layers[depth - 1];
            const formatter = layer?.nodeLabel ?? String;
            const label = formatter(dataName);
            const fWidth = fx1 - fx0;
            const fPadding = Math.min(padding, MAX_PADDING_RATIO * fWidth);
            const isDimmed = highlightedQuadSet.size > 0 && !highlightedQuadSet.has(quad);
            const baseFillColor = (0, common_1.getColorFromVariant)(fillColor, (0, dimmed_colors_1.getDimmedColor)(isDimmed, partitionStyle.dimmed, 'fill', fillColor));
            const dimmedFillColor = isDimmed && 'opacity' in partitionStyle.dimmed
                ? (0, color_library_wrappers_1.multiplyColorOpacity)(baseFillColor, partitionStyle.dimmed.opacity)
                : baseFillColor;
            ctx.fillStyle = dimmedFillColor;
            ctx.beginPath();
            ctx.rect(fx0 + fPadding, y0 + padding / 2, fWidth - fPadding, y1 - y0 - padding);
            ctx.fill();
            if (textColor === colors_1.Colors.Transparent.keyword || label === '' || fWidth < 4)
                return;
            ctx.fillStyle = textColor;
            ctx.save();
            ctx.clip();
            ctx.fillText(label, fx0 + 3 * fPadding, (y0 + y1) / 2);
            ctx.restore();
        });
        ctx.restore();
    }
}
//# sourceMappingURL=canvas_linear_renderers.js.map