/*!
 * Copyright (c) 2026 Vertex Software LLC. All rights reserved.
 */
'use strict';

var index = require('./index-C_J7n4Dv.js');
var scene_view_api_pb_service = require('./scene_view_api_pb_service-DYpTDhrh.js');
var config = require('./config-DTM7F1sm.js');
var entities = require('./entities-C1pFrpRu.js');
require('./bundle-Dsc8KJRQ.js');
require('./geometry_pb-C1IfJb14.js');
require('./wrappers_pb-Dupo3Hcb.js');
require('./streamAttributes-ce88H9XR.js');
var model = require('./model-CNYtD2Ho.js');
var overlays = require('./overlays-CxiJArpE.js');
var bundle = require('./bundle-BhTmftd-.js');
var cursors = require('./cursors-BjfBRMe4.js');
var dom = require('./dom-CXWXs9Hx.js');
var elementRectObserver = require('./elementRectObserver-BobgIEu6.js');
var entities$1 = require('./entities-BhIrCJqA.js');
require('./wrappers_pb-DCb8h8QZ.js');
require('./_commonjsHelpers-CBbBosIU.js');
require('./bundle-96sYCpzz.js');
require('./events-8W8yXGxn.js');
require('./grpc-BsWFEUrc.js');

class MeasurementInteractionHandler {
    get elementRect() {
        return this.rectObserver.rect;
    }
    constructor(controller, measurableEntityTypes) {
        this.rectObserver = new elementRectObserver.ElementRectObserver();
        this.handlePointerMove = async (event) => {
            if (await this.isMeasurableEntityUnderPointer(event)) {
                this.clearCursor();
                this.addCursor(cursors.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 = dom.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 = dom.getMouseClientPosition(event, this.elementRect);
            const [hit] = await api.hitItems(pt);
            const entity = hit != null ? entities.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 = bundle.point.create(event.clientX, event.clientY);
        let didInteract = false;
        const handleMouseMove = (event) => {
            const pos = bundle.point.create(event.clientX, event.clientY);
            const dis = bundle.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) {
        index.registerInstance(this, hostRef);
        /**
         * The model that contains the entities and outcomes from performing precise
         * measurements.
         */
        this.measurementModel = new model.MeasurementModel();
        /**
         * The manager that is responsible for measurement overlays to present by this
         * component.
         */
        this.measurementOverlays = new overlays.MeasurementOverlayManager();
        /**
         * @internal
         *
         * An internal property that can be used to opt-in to performing measurements
         * on other types of entities.
         */
        this.measurableEntityTypes = [
            entities$1.EntityType.PRECISE_SURFACE,
            entities$1.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 (index.h(index.Host, { key: '2113569601821e742598eae47086b8bbd9198257' }, index.h("vertex-viewer-measurement-overlays", { key: 'd5ad40dd490ee2f6e1bddf5190c08907d706e0b9', viewer: this.viewer, measurementOverlays: this.measurementOverlays })));
    }
    setupController() {
        var _a;
        const config$1 = config.parseAndValidateConfig(this.configEnv, this.config);
        const client = new scene_view_api_pb_service.scene_view_api_pb_serviceExports.SceneViewAPIClient(config$1.network.sceneViewHost);
        this.measurementController = new entities.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();

exports.vertex_viewer_measurement_precise = ViewerMeasurementPrecise;
//# sourceMappingURL=vertex-viewer-measurement-precise.entry.cjs.js.map

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