/**
 * @license
 * Copyright Tyler Technologies, Inc. 
 * License: Apache-2.0
 */
import { getEventPath } from '@tylertech/forge-core';
import { BUTTON_AREA_CONSTANTS } from './button-area-constants';
export class ButtonAreaFoundation {
    constructor(_adapter) {
        this._adapter = _adapter;
        this._disabled = false;
        this._clickListener = this._handleClick.bind(this);
        this._keydownListener = this._handleKeydown.bind(this);
        this._pointerdownListener = this._handlePointerdown.bind(this);
        this._ignoreStateLayerListener = this._handleIgnoreStateLayer.bind(this);
        this._slotListener = this._handleSlotChange.bind(this);
    }
    initialize() {
        this._adapter.addListener('click', this._clickListener);
        this._adapter.addListener('keydown', this._keydownListener);
        this._adapter.addListener('pointerdown', this._pointerdownListener);
        this._adapter.addContentSlotListener('click', this._ignoreStateLayerListener.bind(this));
        this._adapter.addContentSlotListener('pointerdown', this._ignoreStateLayerListener.bind(this));
        this._adapter.addContentSlotListener('pointerup', this._ignoreStateLayerListener.bind(this));
        this._adapter.addButtonSlotListener('slotchange', this._slotListener);
    }
    disconnect() {
        this._adapter.removeListener('click', this._clickListener);
        this._adapter.removeListener('keydown', this._keydownListener);
        this._adapter.removeListener('pointerdown', this._pointerdownListener);
        this._adapter.removeContentSlotListener('click', this._ignoreStateLayerListener.bind(this));
        this._adapter.removeContentSlotListener('pointerdown', this._ignoreStateLayerListener.bind(this));
        this._adapter.removeContentSlotListener('pointerup', this._ignoreStateLayerListener.bind(this));
        this._adapter.removeButtonSlotListener('slotchange', this._slotListener);
        this._adapter.destroy();
        this._adapter.stopButtonObserver();
    }
    _handleClick(event) {
        // Prevent the click if disabled
        if (this._disabled) {
            event.stopPropagation();
        }
        // Prevent the click if a selection was made
        const selection = window.getSelection();
        if ((selection === null || selection === void 0 ? void 0 : selection.type) === 'Range' && (selection === null || selection === void 0 ? void 0 : selection.toString().trim()) !== '') {
            event.stopPropagation();
        }
        // Prevent the click if it originates from an ignored element
        if (this._shouldIgnoreEvent(event)) {
            event.stopPropagation();
        }
    }
    _handleKeydown(event) {
        if (event.key !== ' ' && event.key !== 'Enter') {
            return;
        }
        // Prevent the keydown if it originates from an ignored element
        if (this._shouldIgnoreEvent(event)) {
            event.stopPropagation();
        }
        else {
            this._adapter.animateStateLayer();
        }
    }
    _handlePointerdown(event) {
        if (this._disabled) {
            return;
        }
        // Prevent the pointerdown if it originates from an ignored element
        if (this._shouldIgnoreEvent(event)) {
            this._adapter.requestDisabledButtonFrame();
        }
    }
    _handleIgnoreStateLayer(event) {
        if (this._disabled) {
            return;
        }
        // Prevent the state layer animation if the event originates from an ignored element
        if (this._shouldIgnoreEvent(event)) {
            event.stopPropagation();
        }
    }
    _handleSlotChange() {
        // Clear old button-connected listeners
        this._adapter.stopButtonObserver();
        this._adapter.detectSlottedButton();
        this._adapter.startButtonObserver(() => this._handleButtonDisabled());
        // Match the component and button states if either is disabled
        if (this._adapter.isButtonDisabled()) {
            this.disabled = true;
        }
        else if (this._disabled) {
            this._adapter.setDisabled(true);
        }
    }
    _handleButtonDisabled() {
        this.disabled = this._adapter.isButtonDisabled();
    }
    _shouldIgnoreEvent(event) {
        const eventPath = getEventPath(event);
        return eventPath.some(el => el.nodeType === 1 && (el.hasAttribute(BUTTON_AREA_CONSTANTS.attributes.IGNORE) || el.hasAttribute(BUTTON_AREA_CONSTANTS.attributes.IGNORE_ALT)));
    }
    get disabled() {
        return this._disabled;
    }
    set disabled(value) {
        if (this._disabled !== value) {
            this._disabled = value;
            this._adapter.setDisabled(this._disabled);
            this._adapter.toggleHostAttribute(BUTTON_AREA_CONSTANTS.attributes.DISABLED, this._disabled);
        }
    }
}
