/*!
 * Copyright (c) 2026 Vertex Software LLC. All rights reserved.
 */
import { h, F as Fragment, r as registerInstance, H as Host } from './index-EpnuuCxl.js';
import { D as DistanceUnits, A as AngleUnits, g as AreaUnits } from './streamAttributes-B6xi3kRV.js';
import './entities-BAhfr1Nx.js';
import { _ as __assign, v as vector3 } from './bundle-DfdVaPrt.js';
import { c as classname } from './index-DI7z7TKn.js';
import './bundle-CLE0fYge.js';
import './_commonjsHelpers-CG9AChtV.js';
import './bundle-DLfw87TV.js';

/**
 * Source: ftp://ftp.unicode.org/Public/UCD/latest/ucd/SpecialCasing.txt
 */
/**
 * Lower case as a function.
 */
function lowerCase(str) {
    return str.toLowerCase();
}

// Support camel case ("camelCase" -> "camel Case" and "CAMELCase" -> "CAMEL Case").
var DEFAULT_SPLIT_REGEXP = [/([a-z0-9])([A-Z])/g, /([A-Z])([A-Z][a-z])/g];
// Remove all non-word characters.
var DEFAULT_STRIP_REGEXP = /[^A-Z0-9]+/gi;
/**
 * Normalize the string into something other libraries can manipulate easier.
 */
function noCase(input, options) {
    if (options === void 0) { options = {}; }
    var _a = options.splitRegexp, splitRegexp = _a === void 0 ? DEFAULT_SPLIT_REGEXP : _a, _b = options.stripRegexp, stripRegexp = _b === void 0 ? DEFAULT_STRIP_REGEXP : _b, _c = options.transform, transform = _c === void 0 ? lowerCase : _c, _d = options.delimiter, delimiter = _d === void 0 ? " " : _d;
    var result = replace(replace(input, splitRegexp, "$1\0$2"), stripRegexp, "\0");
    var start = 0;
    var end = result.length;
    // Trim the delimiter from around the output string.
    while (result.charAt(start) === "\0")
        start++;
    while (result.charAt(end - 1) === "\0")
        end--;
    // Transform each token independently.
    return result.slice(start, end).split("\0").map(transform).join(delimiter);
}
/**
 * Replace `re` in the input string with the replacement value.
 */
function replace(input, re, value) {
    if (re instanceof RegExp)
        return input.replace(re, value);
    return re.reduce(function (input, re) { return input.replace(re, value); }, input);
}

function dotCase(input, options) {
    if (options === void 0) { options = {}; }
    return noCase(input, __assign({ delimiter: "." }, options));
}

function paramCase(input, options) {
    if (options === void 0) { options = {}; }
    return dotCase(input, __assign({ delimiter: "-" }, options));
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
const MeasurementDetailsEntry = ({ label, ...props }, children) => {
    return (h("div", { ...props, class: "measurement-details-entry" }, h("div", { class: classname('measurement-details-entry-label', paramCase(label)) }, label, ":"), children));
};

// eslint-disable-next-line @typescript-eslint/no-unused-vars
const MinimumDistanceResultEntry = ({ result, formatter, overlays, onShowOverlay, onHideOverlay }) => {
    const v = vector3.subtract(result.point1, result.point2);
    return (h(Fragment, null, h(MeasurementDetailsEntry, { label: "Dist", onMouseEnter: () => onShowOverlay(overlays === null || overlays === void 0 ? void 0 : overlays.addLineFromResult(result)), onMouseLeave: onHideOverlay }, formatter(result.distance)), h(MeasurementDetailsEntry, { label: "X", onMouseEnter: () => onShowOverlay(overlays === null || overlays === void 0 ? void 0 : overlays.addDistanceVectorFromResult(result)), onMouseLeave: onHideOverlay }, formatter(v.x)), h(MeasurementDetailsEntry, { label: "Y", onMouseEnter: () => onShowOverlay(overlays === null || overlays === void 0 ? void 0 : overlays.addDistanceVectorFromResult(result)), onMouseLeave: onHideOverlay }, formatter(v.y)), h(MeasurementDetailsEntry, { label: "Z", onMouseEnter: () => onShowOverlay(overlays === null || overlays === void 0 ? void 0 : overlays.addDistanceVectorFromResult(result)), onMouseLeave: onHideOverlay }, formatter(v.z))));
};
const PlanarAngleResultEntry = ({ result, formatter }) => {
    return (h(MeasurementDetailsEntry, { label: "Angle" }, formatter(result.angle)));
};
const PlanarDistanceResultEntry = ({ result, formatter }) => {
    return (h(MeasurementDetailsEntry, { label: "Parallel Dist" }, formatter(result.distance)));
};
const SurfaceAreaResultEntry = ({ result, formatter }) => {
    return (h(MeasurementDetailsEntry, { label: "Area" }, formatter(result.area)));
};

const viewerMeasurementDetailsCss = () => `:host{display:flex;flex-direction:column;--viewer-measurement-details-x-color:red;--viewer-measurement-details-y-color:var(--green-500);--viewer-measurement-details-z-color:blue}.measurement-details-entry{display:flex;align-items:center}.measurement-details-entry-label{user-select:none;padding-right:0.25rem}.measurement-details-entry-label.x{color:var(--viewer-measurement-details-x-color)}.measurement-details-entry-label.y{color:var(--viewer-measurement-details-y-color)}.measurement-details-entry-label.z{color:var(--viewer-measurement-details-z-color)}`;

const ViewerMeasurementDetails = class {
    constructor(hostRef) {
        registerInstance(this, hostRef);
        /**
         * The unit of distance-based measurement.
         */
        this.distanceUnits = 'millimeters';
        /**
         * The unit of angle-based measurement.
         */
        this.angleUnits = 'degrees';
        /**
         * The number of fraction digits to display.
         */
        this.fractionalDigits = 2;
        this.distanceMeasurementUnits = new DistanceUnits(this.distanceUnits);
        this.angleMeasurementUnits = new AngleUnits(this.angleUnits);
        this.areaMeasurementUnits = new AreaUnits(this.distanceUnits);
        this.handleShowOverlay = (overlay) => {
            this.overlay = overlay;
        };
        this.handleHideOverlay = () => {
            var _a;
            (_a = this.overlay) === null || _a === void 0 ? void 0 : _a.dispose();
        };
        this.handleOutcomeChange = () => {
            this.updateStateFromModel();
        };
    }
    /**
     * @internal
     */
    connectedCallback() {
        var _a;
        this.onOutcomeChangedHandler = (_a = this.measurementModel) === null || _a === void 0 ? void 0 : _a.onOutcomeChanged(this.handleOutcomeChange);
        this.updateStateFromModel();
    }
    /**
     * @internal
     */
    disconnectedCallback() {
        var _a;
        (_a = this.onOutcomeChangedHandler) === null || _a === void 0 ? void 0 : _a.dispose();
    }
    /**
     * @internal
     */
    handleDistanceUnitsChanged() {
        this.distanceMeasurementUnits = new DistanceUnits(this.distanceUnits);
        this.areaMeasurementUnits = new AreaUnits(this.distanceUnits);
    }
    /**
     * @internal
     */
    handleAngleUnitsChanged() {
        this.angleMeasurementUnits = new AngleUnits(this.angleUnits);
    }
    /**
     * @internal
     */
    handleMeasurementModelChanged() {
        var _a, _b;
        (_a = this.onOutcomeChangedHandler) === null || _a === void 0 ? void 0 : _a.dispose();
        this.onOutcomeChangedHandler = (_b = this.measurementModel) === null || _b === void 0 ? void 0 : _b.onOutcomeChanged(this.handleOutcomeChange);
        this.updateStateFromModel();
    }
    /**
     * @internal
     */
    handleResultTypesChanged() {
        this.updateStateFromModel();
    }
    /**
     * @internal
     */
    render() {
        var _a, _b;
        const isFilteredResultType = (result) => {
            var _a, _b;
            return (_b = (_a = this.resultTypes) === null || _a === void 0 ? void 0 : _a.includes(result.type)) !== null && _b !== void 0 ? _b : true;
        };
        const results = ((_b = (_a = this.measurementOutcome) === null || _a === void 0 ? void 0 : _a.results) !== null && _b !== void 0 ? _b : []).filter(isFilteredResultType);
        return (h(Host, null, this.renderResult('planar-angle', results, (result) => (h(PlanarAngleResultEntry, { result: result, overlays: this.measurementOverlays, formatter: this.makeAngleFormatter(), onShowOverlay: this.handleShowOverlay, onHideOverlay: this.handleHideOverlay }))), this.renderResult('planar-distance', results, (result) => (h(PlanarDistanceResultEntry, { result: result, overlays: this.measurementOverlays, formatter: this.makeDistanceFormatter(), onShowOverlay: this.handleShowOverlay, onHideOverlay: this.handleHideOverlay }))), this.renderResult('surface-area', results, (result) => (h(SurfaceAreaResultEntry, { result: result, overlays: this.measurementOverlays, formatter: this.makeAreaFormatter(), onShowOverlay: this.handleShowOverlay, onHideOverlay: this.handleHideOverlay }))), this.renderResult('minimum-distance', results, (result) => (h(MinimumDistanceResultEntry, { result: result, overlays: this.measurementOverlays, formatter: this.makeDistanceFormatter(), onShowOverlay: this.handleShowOverlay, onHideOverlay: this.handleHideOverlay })))));
    }
    updateStateFromModel() {
        var _a;
        this.measurementOutcome = (_a = this.measurementModel) === null || _a === void 0 ? void 0 : _a.getOutcome();
    }
    renderResult(type, results, render) {
        const result = this.getResultForType(type, results);
        return result != null ? render(result) : undefined;
    }
    getResultForType(type, results) {
        return results.find((result) => result.type === type);
    }
    makeDistanceFormatter() {
        return this.makeFormatter((value) => this.distanceMeasurementUnits.convertWorldValueToReal(value), this.distanceMeasurementUnits.unit, this.distanceFormatter);
    }
    makeAngleFormatter() {
        return this.makeFormatter((value) => this.angleMeasurementUnits.convertTo(value), this.angleMeasurementUnits.unit, this.angleFormatter);
    }
    makeAreaFormatter() {
        return this.makeFormatter((value) => this.areaMeasurementUnits.convertWorldValueToReal(value), this.areaMeasurementUnits.unit, this.areaFormatter);
    }
    makeFormatter(convert, units, customFormatter) {
        return (value) => {
            const v = convert(value);
            if (customFormatter != null) {
                return customFormatter(v);
            }
            else {
                return this.formatValue(v, units);
            }
        };
    }
    formatValue(value, unit) {
        var _a, _b;
        const val = value.toFixed(this.fractionalDigits);
        const isApprox = (_b = (_a = this.measurementOutcome) === null || _a === void 0 ? void 0 : _a.isApproximate) !== null && _b !== void 0 ? _b : false;
        return `${isApprox ? '~' + val : val} ${unit.abbreviatedName}`;
    }
    static get watchers() { return {
        "distanceUnits": [{
                "handleDistanceUnitsChanged": 0
            }],
        "angleUnits": [{
                "handleAngleUnitsChanged": 0
            }],
        "measurementModel": [{
                "handleMeasurementModelChanged": 0
            }],
        "resultTypes": [{
                "handleResultTypesChanged": 0
            }]
    }; }
};
ViewerMeasurementDetails.style = viewerMeasurementDetailsCss();

export { ViewerMeasurementDetails as vertex_viewer_measurement_details };
//# sourceMappingURL=vertex-viewer-measurement-details.entry.js.map

//# sourceMappingURL=vertex-viewer-measurement-details.entry.js.map