/*!
 * Copyright (c) 2026 Vertex Software LLC. All rights reserved.
 */
import { h, Host } from "@stencil/core";
import { AngleUnits, AreaUnits, DistanceUnits, } from "../../lib/types";
import { MinimumDistanceResultEntry, PlanarAngleResultEntry, PlanarDistanceResultEntry, SurfaceAreaResultEntry, } from "./viewer-measurement-details-results";
export class ViewerMeasurementDetails {
    constructor() {
        /**
         * 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 is() { return "vertex-viewer-measurement-details"; }
    static get encapsulation() { return "shadow"; }
    static get originalStyleUrls() {
        return {
            "$": ["viewer-measurement-details.css"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["viewer-measurement-details.css"]
        };
    }
    static get properties() {
        return {
            "measurementModel": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "MeasurementModel",
                    "resolved": "MeasurementModel | undefined",
                    "references": {
                        "MeasurementModel": {
                            "location": "import",
                            "path": "../../lib/measurement",
                            "id": "src/lib/measurement/index.ts::MeasurementModel",
                            "referenceLocation": "MeasurementModel"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The `MeasurementModel` that should be reflected in these details.\nIf not specified, a new `MeasurementModel` will be created,\nwhich can then be used to update the display."
                },
                "getter": false,
                "setter": false
            },
            "measurementOverlays": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "MeasurementOverlayManager",
                    "resolved": "MeasurementOverlayManager | undefined",
                    "references": {
                        "MeasurementOverlayManager": {
                            "location": "import",
                            "path": "../../lib/measurement",
                            "id": "src/lib/measurement/index.ts::MeasurementOverlayManager",
                            "referenceLocation": "MeasurementOverlayManager"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The manager that the component will use to present measurement overlays."
                },
                "getter": false,
                "setter": false
            },
            "measurementOutcome": {
                "type": "unknown",
                "mutable": true,
                "complexType": {
                    "original": "MeasurementOutcome",
                    "resolved": "MeasurementOutcome | undefined",
                    "references": {
                        "MeasurementOutcome": {
                            "location": "import",
                            "path": "../../lib/measurement",
                            "id": "src/lib/measurement/index.ts::MeasurementOutcome",
                            "referenceLocation": "MeasurementOutcome"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The outcome to display. This property is automatically updated if a\nmeasurement model is provided."
                },
                "getter": false,
                "setter": false
            },
            "distanceUnits": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "DistanceUnitType",
                    "resolved": "\"centimeters\" | \"feet\" | \"inches\" | \"meters\" | \"millimeters\" | \"yards\"",
                    "references": {
                        "DistanceUnitType": {
                            "location": "import",
                            "path": "../../lib/types",
                            "id": "src/lib/types/index.ts::DistanceUnitType",
                            "referenceLocation": "DistanceUnitType"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The unit of distance-based measurement."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "distance-units",
                "defaultValue": "'millimeters'"
            },
            "angleUnits": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "AngleUnitType",
                    "resolved": "\"degrees\" | \"radians\"",
                    "references": {
                        "AngleUnitType": {
                            "location": "import",
                            "path": "../../lib/types",
                            "id": "src/lib/types/index.ts::AngleUnitType",
                            "referenceLocation": "AngleUnitType"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The unit of angle-based measurement."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "angle-units",
                "defaultValue": "'degrees'"
            },
            "fractionalDigits": {
                "type": "number",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The number of fraction digits to display."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "fractional-digits",
                "defaultValue": "2"
            },
            "distanceFormatter": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "Formatter<number>",
                    "resolved": "number | undefined",
                    "references": {
                        "Formatter": {
                            "location": "import",
                            "path": "../../lib/formatter",
                            "id": "src/lib/formatter.ts::Formatter",
                            "referenceLocation": "Formatter"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "An optional formatter that can be used to format the display of a distance.\nThe formatting function is passed a calculated real-world distance and is\nexpected to return a string."
                },
                "getter": false,
                "setter": false
            },
            "angleFormatter": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "Formatter<number>",
                    "resolved": "number | undefined",
                    "references": {
                        "Formatter": {
                            "location": "import",
                            "path": "../../lib/formatter",
                            "id": "src/lib/formatter.ts::Formatter",
                            "referenceLocation": "Formatter"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "An optional formatter that can be used to format the display of an angle.\nThe formatting function is passed a calculated angle in degrees and is\nexpected to return a string."
                },
                "getter": false,
                "setter": false
            },
            "areaFormatter": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "Formatter<number>",
                    "resolved": "number | undefined",
                    "references": {
                        "Formatter": {
                            "location": "import",
                            "path": "../../lib/formatter",
                            "id": "src/lib/formatter.ts::Formatter",
                            "referenceLocation": "Formatter"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "An optional formatter that can be used to format the display of an area.\nThe formatting function is passed a calculated area and is\nexpected to return a string."
                },
                "getter": false,
                "setter": false
            },
            "resultTypes": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "MeasurementResult['type'][]",
                    "resolved": "(\"minimum-distance\" | \"planar-angle\" | \"planar-distance\" | \"surface-area\")[] | undefined",
                    "references": {
                        "MeasurementResult": {
                            "location": "import",
                            "path": "../../lib/measurement",
                            "id": "src/lib/measurement/index.ts::MeasurementResult",
                            "referenceLocation": "MeasurementResult"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "A set of result types to display. If `undefined`, then all results will be\ndisplayed."
                },
                "getter": false,
                "setter": false
            }
        };
    }
    static get states() {
        return {
            "overlay": {},
            "distanceMeasurementUnits": {},
            "angleMeasurementUnits": {},
            "areaMeasurementUnits": {}
        };
    }
    static get watchers() {
        return [{
                "propName": "distanceUnits",
                "methodName": "handleDistanceUnitsChanged"
            }, {
                "propName": "angleUnits",
                "methodName": "handleAngleUnitsChanged"
            }, {
                "propName": "measurementModel",
                "methodName": "handleMeasurementModelChanged"
            }, {
                "propName": "resultTypes",
                "methodName": "handleResultTypesChanged"
            }];
    }
}
//# sourceMappingURL=viewer-measurement-details.js.map
