/*!
 * Copyright (c) 2026 Vertex Software LLC. All rights reserved.
 */
import { h, Host, } from "@stencil/core";
import { VolumeIntersectionQueryController } from "../../lib/volume-intersection/controller";
import { VolumeIntersectionQueryInteractionHandler } from "../../lib/volume-intersection/interactions";
import { VolumeIntersectionQueryModel, } from "../../lib/volume-intersection/model";
/**
 * The `ViewerBoxQueryTool` allows for the drawing of a "box" on screen to represent
 * a query for items in a specific area of the viewer. This tool then allows for an
 * operation to be performed on the items contained (exclusive) by the box or both
 * contained by and intersecting with (inclusive) the box.
 */
export class ViewerBoxQueryTool {
    constructor() {
        /**
         * The default operation to perform when a drag has completed and the intersection
         * query will be run. Defaults to `clearAndSelect`, and can be changed to `select` or `deselect`.
         *
         * `clearAndSelect` will clear all existing selection, and select the results of the query.
         * `select` will maintain existing selection, and select the results of the query.
         * `deselect` will maintain existing selection, and deselect the results of the query.
         *
         * The operation behavior for this intersection query tool can also be changed by
         * providing a custom implementation of the `VolumeIntersectionQueryController`, or
         * by using the `setOperationTransform` method of the default controller.
         */
        this.operationType = 'clearAndSelect';
        this.handleScreenBoundsChanged = this.handleScreenBoundsChanged.bind(this);
        this.handleExecuteStarted = this.handleExecuteStarted.bind(this);
        this.handleExecuteComplete = this.handleExecuteComplete.bind(this);
    }
    componentWillLoad() {
        var _a;
        this.model = (_a = this.model) !== null && _a !== void 0 ? _a : new VolumeIntersectionQueryModel(this.mode);
        this.screenBoundsChangedDisposable = this.model.onScreenBoundsChanged(this.handleScreenBoundsChanged);
        this.handleViewerChanged(this.viewer);
        this.handleControllerChange(this.controller);
        this.handleDefaultOperationChange(this.operationType);
    }
    disconnectedCallback() {
        var _a, _b, _c, _d;
        (_a = this.model) === null || _a === void 0 ? void 0 : _a.reset();
        (_b = this.screenBoundsChangedDisposable) === null || _b === void 0 ? void 0 : _b.dispose();
        (_c = this.operationStartedDisposable) === null || _c === void 0 ? void 0 : _c.dispose();
        (_d = this.operationCompleteDisposable) === null || _d === void 0 ? void 0 : _d.dispose();
        this.deregisterInteractionHandler();
    }
    /**
     * @ignore
     */
    handleViewerChanged(newViewer) {
        this.deregisterInteractionHandler();
        if (this.model != null && newViewer != null) {
            this.controller = new VolumeIntersectionQueryController(this.model, newViewer);
            this.handleDefaultOperationChange(this.operationType);
            this.registerInteractionHandler(this.controller, newViewer);
        }
    }
    /**
     * @ignore
     */
    handleDefaultOperationChange(updatedOperationType) {
        switch (updatedOperationType) {
            case 'clearAndSelect':
                this.setDefaultClearAndSelectOperation();
                break;
            case 'select':
                this.setDefaultSelectOperation();
                break;
            case 'deselect':
                this.setDefaultDeselectOperation();
                break;
        }
    }
    /**
     * @ignore
     */
    handleModeChange(updatedMode) {
        var _a;
        (_a = this.model) === null || _a === void 0 ? void 0 : _a.setMode(updatedMode);
    }
    /**
     * @ignore
     */
    handleControllerChange(controller) {
        var _a, _b;
        (_a = this.operationStartedDisposable) === null || _a === void 0 ? void 0 : _a.dispose();
        (_b = this.operationCompleteDisposable) === null || _b === void 0 ? void 0 : _b.dispose();
        this.operationStartedDisposable = controller === null || controller === void 0 ? void 0 : controller.onExecuteStarted(this.handleExecuteStarted);
        this.operationStartedDisposable = controller === null || controller === void 0 ? void 0 : controller.onExecuteComplete(this.handleExecuteComplete);
        this.controllerChanged.emit(this.controller);
    }
    /**
     * @ignore
     */
    render() {
        return (h(Host, { key: '52fd0844f7a089687af0de575fc24c771408f7cc' }, h("vertex-viewer-layer", { key: '9f914b377d42c4a2250629df57ea4aae8e05305e' }, this.details != null && (h("div", { key: '498adff4a807104567bf3debdee741be3d3a2dd6', class: "bounds", style: {
                left: `${this.details.screenBounds.x}px`,
                top: `${this.details.screenBounds.y}px`,
                width: `${this.details.screenBounds.width}px`,
                height: `${this.details.screenBounds.height}px`,
            } }, h("slot", { key: '56a15f3ae338a20ccf5138f6f8c9d1269f063135', name: "bounds" }, h("div", { key: '28875acaed488318990aacb3761fad930dfdf059', class: "outline" }), h("div", { key: 'e49c3189e0d1051dd66a6d54d1eff23044f7f5b7', class: "fill" })))))));
    }
    handleScreenBoundsChanged(details) {
        this.details = details;
        this.updateTypeAttribute(details === null || details === void 0 ? void 0 : details.type);
    }
    handleExecuteStarted() {
        var _a;
        (_a = this.interactionHandler) === null || _a === void 0 ? void 0 : _a.disable();
    }
    handleExecuteComplete() {
        var _a;
        (_a = this.interactionHandler) === null || _a === void 0 ? void 0 : _a.enable();
    }
    async registerInteractionHandler(controller, viewer) {
        this.interactionHandler = new VolumeIntersectionQueryInteractionHandler(controller);
        this.interactionHandlerDisposable = await viewer.registerInteractionHandler(this.interactionHandler);
    }
    deregisterInteractionHandler() {
        var _a, _b;
        (_a = this.interactionHandlerDisposable) === null || _a === void 0 ? void 0 : _a.dispose();
        (_b = this.interactionHandler) === null || _b === void 0 ? void 0 : _b.dispose();
        this.interactionHandler = undefined;
    }
    updateTypeAttribute(type) {
        this.hostEl.setAttribute('inclusive', `${type === 'inclusive'}`);
        this.hostEl.setAttribute('exclusive', `${type === 'exclusive'}`);
    }
    setDefaultClearAndSelectOperation() {
        var _a, _b;
        (_a = this.controller) === null || _a === void 0 ? void 0 : _a.setOperationTransform((builder) => builder.select());
        (_b = this.controller) === null || _b === void 0 ? void 0 : _b.setAdditionalTransforms([
            (op) => op.items.where((q) => q.withSelected()).deselect(),
        ]);
    }
    setDefaultSelectOperation() {
        var _a, _b;
        (_a = this.controller) === null || _a === void 0 ? void 0 : _a.setOperationTransform((builder) => builder.select());
        (_b = this.controller) === null || _b === void 0 ? void 0 : _b.setAdditionalTransforms([]);
    }
    setDefaultDeselectOperation() {
        var _a, _b;
        (_a = this.controller) === null || _a === void 0 ? void 0 : _a.setOperationTransform((builder) => builder.deselect());
        (_b = this.controller) === null || _b === void 0 ? void 0 : _b.setAdditionalTransforms([]);
    }
    static get is() { return "vertex-viewer-box-query-tool"; }
    static get encapsulation() { return "shadow"; }
    static get originalStyleUrls() {
        return {
            "$": ["viewer-box-query-tool.css"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["viewer-box-query-tool.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 that this component is bound to. This is automatically assigned\nif added to the light-dom of a parent viewer element."
                },
                "getter": false,
                "setter": false
            },
            "controller": {
                "type": "unknown",
                "mutable": true,
                "complexType": {
                    "original": "VolumeIntersectionQueryController",
                    "resolved": "VolumeIntersectionQueryController | undefined",
                    "references": {
                        "VolumeIntersectionQueryController": {
                            "location": "import",
                            "path": "../../lib/volume-intersection/controller",
                            "id": "src/lib/volume-intersection/controller.ts::VolumeIntersectionQueryController",
                            "referenceLocation": "VolumeIntersectionQueryController"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The controller that is responsible for performing operations using the\nvolume intersection query defined by the drawn box and updating the model."
                },
                "getter": false,
                "setter": false
            },
            "model": {
                "type": "unknown",
                "mutable": true,
                "complexType": {
                    "original": "VolumeIntersectionQueryModel",
                    "resolved": "VolumeIntersectionQueryModel | undefined",
                    "references": {
                        "VolumeIntersectionQueryModel": {
                            "location": "import",
                            "path": "../../lib/volume-intersection/model",
                            "id": "src/lib/volume-intersection/model.ts::VolumeIntersectionQueryModel",
                            "referenceLocation": "VolumeIntersectionQueryModel"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The model that contains the points representing the corners of the box\ndisplayed on screen, the type of the query to be performed, and methods\nfor setting these values."
                },
                "getter": false,
                "setter": false
            },
            "operationType": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "VolumeIntersectionQueryType",
                    "resolved": "\"clearAndSelect\" | \"deselect\" | \"select\"",
                    "references": {
                        "VolumeIntersectionQueryType": {
                            "location": "import",
                            "path": "./types",
                            "id": "src/components/viewer-box-query-tool/types.ts::VolumeIntersectionQueryType",
                            "referenceLocation": "VolumeIntersectionQueryType"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The default operation to perform when a drag has completed and the intersection\nquery will be run. Defaults to `clearAndSelect`, and can be changed to `select` or `deselect`.\n\n`clearAndSelect` will clear all existing selection, and select the results of the query.\n`select` will maintain existing selection, and select the results of the query.\n`deselect` will maintain existing selection, and deselect the results of the query.\n\nThe operation behavior for this intersection query tool can also be changed by\nproviding a custom implementation of the `VolumeIntersectionQueryController`, or\nby using the `setOperationTransform` method of the default controller."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "operation-type",
                "defaultValue": "'clearAndSelect'"
            },
            "mode": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "VolumeIntersectionQueryMode",
                    "resolved": "\"exclusive\" | \"inclusive\" | undefined",
                    "references": {
                        "VolumeIntersectionQueryMode": {
                            "location": "import",
                            "path": "./types",
                            "id": "src/components/viewer-box-query-tool/types.ts::VolumeIntersectionQueryMode",
                            "referenceLocation": "VolumeIntersectionQueryMode"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "An optional value to specify a singular mode of intersection query. This value\ndefaults to `undefined`, which will indicate that both `exclusive` and `inclusive`\nqueries should be made, with `inclusive` being represented by a left to right\ndrag behavior and `exclusive` being represented by a right to left drag.\n\nSetting this value to `inclusive` will cause dragging left to right and left to right\nto result in an `inclusive` query, and the box will only be styled for `inclusive` queries.\n\nSetting this value to `exclusive` will cause dragging left to right and left to right\nto result in an `exclusive` query, and the box will only be styled for `exclusive` queries."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "mode"
            }
        };
    }
    static get states() {
        return {
            "details": {}
        };
    }
    static get events() {
        return [{
                "method": "controllerChanged",
                "name": "controllerChanged",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Event emitted when the `VolumeIntersectionQueryController` associated with this tool changes."
                },
                "complexType": {
                    "original": "VolumeIntersectionQueryController",
                    "resolved": "VolumeIntersectionQueryController",
                    "references": {
                        "VolumeIntersectionQueryController": {
                            "location": "import",
                            "path": "../../lib/volume-intersection/controller",
                            "id": "src/lib/volume-intersection/controller.ts::VolumeIntersectionQueryController",
                            "referenceLocation": "VolumeIntersectionQueryController"
                        }
                    }
                }
            }];
    }
    static get elementRef() { return "hostEl"; }
    static get watchers() {
        return [{
                "propName": "viewer",
                "methodName": "handleViewerChanged"
            }, {
                "propName": "operationType",
                "methodName": "handleDefaultOperationChange"
            }, {
                "propName": "mode",
                "methodName": "handleModeChange"
            }, {
                "propName": "controller",
                "methodName": "handleControllerChange"
            }];
    }
}
//# sourceMappingURL=viewer-box-query-tool.js.map
