/*!
 * Copyright (c) 2026 Vertex Software LLC. All rights reserved.
 */
import { r as registerInstance, c as createEvent, h, H as Host, a as getElement } from './index-EpnuuCxl.js';
import { p as point } from './bundle-DfdVaPrt.js';
import { c as classname } from './index-DI7z7TKn.js';
import { g as getMouseClientPosition } from './dom-D6my8OyX.js';
import { t as translatePointToRelative, c as translatePointToScreen, a as PinController, P as PinModel, g as getPinColors, b as isTextPin } from './model-C-U1XF3h.js';
import { r as readDOM } from './stencil-CEl7wGvE.js';
import './_commonjsHelpers-CG9AChtV.js';
import './bundle-DLfw87TV.js';

function getComputedStyle(el) {
    return window.getComputedStyle(el);
}

const viewerPinLabelCss = () => `:host{--viewer-annotations-pin-label-background-color:var(--viewer-annotations-pin-accent-color);--viewer-annotations-pin-label-border-color:var(--viewer-annotations-pin-primary-color);--viewer-annotations-pin-label-focused-border-color:var(--viewer-annotations-pin-primary-color);--viewer-annotations-pin-label-color:var(--white);--viewer-annotations-pin-label-padding-y:0.375em;--viewer-annotations-pin-label-padding-x:0.5em;--viewer-annotations-pin-label-border-width:2px;--viewer-annotations-pin-label-border-style:solid;--viewer-annotations-pin-label-border-radius:0.25em;--viewer-annotations-pin-label-min-width:2rem;--viewer-annotations-pin-label-max-width:25rem;--viewer-annotations-pin-label-max-height:50rem;overflow:hidden;pointer-events:none}:host([mode='']) .pin-label{color:var(--viewer-annotations-pin-label-color);background:var(--viewer-annotations-pin-label-background-color)}.pin-label-text{font-family:Arial, Helvetica, sans-serif;font-size:0.875rem;line-height:1rem;word-break:break-word;white-space:pre-wrap}.pin-label-input-wrapper{display:flex;position:absolute;pointer-events:auto;box-sizing:border-box;min-width:var(--viewer-annotations-pin-label-min-width);max-width:var(--viewer-annotations-pin-label-max-width);max-height:var(--viewer-annotations-pin-label-max-height);background:var(--viewer-annotations-pin-label-background-color);border-width:var(--viewer-annotations-pin-label-border-width);border-style:var(--viewer-annotations-pin-label-border-style);border-color:var(--viewer-annotations-pin-label-border-color);border-radius:var(--viewer-annotations-pin-label-border-radius)}.pin-label-input-wrapper.focused{min-width:var(--viewer-annotations-pin-label-max-width);border-color:var(--viewer-annotations-pin-label-focused-border-color)}.pin-input-drag-target{position:absolute;top:0;left:0;width:100%;height:100%;cursor:pointer}.pin-label-input{resize:none;position:relative;outline:none;border:none;word-break:break-word;padding:0 0 0 0;background-color:transparent;margin:var(--viewer-annotations-pin-label-padding-y) var(--viewer-annotations-pin-label-padding-x);width:var(--viewer-annotations-pin-label-min-width);flex-grow:1;overflow:hidden;max-width:calc(var(--viewer-annotations-pin-label-max-width) - calc(2 * var(--viewer-annotations-pin-label-padding-x)))}.pin-label-input.readonly{pointer-events:auto;color:black;cursor:pointer}.pin-label-hidden{position:absolute;visibility:hidden;pointer-events:none;width:auto;height:auto;box-sizing:border-box;border-width:var(--viewer-annotations-pin-label-border-width);border-style:var(--viewer-annotations-pin-label-border-style);border-color:var(--viewer-annotations-pin-label-border-color);margin:var(--viewer-annotations-pin-label-padding-y) 0;padding:0 var(--viewer-annotations-pin-label-padding-x);max-width:calc(var(--viewer-annotations-pin-label-max-width) - calc(2 * var(--viewer-annotations-pin-label-padding-x)))}`;

const VertexPinLabel = class {
    constructor(hostRef) {
        registerInstance(this, hostRef);
        this.labelChanged = createEvent(this, "labelChanged");
        this.labelFocused = createEvent(this, "labelFocused");
        this.labelBlurred = createEvent(this, "labelBlurred");
        /**
         * The current text value of the component. Value is updated on user
         * interaction.
         */
        this.value = '';
        this.focused = false;
        this.textareaRows = 1;
        this.computeContentSize = () => {
            readDOM(() => {
                if (this.contentEl != null) {
                    this.contentElBounds = this.contentEl.getBoundingClientRect();
                    const computedStyles = getComputedStyle(this.contentEl);
                    this.textareaRows = Math.max(1, Math.ceil((parseFloat(computedStyles.getPropertyValue('height')) -
                        parseFloat(computedStyles.getPropertyValue('borderWidth')) * 2) /
                        parseFloat(computedStyles.getPropertyValue('lineHeight'))));
                }
            });
        };
        this.handleInputKeyDown = (event) => {
            event.stopPropagation();
            if (event.key === 'Enter' &&
                (event.ctrlKey || event.metaKey || event.shiftKey)) {
                this.textareaRows += 1;
                this.value += '\n';
            }
            else if (event.key === 'Enter') {
                event.preventDefault();
                this.submit();
            }
        };
        this.handlePointerDown = (event) => {
            var _a;
            if (!this.focused) {
                if (this.elementBounds != null) {
                    if (event.buttons !== 2) {
                        event.preventDefault();
                        event.stopPropagation();
                    }
                    this.relativePointerDownPosition = translatePointToRelative(getMouseClientPosition(event, this.elementBounds), this.elementBounds);
                    this.pinPointerDownPosition = (_a = this.pin) === null || _a === void 0 ? void 0 : _a.label.point;
                    window.addEventListener('pointermove', this.handlePointerMove);
                    window.addEventListener('pointerup', this.handlePointerUp);
                }
            }
        };
        this.handlePointerMove = (event) => {
            var _a;
            if (this.elementBounds != null &&
                this.relativePointerDownPosition &&
                this.pinPointerDownPosition != null) {
                // Prevent selection of any text while interacting with the label
                event.preventDefault();
                event.stopPropagation();
                const point$1 = getMouseClientPosition(event, this.elementBounds);
                const relative = translatePointToRelative(point$1, this.elementBounds);
                const relativeDelta = point.subtract(relative, this.relativePointerDownPosition);
                const myUpdatedPin = this.pin != null
                    ? {
                        ...this.pin,
                        label: {
                            ...this.pin.label,
                            point: point.add(this.pinPointerDownPosition, relativeDelta),
                        },
                    }
                    : undefined;
                if (myUpdatedPin) {
                    (_a = this.pinController) === null || _a === void 0 ? void 0 : _a.updatePin(myUpdatedPin);
                    this.computeScreenPosition();
                }
            }
        };
        this.handlePointerUp = (event) => {
            var _a, _b;
            if (((_a = this.pinController) === null || _a === void 0 ? void 0 : _a.getToolMode()) === 'edit' &&
                this.relativePointerDownPosition != null &&
                this.elementBounds != null) {
                const pointerDownScreen = translatePointToScreen(this.relativePointerDownPosition, this.elementBounds);
                const distanceBetweenStartAndEndPoint = point.distance(pointerDownScreen, getMouseClientPosition(event, this.elementBounds));
                if (distanceBetweenStartAndEndPoint <= 2) {
                    this.focused = true;
                    this.labelFocused.emit((_b = this.pin) === null || _b === void 0 ? void 0 : _b.id);
                }
            }
            this.relativePointerDownPosition = undefined;
            this.pinPointerDownPosition = undefined;
            window.removeEventListener('pointermove', this.handlePointerMove);
            window.removeEventListener('pointerup', this.handlePointerUp);
        };
        this.handleTextBlur = () => {
            this.submit();
        };
        this.handleTextInput = (event) => {
            const input = event.target;
            this.value = input.value;
        };
    }
    /**
     * Gives focus to the component's internal text input.
     */
    async setFocus() {
        var _a, _b, _c;
        // HTMLInputElement.focus() doesn't exist in tests.
        if (typeof ((_a = this.inputEl) === null || _a === void 0 ? void 0 : _a.focus) === 'function') {
            this.focused = true;
            this.labelFocused.emit((_b = this.pin) === null || _b === void 0 ? void 0 : _b.id);
            (_c = this.inputEl) === null || _c === void 0 ? void 0 : _c.focus();
        }
    }
    /**
     * @internal
     * submits the current text, unfocuses the input and emits the blur event to consumers
     */
    async submit() {
        var _a, _b;
        this.focused = false;
        this.labelBlurred.emit((_a = this.pin) === null || _a === void 0 ? void 0 : _a.id);
        if (this.pin != null) {
            (_b = this.pinController) === null || _b === void 0 ? void 0 : _b.updatePin({
                ...this.pin,
                label: {
                    point: this.pin.label.point,
                    text: this.value,
                },
            });
        }
    }
    watchFocusChange() {
        var _a, _b;
        this.labelChanged.emit();
        if (this.focused) {
            (_a = this.pinController) === null || _a === void 0 ? void 0 : _a.setSelectedPinId((_b = this.pin) === null || _b === void 0 ? void 0 : _b.id);
        }
    }
    watchPinChange() {
        var _a, _b;
        this.value = (_b = (_a = this.pin) === null || _a === void 0 ? void 0 : _a.label.text) !== null && _b !== void 0 ? _b : '';
        this.computeScreenPosition();
    }
    watchElementBoundsChange() {
        this.computeScreenPosition();
    }
    componentWillLoad() {
        var _a, _b;
        this.value = (_b = (_a = this.pin) === null || _a === void 0 ? void 0 : _a.label.text) !== null && _b !== void 0 ? _b : '';
        this.computeScreenPosition();
    }
    componentDidLoad() {
        this.resizeObserver = new ResizeObserver(() => {
            this.labelChanged.emit();
        });
        this.contentResizeObserver = new ResizeObserver(this.computeContentSize);
        if (this.hostEl != null) {
            this.resizeObserver.observe(this.hostEl);
        }
        if (this.contentEl != null) {
            this.contentResizeObserver.observe(this.contentEl);
        }
        if (this.pinController == null) {
            this.pinController = new PinController(new PinModel());
        }
    }
    disconnectedCallback() {
        var _a, _b;
        (_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
        (_b = this.contentResizeObserver) === null || _b === void 0 ? void 0 : _b.disconnect();
    }
    componentDidRender() {
        if (this.focused && this.inputEl != null) {
            this.setFocus();
        }
    }
    render() {
        var _a, _b, _c;
        const { primaryColor, accentColor } = getPinColors(this.pin);
        return (h(Host, { key: 'a02e4135406398f7e49331ac65ec121c216c75c1' }, h("div", { key: '14373fe8ac2fff6988c38d8c73fdd484c0fd8079', class: classname('pin-label-input-wrapper', {
                focused: this.focused,
            }), onPointerDown: this.handlePointerDown, style: {
                top: `${((_a = this.computedScreenPosition) === null || _a === void 0 ? void 0 : _a.y.toString()) || 0}px`,
                left: `${((_b = this.computedScreenPosition) === null || _b === void 0 ? void 0 : _b.x.toString()) || 0}px`,
                minWidth: this.computeMinWidth(),
                maxWidth: this.computeMaxWidth(),
                maxHeight: this.computeMaxHeight(),
                borderColor: primaryColor,
                background: accentColor,
            } }, h("textarea", { key: '10f15845d35c653f4d84c9d39694977e79ec329a', id: `pin-label-input-${(_c = this.pin) === null || _c === void 0 ? void 0 : _c.id}`, class: classname('pin-label-input', 'pin-label-text', {
                ['readonly']: !this.focused,
            }), disabled: !this.focused, ref: (ref) => (this.inputEl = ref), value: this.value, rows: this.textareaRows, onKeyDown: this.handleInputKeyDown, onInput: this.handleTextInput, onBlur: this.handleTextBlur }), !this.focused && (h("div", { key: 'a82f6c8553da740e3ab8c9c4f0b92cd1c3647ec6', class: "pin-input-drag-target", onPointerDown: this.handlePointerDown }))), h("div", { key: '197aae8a4bcb977305f662b61308310eacb0b780', ref: (el) => (this.contentEl = el), class: classname('pin-label-text', 'pin-label-hidden'), style: {
                maxWidth: this.computeMaxWidth(),
                maxHeight: this.computeMaxHeight(),
            } }, this.hiddenContent())));
    }
    hiddenContent() {
        // This corrects some inconsistencies in how a newline character
        // is represented in a div. Leveraging `<br>`s results in a more
        // consistent representation of the newlines in a textarea.
        return this.value.includes('\n')
            ? this.value
                .split('\n')
                .reduce((res, str) => [...res, str, h("br", null)], [])
            : [this.value];
    }
    computeMinWidth() {
        if (this.contentElBounds != null) {
            const expected = `${this.contentElBounds.width + 8}px`;
            return `min(${expected}, ${this.computeMaxWidth()})`;
        }
        else {
            return `var(--viewer-annotations-pin-label-min-width)`;
        }
    }
    computeMaxWidth() {
        const expected = `var(--viewer-annotations-pin-label-max-width)`;
        return `min(${expected}, ${this.computeRemainingWidth()})`;
    }
    computeMaxHeight() {
        const expected = `var(--viewer-annotations-pin-label-max-height)`;
        return `min(${expected}, ${this.computeRemainingHeight()})`;
    }
    computeRemainingWidth() {
        var _a, _b;
        return `calc(${((_a = this.elementBounds) === null || _a === void 0 ? void 0 : _a.width.toString()) || 0}px - ${((_b = this.computedScreenPosition) === null || _b === void 0 ? void 0 : _b.x.toString()) || 0}px)`;
    }
    computeRemainingHeight() {
        var _a, _b;
        return `calc(${((_a = this.elementBounds) === null || _a === void 0 ? void 0 : _a.height.toString()) || 0}px - ${((_b = this.computedScreenPosition) === null || _b === void 0 ? void 0 : _b.y.toString()) || 0}px)`;
    }
    computeScreenPosition() {
        this.computedScreenPosition =
            isTextPin(this.pin) &&
                this.elementBounds != null &&
                this.pin.label.point != null
                ? translatePointToScreen(this.pin.label.point, this.elementBounds)
                : undefined;
    }
    get hostEl() { return getElement(this); }
    static get watchers() { return {
        "focused": [{
                "watchFocusChange": 0
            }],
        "pin": [{
                "watchPinChange": 0
            }],
        "elementBounds": [{
                "watchElementBoundsChange": 0
            }]
    }; }
};
VertexPinLabel.style = viewerPinLabelCss();

const viewerPinLabelLineCss = () => `:host{--viewer-annotations-pin-label-line-color:var(--viewer-annotations-pin-primary-color);--viewer-annotations-pin-label-line-width:1;overflow:hidden;pointer-events:none}.label-line{pointer-events:auto;stroke:var(--viewer-annotations-pin-label-line-color);stroke-width:var( --viewer-annotations-pin-label-line-width);cursor:default}.svg{position:absolute;top:0;bottom:0;left:0;right:0;overflow:hidden;pointer-events:none;height:100%;width:100%}`;

const VertexPinLabelLine = class {
    constructor(hostRef) {
        registerInstance(this, hostRef);
    }
    render() {
        var _a, _b, _c, _d;
        const { primaryColor } = getPinColors(this.pin);
        return (h(Host, { key: 'f40021966738624fa4707420dd223a1d8d3f0e10' }, h("svg", { key: '80261903100db77ba6191f561cdb67daf614605f', class: "svg" }, h("line", { key: '0dc3e8abaf17f961d5bf5a005ebf4ac29bb8ba96', class: "label-line", style: {
                stroke: primaryColor,
            }, x1: (_a = this.labelPoint) === null || _a === void 0 ? void 0 : _a.x, y1: (_b = this.labelPoint) === null || _b === void 0 ? void 0 : _b.y, x2: (_c = this.pinPoint) === null || _c === void 0 ? void 0 : _c.x, y2: (_d = this.pinPoint) === null || _d === void 0 ? void 0 : _d.y }))));
    }
};
VertexPinLabelLine.style = viewerPinLabelLineCss();

export { VertexPinLabel as vertex_viewer_pin_label, VertexPinLabelLine as vertex_viewer_pin_label_line };
//# sourceMappingURL=vertex-viewer-pin-label.vertex-viewer-pin-label-line.entry.js.map

//# sourceMappingURL=vertex-viewer-pin-label_2.entry.js.map