/*!
 * Copyright (c) 2026 Vertex Software LLC. All rights reserved.
 */
import { r as registerInstance, h, H as Host } from './index-EpnuuCxl.js';
import { s as scene_view_api_pb_serviceExports } from './scene_view_api_pb_service-DiyuPrHM.js';
import { p as parseAndValidateConfig } from './config-CfTifCEz.js';
import { a as MeasurementEntity, M as MeasurementController } from './entities-DUXv_nvW.js';
import './bundle-CLE0fYge.js';
import './geometry_pb-BPrLQ_K_.js';
import './wrappers_pb-aFAwKqIf.js';
import './streamAttributes-B6xi3kRV.js';
import { M as MeasurementModel } from './model-D1YLEyZC.js';
import { M as MeasurementOverlayManager } from './overlays-BlZ9sQii.js';
import { p as point } from './bundle-DfdVaPrt.js';
import { a as measurementWithArrowCursor } from './cursors-DImFnILd.js';
import { g as getMouseClientPosition } from './dom-D6my8OyX.js';
import { E as ElementRectObserver } from './elementRectObserver-CFus3r7d.js';
import { E as EntityType } from './entities-BAhfr1Nx.js';
import './wrappers_pb-Xw_x1jYm.js';
import './_commonjsHelpers-CG9AChtV.js';
import './bundle-DLfw87TV.js';
import './events-CPk-nchx.js';
import './grpc-CZAYqbTu.js';

class MeasurementInteractionHandler {
    get elementRect() {
        return this.rectObserver.rect;
    }
    constructor(controller, measurableEntityTypes) {
        this.rectObserver = new ElementRectObserver();
        this.handlePointerMove = async (event) => {
            if (await this.isMeasurableEntityUnderPointer(event)) {
                this.clearCursor();
                this.addCursor(measurementWithArrowCursor);
            }
            else {
                this.clearCursor();
            }
        };
        this.handlePointerDown = (event) => {
            this.ifNoInteraction(event, async () => {
                if (await this.isMeasurableEntityUnderPointer(event)) {
                    this.measureEntityUnderPointer(event);
                }
                else {
                    await this.controller.clearEntities();
                }
            });
        };
        this.controller = controller;
        this.measurableEntityTypes = measurableEntityTypes;
    }
    initialize(element, api) {
        this.element = element;
        this.api = api;
        this.rectObserver.observe(element);
        element.addEventListener('pointermove', this.handlePointerMove);
        element.addEventListener('pointerdown', this.handlePointerDown);
    }
    dispose() {
        var _a, _b, _c;
        this.rectObserver.disconnect();
        (_a = this.measurementInteraction) === null || _a === void 0 ? void 0 : _a.dispose();
        this.clearCursor();
        (_b = this.element) === null || _b === void 0 ? void 0 : _b.removeEventListener('pointermove', this.handlePointerMove);
        (_c = this.element) === null || _c === void 0 ? void 0 : _c.removeEventListener('pointerdown', this.handlePointerDown);
        this.element = undefined;
        this.api = undefined;
    }
    addCursor(cursor) {
        this.cursor = this.ifInitialized(({ api }) => api.addCursor(cursor));
    }
    clearCursor() {
        var _a;
        (_a = this.cursor) === null || _a === void 0 ? void 0 : _a.dispose();
        this.cursor = undefined;
    }
    async isMeasurableEntityUnderPointer(event) {
        var _a;
        const pt = getMouseClientPosition(event, this.elementRect);
        const type = await ((_a = this.api) === null || _a === void 0 ? void 0 : _a.getEntityTypeAtPoint(pt));
        return type != null && this.measurableEntityTypes.includes(type);
    }
    measureEntityUnderPointer(event) {
        this.ifInitialized(async ({ api }) => {
            const pt = getMouseClientPosition(event, this.elementRect);
            const [hit] = await api.hitItems(pt);
            const entity = hit != null ? MeasurementEntity.fromHit(hit) : undefined;
            if (entity != null) {
                await this.controller.addEntity(entity);
            }
            else {
                await this.controller.clearEntities();
            }
        });
    }
    ifInitialized(f) {
        if (this.element != null && this.api != null) {
            return f({ element: this.element, api: this.api });
        }
        else {
            throw new Error('Measurement interaction handler not initialized.');
        }
    }
    ifNoInteraction(event, f) {
        const startPos = point.create(event.clientX, event.clientY);
        let didInteract = false;
        const handleMouseMove = (event) => {
            const pos = point.create(event.clientX, event.clientY);
            const dis = point.distance(startPos, pos);
            didInteract = dis > 2;
        };
        const handleMouseUp = () => {
            window.removeEventListener('pointermove', handleMouseMove);
            window.removeEventListener('pointerup', handleMouseUp);
            if (!didInteract) {
                f();
            }
        };
        window.addEventListener('pointermove', handleMouseMove);
        window.addEventListener('pointerup', handleMouseUp);
    }
}

const viewerMeasurementPreciseCss = () => `:host{display:block;position:absolute;top:0;bottom:0;left:0;right:0;pointer-events:none}`;

const ViewerMeasurementPrecise = class {
    constructor(hostRef) {
        registerInstance(this, hostRef);
        /**
         * The model that contains the entities and outcomes from performing precise
         * measurements.
         */
        this.measurementModel = new MeasurementModel();
        /**
         * The manager that is responsible for measurement overlays to present by this
         * component.
         */
        this.measurementOverlays = new MeasurementOverlayManager();
        /**
         * @internal
         *
         * An internal property that can be used to opt-in to performing measurements
         * on other types of entities.
         */
        this.measurableEntityTypes = [
            EntityType.PRECISE_SURFACE,
            EntityType.IMPRECISE_SURFACE,
        ];
        /**
         * The environment that will be used to request measurement results.
         */
        this.configEnv = 'platprod';
    }
    /**
     * @ignore
     */
    connectedCallback() {
        this.setupInteractionHandler();
    }
    /**
     * @ignore
     */
    componentWillLoad() {
        this.setupController();
        this.setupInteractionHandler();
    }
    /**
     * @ignore
     */
    disconnectedCallback() {
        this.clearInteractionHandler();
    }
    /**
     * @ignore
     */
    handleMeasurableEntityTypesChanged() {
        this.setupInteractionHandler();
    }
    /**
     * @ignore
     */
    handleMeasurementControllerChanged() {
        this.setupInteractionHandler();
    }
    /**
     * @ignore
     */
    handleMeasurementModelChanged() {
        this.setupController();
    }
    /**
     * @ignore
     */
    handleViewerChanged() {
        this.setupInteractionHandler();
    }
    /**
     * @ignore
     */
    render() {
        return (h(Host, { key: '2113569601821e742598eae47086b8bbd9198257' }, h("vertex-viewer-measurement-overlays", { key: 'd5ad40dd490ee2f6e1bddf5190c08907d706e0b9', viewer: this.viewer, measurementOverlays: this.measurementOverlays })));
    }
    setupController() {
        var _a;
        const config = parseAndValidateConfig(this.configEnv, this.config);
        const client = new scene_view_api_pb_serviceExports.SceneViewAPIClient(config.network.sceneViewHost);
        this.measurementController = new MeasurementController(this.measurementModel, client, () => { var _a; return (_a = this.viewer) === null || _a === void 0 ? void 0 : _a.token; }, (_a = this.viewer) === null || _a === void 0 ? void 0 : _a.deviceId);
    }
    clearInteractionHandler() {
        var _a;
        (_a = this.registeredInteractionHandler) === null || _a === void 0 ? void 0 : _a.then((handler) => handler.dispose());
        this.registeredInteractionHandler = undefined;
    }
    setupInteractionHandler() {
        var _a;
        this.clearInteractionHandler();
        if (this.measurementController != null) {
            this.registeredInteractionHandler =
                (_a = this.viewer) === null || _a === void 0 ? void 0 : _a.registerInteractionHandler(new MeasurementInteractionHandler(this.measurementController, this.measurableEntityTypes));
        }
    }
    static get watchers() { return {
        "measurableEntityTypes": [{
                "handleMeasurableEntityTypesChanged": 0
            }],
        "measurementController": [{
                "handleMeasurementControllerChanged": 0
            }],
        "measurementModel": [{
                "handleMeasurementModelChanged": 0
            }],
        "viewer": [{
                "handleViewerChanged": 0
            }]
    }; }
};
ViewerMeasurementPrecise.style = viewerMeasurementPreciseCss();

export { ViewerMeasurementPrecise as vertex_viewer_measurement_precise };
//# sourceMappingURL=vertex-viewer-measurement-precise.entry.js.map

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