/**
 * @license
 * Copyright Tyler Technologies, Inc. 
 * License: Apache-2.0
 */
import { task } from '../../core/utils/event-utils';
import { BASE_BUTTON_CONSTANTS } from './base-button-constants';
export class BaseButtonFoundation {
    constructor(_adapter) {
        this._adapter = _adapter;
        this._type = 'button'; // We default our buttons to the "button" type instead of "submit" as that is more common
        this._disabled = false;
        this._popoverIcon = false;
        this._dense = false;
        this._clickListener = this._onClick.bind(this);
        this._keydownListener = this._onKeydown.bind(this);
        this._slotChangeListener = () => this._detectSlottedAnchor();
    }
    initialize() {
        this._detectSlottedAnchor();
        this._adapter.addDefaultSlotChangeListener(this._slotChangeListener);
    }
    /**
     * Handles overriding the the `click()` method on the HTMLElement instance
     */
    click({ animateStateLayer = false } = {}) {
        if (this._disabled) {
            return;
        }
        this._adapter.clickHost();
        if (animateStateLayer) {
            this._adapter.animateStateLayer();
        }
    }
    focus(options) {
        this._adapter.focusHost(options);
        if ((options === null || options === void 0 ? void 0 : options.focusVisible) !== false) {
            this._adapter.forceFocusVisible();
        }
    }
    async _onClick(evt) {
        const isFormType = this._type === 'submit' || this._type === 'reset';
        // Custom elements do not work with the popover* attributes by default so we need to manually
        // manage the popover functionality for now...
        if (!isFormType && this._adapter.hasPopoverTarget()) {
            const isOpen = this._adapter.managePopover();
            // If the popover was opened successfully we can stop here since there is no need to
            // handle any other scenarios
            if (isOpen) {
                return;
            }
        }
        // Wait a cycle to allow the click event to propagate
        await new Promise(resolve => setTimeout(resolve));
        // We allow for our click event to bubble first before we handle it in case the developer
        // wants to prevent the default behavior
        if (evt.defaultPrevented || this._disabled) {
            return;
        }
        // For button types of submit or reset, we need to manually submit or reset the form
        // since the click event doesn't do that for us with custom elements
        if (isFormType) {
            this._adapter.clickFormButton(this._type);
        }
    }
    /**
     * Handle keydown events on the host element to manually trigger click events.
     */
    async _onKeydown(evt) {
        // Handle the special case for the space key to avoid scrolling when triggered
        if (evt.key === ' ') {
            evt.preventDefault();
            this.click();
            return;
        }
        // Wait a cycle for the keydown event to propagate
        await task();
        if (evt.defaultPrevented || this._disabled) {
            return;
        }
        if (evt.key === 'Enter') {
            this.click();
        }
    }
    _detectSlottedAnchor() {
        if (this._adapter.hasSlottedAnchor) {
            this.disabled = false;
            this._adapter.removeHostListener('click', this._clickListener);
            this._adapter.removeHostListener('keydown', this._keydownListener);
        }
        else {
            this._adapter.addHostListener('click', this._clickListener);
            this._adapter.addHostListener('keydown', this._keydownListener);
        }
        this._adapter.initialize();
    }
    get type() {
        return this._type;
    }
    set type(type) {
        if (this._type !== type) {
            this._type = type;
            this._adapter.setHostAttribute(BASE_BUTTON_CONSTANTS.attributes.TYPE, type);
        }
    }
    get disabled() {
        return this._disabled;
    }
    set disabled(value) {
        value = Boolean(value);
        if (this._disabled === value) {
            return;
        }
        if (this._adapter.hasSlottedAnchor) {
            value = false;
        }
        this._disabled = value;
        this._adapter.setDisabled(this._disabled);
        this._adapter.toggleHostAttribute(BASE_BUTTON_CONSTANTS.attributes.DISABLED, value);
    }
    get popoverIcon() {
        return this._popoverIcon;
    }
    set popoverIcon(value) {
        value = Boolean(value);
        if (this._popoverIcon !== value) {
            this._popoverIcon = value;
            this._adapter.toggleDefaultPopoverIcon(this._popoverIcon);
            this._adapter.toggleHostAttribute(BASE_BUTTON_CONSTANTS.attributes.POPOVER_ICON, value);
        }
    }
    get dense() {
        return this._dense;
    }
    set dense(value) {
        value = Boolean(value);
        if (this._dense !== value) {
            this._dense = value;
            this._adapter.toggleHostAttribute(BASE_BUTTON_CONSTANTS.attributes.DENSE, value);
        }
    }
}
