/*!
 * Copyright (c) 2026 Vertex Software LLC. All rights reserved.
 */
import { Fragment, 
// eslint-disable-next-line @typescript-eslint/no-unused-vars
h, } from "@stencil/core";
import { Matrix4, Vector3 } from "@vertexvis/geometry";
import { Viewport } from "../..";
import { PinController } from "../../lib/pins/controller";
import { isTextPin } from "../../lib/pins/model";
import { PinModel } from "../../lib/pins/model";
import { translatePointToScreen } from "../viewer-pin-tool/utils";
import { PinRenderer } from "./pin-renderer";
import { getClosestCenterToPoint } from "./utils";
export class ViewerPinGroup {
    constructor() {
        /**
         * The local matrix of this element.
         */
        this.matrix = Matrix4.makeIdentity();
        /**
         * Projection view matrix used for computing the position of the pin line
         */
        this.projectionViewMatrix = Matrix4.makeIdentity();
        /**
         * The model that contains the entities and outcomes from performing pin operations
         */
        this.pinModel = new PinModel();
        /**
         * Whether the pin is "selected"
         */
        this.selected = false;
        /**
         * @internal
         * Whether the pin is occluded
         */
        this.occluded = false;
        /**
         * @internal
         * Whether the pin is detached
         */
        this.detached = false;
        this.invalidateStateCounter = 0;
        this.invalidateState = () => {
            this.invalidateStateCounter = this.invalidateStateCounter + 1;
        };
    }
    componentDidLoad() {
        var _a;
        this.setLabelObserver();
        if (this.pinController == null) {
            this.pinController = new PinController(this.pinModel);
        }
        if (this.selected) {
            (_a = this.labelEl) === null || _a === void 0 ? void 0 : _a.setFocus();
        }
    }
    /**
     * @ignore
     */
    async handleOcclusionStateChanged(event) {
        this.occluded = event.detail;
    }
    /**
     * @ignore
     */
    async handleDetachedStateChanged(event) {
        this.detached = event.detail;
    }
    disconnectedCallback() {
        var _a, _b;
        (_a = this.labelEl) === null || _a === void 0 ? void 0 : _a.removeEventListener('labelChanged', this.invalidateState);
        (_b = this.resizeObserver) === null || _b === void 0 ? void 0 : _b.disconnect();
    }
    render() {
        var _a;
        if (this.pin == null) {
            throw new Error('Unable to draw pin');
        }
        const { pinPoint, labelPoint } = this.computePinPoints(this.pin);
        return (h(Fragment, { key: 'b26f95c0e4b86b263eca80c5db8576ef1c787b26' }, h("vertex-viewer-dom-element", { key: '9fcb9d0f55f9abb3397db4051ed59c7a05d4ae6a', "data-testid": `drawn-pin-${this.pin.id}`, position: this.pin.worldPosition, onPointerDown: async () => {
                var _a;
                await ((_a = this.labelEl) === null || _a === void 0 ? void 0 : _a.submit());
                this.selectPin();
                this.handleAnchorPointerDown();
            }, detachedOff: false }, h(PinRenderer, { key: '2264652f4c83539f47af324f6937fb6581edafe1', pin: this.pin, selected: this.selected, occluded: this.occluded, detached: this.detached })), isTextPin(this.pin) && !this.occluded && !this.detached && (h(Fragment, { key: '04c86f573b99fb320b0a651dc903131e6654bd9e' }, h("vertex-viewer-pin-label-line", { key: 'cec6ee8195fba5fadd9e1b272abd61b6b6dd05c6', id: `pin-label-line-${(_a = this.pin) === null || _a === void 0 ? void 0 : _a.id}`, pinPoint: pinPoint, pin: this.pin, labelPoint: labelPoint, onPointerDown: () => this.selectPin() }), h("vertex-viewer-pin-label", { key: '556a36ac8e9046b0e40c6973c1ecf47319f28ab6', pin: this.pin, ref: (el) => (this.labelEl = el), elementBounds: this.elementBounds, pinController: this.pinController, onPointerDown: () => this.selectPin() })))));
    }
    setLabelObserver() {
        if (this.labelEl != null) {
            this.labelEl.addEventListener('labelChanged', this.invalidateState);
            this.resizeObserver = new ResizeObserver(() => this.invalidateState());
            this.resizeObserver.observe(this.labelEl);
        }
    }
    computePinPoints(pin) {
        if (this.elementBounds != null && this.pin != null) {
            return isTextPin(this.pin) && this.pin.label.point != null
                ? this.computeTextPinPoints(this.pin, this.elementBounds)
                : this.computeDefaultPinPoints(this.pin, this.elementBounds);
        }
        return { pinPoint: pin.worldPosition };
    }
    computeDefaultPinPoints(pin, elementBounds) {
        return {
            pinPoint: this.getFromWorldPosition(pin.worldPosition, this.projectionViewMatrix, elementBounds),
        };
    }
    computeTextPinPoints(pin, elementBounds) {
        var _a, _b, _c, _d;
        const { pinPoint } = this.computeDefaultPinPoints(pin, elementBounds);
        const screenPosition = translatePointToScreen(pin.label.point, elementBounds);
        const labelWidth = ((_b = (_a = this.labelEl) === null || _a === void 0 ? void 0 : _a.firstElementChild) === null || _b === void 0 ? void 0 : _b.clientWidth) || 0;
        const labelHeight = ((_d = (_c = this.labelEl) === null || _c === void 0 ? void 0 : _c.firstElementChild) === null || _d === void 0 ? void 0 : _d.clientHeight) || 0;
        return {
            pinPoint,
            labelPoint: getClosestCenterToPoint(screenPosition, pinPoint, {
                width: labelWidth,
                height: labelHeight,
            }),
        };
    }
    handleAnchorPointerDown() {
        var _a, _b;
        if (this.elementBounds != null &&
            ((_a = this.pinController) === null || _a === void 0 ? void 0 : _a.getToolMode()) === 'edit' &&
            this.pin != null) {
            (_b = this.pinController) === null || _b === void 0 ? void 0 : _b.setDraggable({ id: this.pin.id });
        }
    }
    selectPin() {
        var _a, _b;
        (_a = this.pinController) === null || _a === void 0 ? void 0 : _a.setSelectedPinId((_b = this.pin) === null || _b === void 0 ? void 0 : _b.id);
    }
    getFromWorldPosition(pt, projectionViewMatrix, dimensions) {
        const ndcPt = Vector3.transformMatrix(pt, projectionViewMatrix);
        return Viewport.fromDimensions(dimensions).transformVectorToViewport(ndcPt);
    }
    static get is() { return "vertex-viewer-pin-group"; }
    static get originalStyleUrls() {
        return {
            "$": ["viewer-pin-group.css"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["viewer-pin-group.css"]
        };
    }
    static get properties() {
        return {
            "pin": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "Pin",
                    "resolved": "IconPin | TextPin | undefined",
                    "references": {
                        "Pin": {
                            "location": "import",
                            "path": "../../lib/pins/model",
                            "id": "src/lib/pins/model.ts::Pin",
                            "referenceLocation": "Pin"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The pin to draw for the group"
                },
                "getter": false,
                "setter": false
            },
            "matrix": {
                "type": "unknown",
                "mutable": true,
                "complexType": {
                    "original": "Matrix4.Matrix4",
                    "resolved": "[number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number]",
                    "references": {
                        "Matrix4": {
                            "location": "import",
                            "path": "@vertexvis/geometry",
                            "id": "../geometry/dist/index.d.ts::\"/home/runner/work/vertex-web-sdk/vertex-web-sdk/packages/geometry/dist/matrix4\"",
                            "referenceLocation": "Matrix4"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The local matrix of this element."
                },
                "getter": false,
                "setter": false,
                "defaultValue": "Matrix4.makeIdentity()"
            },
            "projectionViewMatrix": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "Matrix4.Matrix4",
                    "resolved": "[number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number]",
                    "references": {
                        "Matrix4": {
                            "location": "import",
                            "path": "@vertexvis/geometry",
                            "id": "../geometry/dist/index.d.ts::\"/home/runner/work/vertex-web-sdk/vertex-web-sdk/packages/geometry/dist/matrix4\"",
                            "referenceLocation": "Matrix4"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Projection view matrix used for computing the position of the pin line"
                },
                "getter": false,
                "setter": false,
                "defaultValue": "Matrix4.makeIdentity()"
            },
            "elementBounds": {
                "type": "unknown",
                "mutable": true,
                "complexType": {
                    "original": "DOMRect",
                    "resolved": "DOMRect | undefined",
                    "references": {
                        "DOMRect": {
                            "location": "global",
                            "id": "global::DOMRect"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The dimensions of the canvas for the pins"
                },
                "getter": false,
                "setter": false
            },
            "pinModel": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "PinModel",
                    "resolved": "PinModel",
                    "references": {
                        "PinModel": {
                            "location": "import",
                            "path": "../../lib/pins/model",
                            "id": "src/lib/pins/model.ts::PinModel",
                            "referenceLocation": "PinModel"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The model that contains the entities and outcomes from performing pin operations"
                },
                "getter": false,
                "setter": false,
                "defaultValue": "new PinModel()"
            },
            "pinController": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "PinController",
                    "resolved": "PinController | undefined",
                    "references": {
                        "PinController": {
                            "location": "import",
                            "path": "../../lib/pins/controller",
                            "id": "src/lib/pins/controller.ts::PinController",
                            "referenceLocation": "PinController"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The controller that drives behavior for pin operations"
                },
                "getter": false,
                "setter": false
            },
            "selected": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Whether the pin is \"selected\""
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "selected",
                "defaultValue": "false"
            },
            "occluded": {
                "type": "boolean",
                "mutable": true,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "internal",
                            "text": "Whether the pin is occluded"
                        }],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "occluded",
                "defaultValue": "false"
            },
            "detached": {
                "type": "boolean",
                "mutable": true,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "internal",
                            "text": "Whether the pin is detached"
                        }],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "detached",
                "defaultValue": "false"
            }
        };
    }
    static get states() {
        return {
            "invalidateStateCounter": {}
        };
    }
    static get listeners() {
        return [{
                "name": "occlusionStateChanged",
                "method": "handleOcclusionStateChanged",
                "target": undefined,
                "capture": false,
                "passive": false
            }, {
                "name": "detachedStateChanged",
                "method": "handleDetachedStateChanged",
                "target": undefined,
                "capture": false,
                "passive": false
            }];
    }
}
//# sourceMappingURL=viewer-pin-group.js.map
