/*!
 * Copyright (c) 2026 Vertex Software LLC. All rights reserved.
 */
import { h, Host, } from "@stencil/core";
import { stampTemplateWithId } from "../../lib/templates";
import { ArrowMarkup, CircleMarkup, FreeformMarkup, } from "../../lib/types/markup";
import { isVertexViewerArrowMarkup, } from "../viewer-markup-arrow/utils";
import { isVertexViewerCircleMarkup } from "../viewer-markup-circle/utils";
import { isVertexViewerFreeformMarkup } from "../viewer-markup-freeform/utils";
export class ViewerMarkupTool {
    constructor() {
        /**
         * The type of markup.
         *
         * This property will automatically be set when a child of a
         * `<vertex-viewer-markup>` element.
         */
        this.tool = 'arrow';
        /**
         * Disables markups.
         *
         * This property will automatically be set when a child of a
         * `<vertex-viewer-markup>` element.
         */
        this.disabled = false;
        /**
         * The style of the starting anchor. This defaults to none.
         */
        this.startLineAnchorStyle = 'none';
        /**
         * The style of the ending anchor. This defaults to 'arrow-triangle.'
         */
        this.endLineAnchorStyle = 'arrow-triangle';
        /**
         * Defines the behavior of the provided markup when the originating viewport is smaller
         * than the current viewport, or is scaled to a size smaller than the current viewport
         * using the `scale` property.
         *
         * Options:
         * - `x-only`: Markup will be centered horizontally, but not vertically.
         * - `y-only`: Markup will be centered vertically, but not horizontally.
         * - `both`: Markup will be centered both horizontally and vertically.
         * - `none`: Markup will not be centered (default).
         */
        this.centeringBehavior = 'none';
        /**
         * The scale to render this markup at. This value is used to scale the element's bounds
         * along with any `offset` to determine the final computed coordinates.
         *
         * When provided, all computed coordinates will be scaled by this amount.
         */
        this.scale = 1;
        /**
         * Captures internal state that you want to preserve across dev refreshes, but
         * don't want to trigger a render when the state changes.
         */
        this.stateMap = {};
        this.handleMarkupInteractionBegin = () => {
            this.markupBegin.emit();
        };
        this.handleMarkupInteractionEnd = () => {
            const { markupElement } = this.stateMap;
            if (isVertexViewerFreeformMarkup(markupElement)) {
                const { points, bounds } = markupElement;
                if (points != null && points.length > 0 && bounds != null) {
                    this.markupEnd.emit(new FreeformMarkup({ points, bounds }));
                }
            }
            else if (isVertexViewerCircleMarkup(markupElement)) {
                const { bounds } = markupElement;
                if (bounds != null) {
                    this.markupEnd.emit(new CircleMarkup({ bounds }));
                }
            }
            else if (isVertexViewerArrowMarkup(markupElement)) {
                const { start, end } = markupElement;
                if (start != null && end != null) {
                    this.markupEnd.emit(new ArrowMarkup({ start, end }));
                }
            }
        };
    }
    async handleViewerChanged() {
        if (this.stateMap.markupElement != null) {
            this.stateMap.markupElement.viewer = this.viewer;
        }
    }
    /**
     * @ignore
     */
    handlePropertyChanged() {
        this.updateMarkupElement();
    }
    handleScalingConfigurationChanged() {
        this.updateMarkupElement();
    }
    /**
     * @ignore
     */
    componentDidLoad() {
        this.updateMarkupElement();
    }
    /**
     * Resets the state of the internally managed markup element
     * to allow for creating a new markup. This state is automatically
     * managed when this element is placed as a child of a
     * `<vertex-viewer-markup>` element.
     */
    async reset() {
        const { markupElement } = this.stateMap;
        if (isVertexViewerFreeformMarkup(markupElement)) {
            markupElement.points = undefined;
            markupElement.bounds = undefined;
            markupElement.mode = 'create';
        }
        else if (isVertexViewerCircleMarkup(markupElement)) {
            markupElement.bounds = undefined;
            markupElement.mode = 'create';
        }
        else if (isVertexViewerArrowMarkup(markupElement)) {
            markupElement.start = undefined;
            markupElement.end = undefined;
            markupElement.mode = 'create';
        }
    }
    /**
     * @ignore
     */
    render() {
        if (!this.disabled) {
            if (this.tool === 'arrow' ||
                this.tool === 'circle' ||
                this.tool === 'freeform') {
                return (h(Host, null, h("slot", null)));
            }
            else {
                return h(Host, null, `Unsupported tool type '${this.tool}'.`);
            }
        }
        else {
            return h(Host, null);
        }
    }
    createArrowMarkupElement() {
        if (this.arrowTemplateId != null) {
            const element = stampTemplateWithId(window.document.body, this.arrowTemplateId, isVertexViewerArrowMarkup, () => console.warn(`Arrow template with ID ${this.arrowTemplateId} not found. Using default arrow element.`), () => console.warn(`Arrow template does not contain a vertex-viewer-markup-arrow. Using default arrow element.`));
            if (element != null) {
                return element;
            }
        }
        return document.createElement('vertex-viewer-markup-arrow');
    }
    createCircleMarkupElement() {
        if (this.circleTemplateId != null) {
            const element = stampTemplateWithId(window.document.body, this.circleTemplateId, isVertexViewerCircleMarkup, () => console.warn(`Circle template with ID ${this.circleTemplateId} not found. Using default circle element.`), () => console.warn(`Circle template does not contain a vertex-viewer-markup-circle. Using default circle element.`));
            if (element != null) {
                return element;
            }
        }
        return document.createElement('vertex-viewer-markup-circle');
    }
    createFreeformMarkupElement() {
        if (this.freeformTemplateId != null) {
            const element = stampTemplateWithId(window.document.body, this.freeformTemplateId, isVertexViewerFreeformMarkup, () => console.warn(`Freeform template with ID ${this.freeformTemplateId} not found. Using default freeform element.`), () => console.warn(`Freeform template does not contain a vertex-viewer-markup-freeform. Using default freeform element.`));
            if (element != null) {
                return element;
            }
        }
        return document.createElement('vertex-viewer-markup-freeform');
    }
    createNewMarkupElement() {
        switch (this.tool) {
            case 'arrow':
                return this.createArrowMarkupElement();
            case 'circle':
                return this.createCircleMarkupElement();
            case 'freeform':
                return this.createFreeformMarkupElement();
        }
    }
    updateMarkupElement() {
        const { markupElement } = this.stateMap;
        if (markupElement != null) {
            markupElement.remove();
            markupElement.dispose();
            markupElement.viewer = undefined;
            markupElement.removeEventListener('interactionBegin', this.handleMarkupInteractionBegin);
            markupElement.removeEventListener('interactionEnd', this.handleMarkupInteractionEnd);
        }
        if (!this.disabled) {
            const newMarkupElement = this.createNewMarkupElement();
            this.hostEl.append(newMarkupElement);
            if (this.tool === 'arrow') {
                newMarkupElement.startLineAnchorStyle = this.startLineAnchorStyle;
                newMarkupElement.endLineAnchorStyle = this.endLineAnchorStyle;
            }
            newMarkupElement.mode = 'create';
            newMarkupElement.viewer = this.viewer;
            newMarkupElement.originatingViewport = this.originatingViewport;
            newMarkupElement.centeringBehavior = this.centeringBehavior;
            newMarkupElement.offset = this.offset;
            newMarkupElement.scale = this.scale;
            newMarkupElement.addEventListener('interactionBegin', this.handleMarkupInteractionBegin);
            newMarkupElement.addEventListener('interactionEnd', this.handleMarkupInteractionEnd);
            this.stateMap.markupElement = newMarkupElement;
        }
    }
    static get is() { return "vertex-viewer-markup-tool"; }
    static get encapsulation() { return "shadow"; }
    static get originalStyleUrls() {
        return {
            "$": ["viewer-markup-tool.css"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["viewer-markup-tool.css"]
        };
    }
    static get properties() {
        return {
            "arrowTemplateId": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "An HTML template that describes the HTML to use for new arrow\nmarkup. It's expected that the template contains a\n`<vertex-viewer-markup-arrow>`."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "arrow-template-id"
            },
            "circleTemplateId": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "An HTML template that describes the HTML to use for new circle\nmarkup. It's expected that the template contains a\n`<vertex-viewer-markup-circle>`."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "circle-template-id"
            },
            "freeformTemplateId": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "An HTML template that describes the HTML to use for new freeform\nmarkup. It's expected that the template contains a\n`<vertex-viewer-markup-freeform>`."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "freeform-template-id"
            },
            "tool": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "ViewerMarkupToolType",
                    "resolved": "\"arrow\" | \"circle\" | \"freeform\"",
                    "references": {
                        "ViewerMarkupToolType": {
                            "location": "local",
                            "path": "/home/runner/work/vertex-web-sdk/vertex-web-sdk/packages/viewer/src/components/viewer-markup-tool/viewer-markup-tool.tsx",
                            "id": "src/components/viewer-markup-tool/viewer-markup-tool.tsx::ViewerMarkupToolType"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The type of markup.\n\nThis property will automatically be set when a child of a\n`<vertex-viewer-markup>` element."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "tool",
                "defaultValue": "'arrow'"
            },
            "disabled": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Disables markups.\n\nThis property will automatically be set when a child of a\n`<vertex-viewer-markup>` element."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "disabled",
                "defaultValue": "false"
            },
            "viewer": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "BasicViewer",
                    "resolved": "BasicViewer | undefined",
                    "references": {
                        "BasicViewer": {
                            "location": "import",
                            "path": "@vertexvis/utils",
                            "id": "../utils/dist/index.d.ts::BasicViewer",
                            "referenceLocation": "BasicViewer"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The viewer to connect to markup.\n\nThis property will automatically be set when a child of a\n`<vertex-viewer-markup>` or `<vertex-viewer>` element."
                },
                "getter": false,
                "setter": false
            },
            "startLineAnchorStyle": {
                "type": "string",
                "mutable": true,
                "complexType": {
                    "original": "LineAnchorStyle",
                    "resolved": "\"arrow-line\" | \"arrow-triangle\" | \"dot\" | \"hash\" | \"none\"",
                    "references": {
                        "LineAnchorStyle": {
                            "location": "import",
                            "path": "../viewer-markup-arrow/utils",
                            "id": "src/components/viewer-markup-arrow/utils.ts::LineAnchorStyle",
                            "referenceLocation": "LineAnchorStyle"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The style of the starting anchor. This defaults to none."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "start-line-anchor-style",
                "defaultValue": "'none'"
            },
            "endLineAnchorStyle": {
                "type": "string",
                "mutable": true,
                "complexType": {
                    "original": "LineAnchorStyle",
                    "resolved": "\"arrow-line\" | \"arrow-triangle\" | \"dot\" | \"hash\" | \"none\"",
                    "references": {
                        "LineAnchorStyle": {
                            "location": "import",
                            "path": "../viewer-markup-arrow/utils",
                            "id": "src/components/viewer-markup-arrow/utils.ts::LineAnchorStyle",
                            "referenceLocation": "LineAnchorStyle"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The style of the ending anchor. This defaults to 'arrow-triangle.'"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "end-line-anchor-style",
                "defaultValue": "'arrow-triangle'"
            },
            "originatingViewport": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "Dimensions.Dimensions",
                    "resolved": "Dimensions | undefined",
                    "references": {
                        "Dimensions": {
                            "location": "import",
                            "path": "@vertexvis/geometry",
                            "id": "../geometry/dist/index.d.ts::\"/home/runner/work/vertex-web-sdk/vertex-web-sdk/packages/geometry/dist/dimensions\"",
                            "referenceLocation": "Dimensions"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The original viewport dimensions where this markup was created. This value is used\nto determine where the markup should be rendered relative to the current viewport,\nenabling some markup to appear \"off-screen\".\n\nWhen provided, all NDC values will be considered relative to this viewport."
                },
                "getter": false,
                "setter": false
            },
            "centeringBehavior": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "MarkupCenteringBehavior",
                    "resolved": "\"both\" | \"none\" | \"x-only\" | \"y-only\"",
                    "references": {
                        "MarkupCenteringBehavior": {
                            "location": "import",
                            "path": "../../lib/types/markup",
                            "id": "src/lib/types/markup.ts::MarkupCenteringBehavior",
                            "referenceLocation": "MarkupCenteringBehavior"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Defines the behavior of the provided markup when the originating viewport is smaller\nthan the current viewport, or is scaled to a size smaller than the current viewport\nusing the `scale` property.\n\nOptions:\n- `x-only`: Markup will be centered horizontally, but not vertically.\n- `y-only`: Markup will be centered vertically, but not horizontally.\n- `both`: Markup will be centered both horizontally and vertically.\n- `none`: Markup will not be centered (default)."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "centering-behavior",
                "defaultValue": "'none'"
            },
            "offset": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "Point.Point",
                    "resolved": "Point | undefined",
                    "references": {
                        "Point": {
                            "location": "import",
                            "path": "@vertexvis/geometry",
                            "id": "../geometry/dist/index.d.ts::\"/home/runner/work/vertex-web-sdk/vertex-web-sdk/packages/geometry/dist/point\"",
                            "referenceLocation": "Point"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The current offset of the visible viewport. This value is used to determine where\nmarkup should be rendered relative to the current viewport, enabling some markup to appear \"off-screen\".\n\nWhen provided, all computed coordinates will be offset by this amount."
                },
                "getter": false,
                "setter": false
            },
            "scale": {
                "type": "number",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The scale to render this markup at. This value is used to scale the element's bounds\nalong with any `offset` to determine the final computed coordinates.\n\nWhen provided, all computed coordinates will be scaled by this amount."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "scale",
                "defaultValue": "1"
            }
        };
    }
    static get states() {
        return {
            "stateMap": {}
        };
    }
    static get events() {
        return [{
                "method": "markupBegin",
                "name": "markupBegin",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "An event that is dispatched when a user begins a new markup."
                },
                "complexType": {
                    "original": "void",
                    "resolved": "void",
                    "references": {}
                }
            }, {
                "method": "markupEnd",
                "name": "markupEnd",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "An event that is dispatched when a user has finished their markup."
                },
                "complexType": {
                    "original": "Markup",
                    "resolved": "ArrowMarkup | CircleMarkup | FreeformMarkup",
                    "references": {
                        "Markup": {
                            "location": "import",
                            "path": "../../lib/types/markup",
                            "id": "src/lib/types/markup.ts::Markup",
                            "referenceLocation": "Markup"
                        }
                    }
                }
            }];
    }
    static get methods() {
        return {
            "reset": {
                "complexType": {
                    "signature": "() => Promise<void>",
                    "parameters": [],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "Resets the state of the internally managed markup element\nto allow for creating a new markup. This state is automatically\nmanaged when this element is placed as a child of a\n`<vertex-viewer-markup>` element.",
                    "tags": []
                }
            }
        };
    }
    static get elementRef() { return "hostEl"; }
    static get watchers() {
        return [{
                "propName": "viewer",
                "methodName": "handleViewerChanged"
            }, {
                "propName": "arrowTemplateId",
                "methodName": "handlePropertyChanged"
            }, {
                "propName": "circleTemplateId",
                "methodName": "handlePropertyChanged"
            }, {
                "propName": "disabled",
                "methodName": "handlePropertyChanged"
            }, {
                "propName": "endLineAnchorStyle",
                "methodName": "handlePropertyChanged"
            }, {
                "propName": "freeformTemplateId",
                "methodName": "handlePropertyChanged"
            }, {
                "propName": "startLineAnchorStyle",
                "methodName": "handlePropertyChanged"
            }, {
                "propName": "tool",
                "methodName": "handlePropertyChanged"
            }, {
                "propName": "scale",
                "methodName": "handleScalingConfigurationChanged"
            }, {
                "propName": "offset",
                "methodName": "handleScalingConfigurationChanged"
            }, {
                "propName": "originatingViewport",
                "methodName": "handleScalingConfigurationChanged"
            }, {
                "propName": "centeringBehavior",
                "methodName": "handleScalingConfigurationChanged"
            }];
    }
}
//# sourceMappingURL=viewer-markup-tool.js.map
