/**
 * @license
 * Copyright 2023 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 = event => this._handleClick(event);
        this._keydownListener = event => this._handleKeydown(event);
        this._pointerdownListener = event => this._handlePointerdown(event);
        this._slotListener = () => this._handleSlotChange();
    }
    initialize() {
        this._adapter.addListener('click', this._clickListener);
        this._adapter.addListener('keydown', this._keydownListener);
        this._adapter.addListener('pointerdown', this._pointerdownListener);
        this._adapter.addSlotChangeListener(this._slotListener);
        this._adapter.createRipple();
    }
    disconnect() {
        this._adapter.destroy();
        this._adapter.removeListener('click', this._clickListener);
        this._adapter.removeSlotChangeListener(this._slotListener);
        this._adapter.stopButtonObserver();
    }
    _handleClick(event) {
        var _a;
        // Prevent the click if disabled
        if (this._disabled) {
            event.stopPropagation();
        }
        // Prevent the click if a selection was made
        const selectionType = (_a = window.getSelection()) === null || _a === void 0 ? void 0 : _a.type;
        if (selectionType === 'Range') {
            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();
        }
    }
    _handlePointerdown(event) {
        if (this._disabled) {
            return;
        }
        // Prevent the ripple animation when ignored children are clicked
        if (this._shouldIgnoreEvent(event)) {
            this._adapter.requestDisabledButtonFrame();
        }
    }
    _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.buttonIsDisabled()) {
            this.disabled = true;
        }
        else if (this._disabled) {
            this._adapter.setDisabled(true);
        }
    }
    _handleButtonDisabled() {
        this.disabled = this._adapter.buttonIsDisabled();
    }
    _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);
        }
    }
}
