/**
 * @license
 * Copyright Tyler Technologies, Inc. 
 * License: Apache-2.0
 */
import { addClass, getShadowElement, removeClass, toggleClass } from '@tylertech/forge-core';
import { BaseAdapter } from '../core/base';
import { FOCUS_INDICATOR_CONSTANTS } from '../focus-indicator';
import { FIELD_CONSTANTS } from './field-constants';
export class FieldAdapter extends BaseAdapter {
    get focusIndicator() {
        return this._focusIndicatorElement;
    }
    constructor(component) {
        super(component);
        this._rootElement = getShadowElement(component, FIELD_CONSTANTS.selectors.ROOT);
        this._containerElement = getShadowElement(component, FIELD_CONSTANTS.selectors.CONTAINER);
        this._labelElement = getShadowElement(component, FIELD_CONSTANTS.selectors.LABEL);
        this._popoverIconElement = getShadowElement(component, FIELD_CONSTANTS.selectors.POPOVER_ICON);
        this._focusIndicatorElement = getShadowElement(component, FOCUS_INDICATOR_CONSTANTS.elementName);
    }
    addRootListener(name, listener) {
        this._rootElement.addEventListener(name, listener);
    }
    addPopoverIconClickListener(listener) {
        this._popoverIconElement.addEventListener('click', listener);
    }
    removePopoverIconClickListener(listener) {
        this._popoverIconElement.removeEventListener('click', listener);
    }
    /**
     * Moves the label into the container element if the position is inset, or out to the root
     * element otherwise.
     */
    setLabelPosition(value) {
        this._labelElement.remove();
        if (value === 'inset') {
            this._containerElement.prepend(this._labelElement);
        }
        else {
            this._rootElement.prepend(this._labelElement);
        }
    }
    /**
     * Adds or removes animation classes on the root element.
     */
    setFloatingLabel(value, skipAnimation = false) {
        if (skipAnimation) {
            return;
        }
        const className = value ? FIELD_CONSTANTS.classes.FLOATING_IN : FIELD_CONSTANTS.classes.FLOATING_OUT;
        const animationName = value ? FIELD_CONSTANTS.animations.FLOAT_IN_LABEL : FIELD_CONSTANTS.animations.FLOAT_OUT_LABEL;
        const animationEndListener = (evt) => {
            if (evt.animationName === animationName) {
                removeClass(className, this._rootElement);
                this._rootElement.removeEventListener('animationend', animationEndListener);
            }
        };
        addClass(className, this._rootElement);
        this._rootElement.addEventListener('animationend', animationEndListener);
    }
    /**
     * Adds or removes a class from the root element indicating whether the slot has any assigned
     * nodes.
     */
    handleSlotChange(slot) {
        if (slot.name === '') {
            this._trySlotLabel(slot);
            return;
        }
        // Ensure that the slot belongs to the field
        while (slot.assignedSlot) {
            slot = slot.assignedSlot;
        }
        if (!slot) {
            return;
        }
        const classMap = {
            label: FIELD_CONSTANTS.classes.HAS_LABEL,
            start: FIELD_CONSTANTS.classes.HAS_START,
            end: FIELD_CONSTANTS.classes.HAS_END,
            accessory: FIELD_CONSTANTS.classes.HAS_ACCESSORY,
            'support-text': FIELD_CONSTANTS.classes.HAS_SUPPORT_START,
            'support-text-end': FIELD_CONSTANTS.classes.HAS_SUPPORT_END
        };
        if (slot.name in classMap) {
            toggleClass(this._rootElement, !!slot.assignedNodes({ flatten: true }).length, classMap[slot.name]);
        }
    }
    /**
     * Gets `<label>` and `<forge-label>` elements from the default slot and assigns them to the
     * 'label' slot.
     */
    _trySlotLabel(slot) {
        const elements = slot.assignedElements({ flatten: true });
        const labels = elements.filter(el => el.matches(FIELD_CONSTANTS.selectors.LABEL_ELEMENTS));
        labels.forEach(label => {
            if (label.slot) {
                return;
            }
            label.slot = 'label';
        });
    }
}
