"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Meter = exports.MeterFillStyle = exports.MeterSize = void 0;
const classnames_1 = __importDefault(require("classnames"));
const react_1 = __importDefault(require("react"));
const utils_1 = require("./utils");
const common_1 = require("../../utils/common");
const icon_1 = require("../icons/icon");
const METER_CORNER_RADIUS = 8;
const METER_MARKER_SIZE = 8;
const BASELINE_MARKER_ADJUSTMENT = 1;
exports.MeterSize = Object.freeze({
    Small: 'small',
    Medium: 'medium',
    Large: 'large',
});
exports.MeterFillStyle = Object.freeze({
    Single: 'single',
    Solid: 'solid',
    Gradient: 'gradient',
});
const Meter = ({ value, domain, fill, trackColor, orientation = common_1.LayoutDirection.Horizontal, size = exports.MeterSize.Medium, baseline = 0, target, markerColor, fillBorderColor, fillBorderWidth = 0, showBaselineMarker = false, roundTrackStart = true, roundTrackEnd = true, roundFillStart = true, roundFillEnd = true, className, style, title, valueTitle, targetTitle, ariaLabel = 'Meter', ariaValueText, ariaValueMin, ariaValueMax, ariaValueNow, }) => {
    const isVertical = orientation === common_1.LayoutDirection.Vertical;
    const normalizedDomain = (0, common_1.sortNumbers)(domain);
    const [domainMin, domainMax] = normalizedDomain;
    const geometry = (0, utils_1.getMeterGeometry)(normalizedDomain, value, baseline);
    const baselinePosition = (0, common_1.clamp)(geometry.rawBaselinePosition, 0, 100);
    const hasVisibleBaselineMarker = geometry.isBaselineInDomain && showBaselineMarker;
    const fallbackFillColor = fill.type === exports.MeterFillStyle.Single ? fill.color : fill.fallbackColor ?? fill.colorStops[0]?.color ?? trackColor;
    const solidFillColor = fill.type === exports.MeterFillStyle.Single
        ? fill.color
        : (0, utils_1.getMeterSolidFillColor)(normalizedDomain, fill.colorStops, value, fallbackFillColor);
    const gradientFill = fill.type === 'palette' && fill.style === exports.MeterFillStyle.Gradient
        ? (0, utils_1.getMeterGradientFill)(normalizedDomain, fill.colorStops, orientation)
        : undefined;
    const revealWindow = gradientFill ? (0, utils_1.getMeterRevealWindow)(geometry.fillStart, geometry.fillSize) : undefined;
    const resolvedMarkerColor = markerColor ??
        (fill.type === exports.MeterFillStyle.Single
            ? fill.color
            : (0, utils_1.getMeterSolidFillColor)(normalizedDomain, fill.colorStops, baseline, fallbackFillColor));
    const [resolvedAriaValueMin, resolvedAriaValueMax] = (0, common_1.sortNumbers)([
        ariaValueMin ?? domainMin,
        ariaValueMax ?? domainMax,
    ]);
    const resolvedAriaValueNow = (0, common_1.clamp)(ariaValueNow ?? value, resolvedAriaValueMin, resolvedAriaValueMax);
    const isFillForward = geometry.rawValuePosition >= geometry.rawBaselinePosition;
    let baselineMarkerNudgePx = 0;
    const fillBorderRadius = getFillBorderRadius({
        isVertical,
        isForward: isFillForward,
        roundStart: roundFillStart,
        roundEnd: roundFillEnd,
    });
    const trackBorderRadius = getTrackBorderRadius({
        isVertical,
        roundStart: roundTrackStart,
        roundEnd: roundTrackEnd,
    });
    if (geometry.isBaselineInDomain && geometry.fillSize > 0 && !roundFillStart) {
        baselineMarkerNudgePx = isFillForward ? BASELINE_MARKER_ADJUSTMENT : -BASELINE_MARKER_ADJUSTMENT;
    }
    const fillBorderStyle = geometry.fillSize > 0 && fillBorderColor && fillBorderWidth > 0
        ? { boxShadow: `0 0 0 ${fillBorderWidth}px ${fillBorderColor}` }
        : {};
    const fillWindowStyle = isVertical
        ? {
            bottom: `${geometry.fillStart}%`,
            top: `${100 - geometry.fillEnd}%`,
        }
        : {
            left: `${geometry.fillStart}%`,
            right: `${100 - geometry.fillEnd}%`,
        };
    const fillPaintStyle = gradientFill && revealWindow
        ? isVertical
            ? {
                top: 'auto',
                height: `${revealWindow.scaleFactor * 100}%`,
                bottom: `${revealWindow.offset}%`,
                backgroundImage: gradientFill,
            }
            : {
                right: 'auto',
                width: `${revealWindow.scaleFactor * 100}%`,
                left: `${revealWindow.offset}%`,
                backgroundImage: gradientFill,
            }
        : {
            backgroundColor: solidFillColor,
        };
    const targetPlacement = (0, common_1.isNil)(target)
        ? null
        : `calc(${(0, common_1.clamp)((0, utils_1.getMeterScalePosition)(normalizedDomain, target), 0, 100)}% - ${METER_MARKER_SIZE / 2}px)`;
    const baselinePlacement = hasVisibleBaselineMarker
        ? `calc(${baselinePosition}% - ${METER_MARKER_SIZE / 2 + baselineMarkerNudgePx}px)`
        : null;
    return (react_1.default.createElement("div", { className: (0, classnames_1.default)('echMeter', `echMeter--${size}`, {
            'echMeter--vertical': isVertical,
            'echMeter--horizontal': !isVertical,
        }, className), style: { ...style, backgroundColor: trackColor, ...trackBorderRadius }, title: title },
        targetPlacement && (react_1.default.createElement("div", { className: getDirectionalClasses('echMeterTarget', isVertical), style: {
                [isVertical ? 'bottom' : 'left']: targetPlacement,
            }, title: targetTitle },
            react_1.default.createElement(icon_1.Icon, { height: METER_MARKER_SIZE, width: METER_MARKER_SIZE, type: "downArrow", color: resolvedMarkerColor }))),
        baselinePlacement && (react_1.default.createElement("div", { className: getDirectionalClasses('echMeterBaselineMarker', isVertical), style: {
                [isVertical ? 'bottom' : 'left']: baselinePlacement,
            } },
            react_1.default.createElement("div", { className: "echMeterBaselineMarker__mark", style: { backgroundColor: resolvedMarkerColor } }))),
        react_1.default.createElement("div", { className: getDirectionalClasses('echMeterBar', isVertical), style: { ...fillWindowStyle, ...fillBorderRadius, ...fillBorderStyle }, role: "meter", title: valueTitle, "aria-label": ariaLabel, "aria-valuemin": resolvedAriaValueMin, "aria-valuemax": resolvedAriaValueMax, "aria-valuenow": resolvedAriaValueNow, "aria-valuetext": ariaValueText }, geometry.fillSize > 0 && (react_1.default.createElement("div", { className: (0, classnames_1.default)('echMeterFillPaint', {
                'echMeterFillPaint--vertical': isVertical,
                'echMeterFillPaint--horizontal': !isVertical,
            }), style: { ...fillPaintStyle, ...fillBorderRadius } })))));
};
exports.Meter = Meter;
function getTrackBorderRadius({ isVertical, roundStart, roundEnd, }) {
    const startRadius = roundStart ? METER_CORNER_RADIUS : 0;
    const endRadius = roundEnd ? METER_CORNER_RADIUS : 0;
    return isVertical
        ? {
            borderTopLeftRadius: endRadius,
            borderTopRightRadius: endRadius,
            borderBottomLeftRadius: startRadius,
            borderBottomRightRadius: startRadius,
        }
        : {
            borderTopLeftRadius: startRadius,
            borderTopRightRadius: endRadius,
            borderBottomLeftRadius: startRadius,
            borderBottomRightRadius: endRadius,
        };
}
function getFillBorderRadius({ isVertical, isForward, roundStart, roundEnd, }) {
    const startRadius = roundStart ? METER_CORNER_RADIUS : 0;
    const endRadius = roundEnd ? METER_CORNER_RADIUS : 0;
    if (isVertical) {
        return isForward
            ? {
                borderTopLeftRadius: endRadius,
                borderTopRightRadius: endRadius,
                borderBottomLeftRadius: startRadius,
                borderBottomRightRadius: startRadius,
            }
            : {
                borderTopLeftRadius: startRadius,
                borderTopRightRadius: startRadius,
                borderBottomLeftRadius: endRadius,
                borderBottomRightRadius: endRadius,
            };
    }
    return isForward
        ? {
            borderTopLeftRadius: startRadius,
            borderTopRightRadius: endRadius,
            borderBottomLeftRadius: startRadius,
            borderBottomRightRadius: endRadius,
        }
        : {
            borderTopLeftRadius: endRadius,
            borderTopRightRadius: startRadius,
            borderBottomLeftRadius: endRadius,
            borderBottomRightRadius: startRadius,
        };
}
function getDirectionalClasses(base, isVertical) {
    return (0, classnames_1.default)(base, {
        [`${base}--vertical`]: isVertical,
        [`${base}--horizontal`]: !isVertical,
    });
}
//# sourceMappingURL=meter.js.map