/*!
 * Copyright (c) 2026 Vertex Software LLC. All rights reserved.
 */
import { h, Host } from "@stencil/core";
import { Matrix4 } from "@vertexvis/geometry";
import { readDOM, writeDOM } from "../../lib/stencil";
import { parseCssColorValue } from "./lib/dom";
import { DEFAULT_PLANE_OPACITY, HitIndicator } from "./lib/indicator";
export class ViewerHitResultIndicator {
    constructor() {
        this.arrowColor = '#0099cc';
        this.planeColor = '#0099cc';
        this.outlineColor = '#000000';
        this.planeOpacity = DEFAULT_PLANE_OPACITY;
        this.handleViewerFrameDrawn = () => {
            this.updatePropsFromViewer();
        };
        this.handleViewerDimensionsChange = () => {
            writeDOM(() => {
                if (this.viewer != null && this.canvasRef != null) {
                    this.canvasRef.width = this.viewer.viewport.width;
                    this.canvasRef.height = this.viewer.viewport.height;
                    this.updateAndRedrawIndicator();
                }
            });
        };
        this.handleResize = () => {
            if (this.canvasRef != null) {
                this.updateAndRedrawIndicator();
            }
        };
        this.updatePropsFromViewer = () => {
            const { frame } = this.viewer || {};
            if (frame != null) {
                const widget = this.getIndicator();
                widget.updateFrame(frame);
            }
        };
        this.setupIndicator = (canvasRef) => {
            var _a, _b;
            console.debug(`Initializing hit indicator. [initial-position=${JSON.stringify(this.position)}, initial-normal=${JSON.stringify(this.normal)} has-initial-frame=${((_a = this.viewer) === null || _a === void 0 ? void 0 : _a.frame) != null}]`);
            this.indicator = new HitIndicator(canvasRef, {
                arrow: this.arrowColor,
                plane: this.planeColor,
            }, {
                plane: this.planeOpacity,
            });
            this.transform = this.createTransform();
            this.indicator.updateTransformAndNormal(this.transform, this.normal);
            if (((_b = this.viewer) === null || _b === void 0 ? void 0 : _b.frame) != null) {
                this.indicator.updateFrame(this.viewer.frame);
            }
            return this.indicator;
        };
        this.updateAndRedrawIndicator = () => {
            readDOM(() => {
                this.getIndicator().updateAndDraw();
            });
        };
        this.createTransform = () => {
            if (this.position != null) {
                return Matrix4.makeTranslation(this.position);
            }
        };
        this.getIndicator = () => {
            if (this.indicator == null && this.canvasRef != null) {
                return this.setupIndicator(this.canvasRef);
            }
            else if (this.indicator != null) {
                return this.indicator;
            }
            else {
                throw new Error('Hit indicator was not initialized. The canvas element may not have been initialized.');
            }
        };
    }
    componentDidLoad() {
        this.handleViewerChanged(this.viewer, undefined);
        this.canvasResizeObserver = new ResizeObserver(this.handleResize);
        if (this.canvasRef != null) {
            this.canvasResizeObserver.observe(this.canvasRef);
            this.setupIndicator(this.canvasRef);
        }
        readDOM(() => {
            var _a, _b;
            const hostStyles = window.getComputedStyle(this.hostEl);
            this.arrowColor = parseCssColorValue(hostStyles, '--viewer-hit-result-indicator-arrow-color');
            this.planeColor = parseCssColorValue(hostStyles, '--viewer-hit-result-indicator-plane-color');
            this.outlineColor = parseCssColorValue(hostStyles, '--viewer-hit-result-indicator-outline-color');
            this.planeOpacity = hostStyles
                .getPropertyValue('--viewer-hit-result-indicator-plane-opacity')
                .trim();
            (_a = this.indicator) === null || _a === void 0 ? void 0 : _a.updateColors({
                arrow: this.arrowColor,
                plane: this.planeColor,
                outline: this.outlineColor,
            });
            (_b = this.indicator) === null || _b === void 0 ? void 0 : _b.updateOpacities({
                plane: this.planeOpacity,
            });
        });
    }
    disconnectedCallback() {
        var _a, _b;
        (_a = this.canvasResizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
        (_b = this.indicator) === null || _b === void 0 ? void 0 : _b.dispose();
    }
    /**
     * @ignore
     */
    handleViewerChanged(newViewer, oldViewer) {
        oldViewer === null || oldViewer === void 0 ? void 0 : oldViewer.removeEventListener('frameDrawn', this.handleViewerFrameDrawn);
        oldViewer === null || oldViewer === void 0 ? void 0 : oldViewer.removeEventListener('dimensionschange', this.handleViewerDimensionsChange);
        newViewer === null || newViewer === void 0 ? void 0 : newViewer.addEventListener('frameDrawn', this.handleViewerFrameDrawn);
        newViewer === null || newViewer === void 0 ? void 0 : newViewer.addEventListener('dimensionschange', this.handleViewerDimensionsChange);
    }
    /**
     * @ignore
     */
    handlePositionChanged(newPosition, oldPosition) {
        var _a;
        this.transform = this.createTransform();
        console.debug(`Updating indicator position [previous=${JSON.stringify(oldPosition)}, current=${JSON.stringify(newPosition)}]`);
        (_a = this.indicator) === null || _a === void 0 ? void 0 : _a.updateTransformAndNormal(this.transform, this.normal);
    }
    handleNormalChanged(newNormal, oldNormal) {
        var _a;
        console.debug(`Updating indicator normal [previous=${JSON.stringify(oldNormal)}, current=${JSON.stringify(newNormal)}]`);
        if (newNormal) {
            (_a = this.indicator) === null || _a === void 0 ? void 0 : _a.updateTransformAndNormal(this.transform, this.normal);
        }
    }
    render() {
        var _a, _b;
        return (h(Host, { key: 'b01a77bd8351c40aa405af4c6b78b455de415a18' }, h("canvas", { key: 'bef28c167aa8f5db50e8130111d63592ba9cd4b4', ref: (el) => {
                this.canvasRef = el;
            }, class: "indicator", width: (_a = this.viewer) === null || _a === void 0 ? void 0 : _a.viewport.width, height: (_b = this.viewer) === null || _b === void 0 ? void 0 : _b.viewport.height })));
    }
    static get is() { return "vertex-viewer-hit-result-indicator"; }
    static get encapsulation() { return "shadow"; }
    static get originalStyleUrls() {
        return {
            "$": ["viewer-hit-result-indicator.css"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["viewer-hit-result-indicator.css"]
        };
    }
    static get properties() {
        return {
            "viewer": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "HTMLVertexViewerElement",
                    "resolved": "HTMLVertexViewerElement | undefined",
                    "references": {
                        "HTMLVertexViewerElement": {
                            "location": "global",
                            "id": "global::HTMLVertexViewerElement"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The viewer to connect to this indicator. If nested within a <vertex-viewer>,\nthis property will be populated automatically."
                },
                "getter": false,
                "setter": false
            },
            "position": {
                "type": "unknown",
                "mutable": true,
                "complexType": {
                    "original": "Vector3.Vector3",
                    "resolved": "Vector3 | undefined",
                    "references": {
                        "Vector3": {
                            "location": "import",
                            "path": "@vertexvis/geometry",
                            "id": "../geometry/dist/index.d.ts::\"/home/runner/work/vertex-web-sdk/vertex-web-sdk/packages/geometry/dist/vector3\"",
                            "referenceLocation": "Vector3"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The position of this indicator. A point will be displayed at this position,\nand it will be used alongside the provided `normal` to display a plane and\nnormal arrow centered at the position."
                },
                "getter": false,
                "setter": false
            },
            "normal": {
                "type": "unknown",
                "mutable": true,
                "complexType": {
                    "original": "Vector3.Vector3",
                    "resolved": "Vector3 | undefined",
                    "references": {
                        "Vector3": {
                            "location": "import",
                            "path": "@vertexvis/geometry",
                            "id": "../geometry/dist/index.d.ts::\"/home/runner/work/vertex-web-sdk/vertex-web-sdk/packages/geometry/dist/vector3\"",
                            "referenceLocation": "Vector3"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The normal of this indicator. This value will be represented as an arrow,\nand will be used alongside the provided `position` to display a plane."
                },
                "getter": false,
                "setter": false
            }
        };
    }
    static get elementRef() { return "hostEl"; }
    static get watchers() {
        return [{
                "propName": "viewer",
                "methodName": "handleViewerChanged"
            }, {
                "propName": "position",
                "methodName": "handlePositionChanged"
            }, {
                "propName": "normal",
                "methodName": "handleNormalChanged"
            }];
    }
}
//# sourceMappingURL=viewer-hit-result-indicator.js.map
