// #region Imports
import { RendererServiceLocator } from '../../../../../Dom/Renderer';
import { on } from '@breadstone/mosaik-elements';
import { Attachable } from '../../../../Behaviors/Attachable';
import { Disableable } from '../../../../Behaviors/Disableable';
import { CustomElement } from '../../../Abstracts/CustomElement';
// #endregion
/**
 * Adorner - Abstract base class for decorative overlay elements attached to controls.
 *
 * @description
 * The AdornerElement provides foundational functionality for creating decorative overlay elements
 * that attach to and enhance other controls. Adorners are lightweight UI enhancements that appear
 * in response to mouse interactions (hover, move, leave, down) and can be positioned relative to
 * their target control using the Attachable behavior. Common use cases include tooltips, badges,
 * resize handles, selection indicators, and contextual helpers. This abstract class manages the
 * lifecycle of adorner DOM elements, handles mouse event subscriptions, and provides extension
 * points for subclasses to implement custom show/hide behavior.
 *
 * @name Adorner
 * @category Primitives
 *
 * @dependency {Attachable} - Positioning behavior for attaching to target elements
 * @dependency {Disableable} - Disabled state management
 *
 * @example
 * Creating a simple tooltip adorner:
 * ```typescript
 * export class TooltipElement extends AdornerElement {
 *     protected show(): void {
 *         const tooltip = this.create<HTMLDivElement>({
 *             classes: 'mosaik-tooltip'
 *         });
 *         tooltip.textContent = this.getAttribute('tooltip-text') || '';
 *     }
 *
 *     protected hide(): void {
 *         this.dispose();
 *     }
 * }
 * ```
 *
 * @example
 * Creating a badge adorner:
 * ```typescript
 * export class BadgeAdorner extends AdornerElement {
 *     private _badgeElement: HTMLElement | null = null;
 *
 *     protected show(): void {
 *         if (!this._badgeElement) {
 *             this._badgeElement = this.create<HTMLDivElement>({
 *                 classes: ['mosaik-badge', 'mosaik-badge-corner']
 *             });
 *         }
 *         this._badgeElement.style.display = 'block';
 *     }
 *
 *     protected hide(): void {
 *         if (this._badgeElement) {
 *             this._badgeElement.style.display = 'none';
 *         }
 *     }
 * }
 * ```
 *
 * @example
 * Using adorner with attachment configuration:
 * ```html
 * <mosaik-button control="my-button">Click Me</mosaik-button>
 * <custom-tooltip-adorner
 *     control="my-button"
 *     tooltip-text="Click to perform action"
 *     placement="top"
 *     offset="8">
 * </custom-tooltip-adorner>
 * ```
 *
 * @abstract
 * @public
 */
export class AdornerElement extends Disableable(Attachable(CustomElement)) {
    // #region Fields
    _adornerElement;
    _mouseEnterSubscription;
    _mouseMoveSubscription;
    _mouseLeaveSubscription;
    _mouseDownSubscription;
    // #endregion
    // #region Ctor
    /**
     * @public
     */
    constructor() {
        super();
        this._adornerElement = null;
        this._mouseEnterSubscription = null;
        this._mouseMoveSubscription = null;
        this._mouseLeaveSubscription = null;
        this._mouseDownSubscription = null;
    }
    // #endregion
    // #region Properties
    /**
     * Returns the `is` property.
     * The `is` property represents natural name of this element.
     *
     * @public
     * @static
     * @readonly
     */
    static get is() {
        return 'mosaik-adorner';
    }
    // #endregion
    // #region Methods
    /**
     * @protected
     * @override
     */
    onApplyTemplate() {
        super.onApplyTemplate();
        if (this.control) {
            this._mouseEnterSubscription = on(this.control, 'mouseenter', () => this.show());
            this._mouseMoveSubscription = on(this.control, 'mousemove', () => this.show());
            this._mouseLeaveSubscription = on(this.control, 'mouseleave', () => this.hide());
            this._mouseDownSubscription = on(this.control, 'mousedown', () => this.hide());
        }
    }
    /**
     * @public
     * @override
     */
    disconnectedCallback() {
        this._mouseEnterSubscription?.dispose();
        this._mouseMoveSubscription?.dispose();
        this._mouseLeaveSubscription?.dispose();
        this._mouseDownSubscription?.dispose();
        super.disconnectedCallback();
    }
    /**
     * @protected
     */
    create(config) {
        this._adornerElement = RendererServiceLocator.current.createElement(AdornerElement.is);
        if (this._adornerElement) {
            const classes = Array.isArray(config.classes) ? config.classes : [config.classes];
            classes.forEach((x) => {
                if (this._adornerElement) {
                    RendererServiceLocator.current.addClass(this._adornerElement, x ?? '');
                }
            });
            const parent = config.parent ?? RendererServiceLocator.current.parentNode(this);
            RendererServiceLocator.current.appendChild(parent, this._adornerElement);
        }
        return this._adornerElement;
    }
    /**
     * @protected
     */
    dispose() {
        if (this._adornerElement) {
            const parent = RendererServiceLocator.current.parentNode(this._adornerElement);
            if (parent && this._adornerElement) {
                RendererServiceLocator.current.removeChild(parent, this._adornerElement);
                this._adornerElement = null;
            }
        }
    }
}
//# sourceMappingURL=AdornerElement.js.map