/**
 * @license
 * Copyright 2023 Tyler Technologies, Inc. 
 * License: Apache-2.0
 */
import { addClass, elementFromHTML, getActiveElement, getShadowElement, removeClass, removeElement, toggleClass, walkUpUntil } from '@tylertech/forge-core';
import { BaseAdapter } from '../../core/base/base-adapter';
import { ICON_CONSTANTS } from '../../icon';
import { ForgeRipple, ForgeRippleFoundation } from '../../ripple';
import { CHIP_SET_CONSTANTS } from '../chip-set/chip-set-constants';
const checkmarkTemplate = '<div class=\"forge-chip__checkmark\" aria-hidden=\"true\"><svg class=\"forge-chip__checkmark-svg\" viewBox=\"-2 -3 30 30\"><path class=\"forge-chip__checkmark-path\" fill=\"none\" stroke=\"black\" d=\"M1.73,12.91 8.1,19.28 22.79,4.59\"/></svg></div>';
import { CHIP_CONSTANTS } from './chip-constants';
export class ChipAdapter extends BaseAdapter {
    constructor(component) {
        super(component);
        this._rootElement = getShadowElement(this._component, CHIP_CONSTANTS.selectors.ROOT);
        this._buttonElement = getShadowElement(this._component, CHIP_CONSTANTS.selectors.BUTTON);
        this._leadingSlotElement = getShadowElement(this._component, 'slot[name=leading]');
        this._rootElement.addEventListener('click', evt => {
            if (evt.target === this._deleteButton) {
                return;
            }
            this._buttonElement.focus();
        }, { capture: true });
    }
    // ForgeRippleCapableSurface
    get root() {
        return this._rootElement;
    }
    get unbounded() {
        return false;
    }
    get disabled() {
        var _a;
        return (_a = this._buttonElement) === null || _a === void 0 ? void 0 : _a.disabled;
    }
    addRootListener(type, listener) {
        this._rootElement.addEventListener(type, listener);
    }
    removeRootListener(type, listener) {
        this._rootElement.removeEventListener(type, listener);
    }
    addButtonListener(type, listener) {
        this._buttonElement.addEventListener(type, listener);
    }
    removeButtonListener(type, listener) {
        this._buttonElement.removeEventListener(type, listener);
    }
    initializeRipple() {
        const adapter = Object.assign(Object.assign({}, ForgeRipple.createAdapter(this)), { registerInteractionHandler: (evtType, handler) => {
                if (['focus', 'blur', 'keydown'].includes(evtType)) {
                    this._buttonElement.addEventListener(evtType, handler, { passive: true });
                }
                else {
                    this._rootElement.addEventListener(evtType, handler, { passive: true });
                }
            }, deregisterInteractionHandler: (evtType, handler) => {
                if (['focus', 'blur', 'keydown'].includes(evtType)) {
                    this._buttonElement.removeEventListener(evtType, handler, { passive: true });
                }
                else {
                    this._rootElement.removeEventListener(evtType, handler, { passive: true });
                }
            }, isSurfaceActive: () => this._buttonElement.matches(':active'), isUnbounded: () => Boolean(this.unbounded), isSurfaceDisabled: () => this._buttonElement.disabled, addClass: className => addClass(className, this._rootElement), removeClass: className => removeClass(className, this._rootElement), updateCssVariable: (varName, value) => this._rootElement.style.setProperty(varName, value) });
        this._rippleInstance = new ForgeRipple(this._rootElement, new ForgeRippleFoundation(adapter));
        return this._rippleInstance;
    }
    clearTypeClass() {
        removeClass([CHIP_CONSTANTS.classes.ACTION, CHIP_CONSTANTS.classes.CHOICE, CHIP_CONSTANTS.classes.FILTER, CHIP_CONSTANTS.classes.INPUT], this._buttonElement);
    }
    addRootClass(className) {
        this._rootElement.classList.add(className);
    }
    removeRootClass(name) {
        this._rootElement.classList.remove(name);
    }
    setCheckmarkVisibility(isVisible) {
        if (isVisible) {
            if (!this._checkmarkElement) {
                this._checkmarkElement = elementFromHTML(checkmarkTemplate);
            }
            this._rootElement.insertBefore(this._checkmarkElement, this._rootElement.firstChild);
        }
        else if (this._checkmarkElement && this._checkmarkElement.isConnected) {
            removeElement(this._checkmarkElement);
        }
    }
    setSelected(value) {
        toggleClass(this._rootElement, value, CHIP_CONSTANTS.classes.SELECTED);
    }
    setDisabled(value) {
        this._buttonElement.disabled = value;
        this._buttonElement.tabIndex = value ? -1 : 0;
        toggleClass(this._rootElement, value, CHIP_CONSTANTS.classes.DISABLED);
    }
    setDense(value) {
        toggleClass(this._rootElement, value, CHIP_CONSTANTS.classes.DENSE);
    }
    setDeleteButtonVisibility(isVisible, listener) {
        if (isVisible) {
            if (!this._deleteButton) {
                this._deleteButton = this._createDeleteButton(listener);
            }
            if (!this._deleteButtonTouchTarget) {
                this._deleteButtonTouchTarget = this._createDeleteButtonTouchTarget(listener);
            }
            this._deleteButton.appendChild(this._deleteButtonTouchTarget);
            this._rootElement.appendChild(this._deleteButton);
        }
        else {
            if (this._deleteButtonTouchTarget) {
                removeElement(this._deleteButtonTouchTarget);
            }
            if (this._deleteButton) {
                removeElement(this._deleteButton);
            }
        }
    }
    setLeadingSlotVisibility(isVisible) {
        toggleClass(this._leadingSlotElement, !isVisible, CHIP_CONSTANTS.classes.LEADING_HIDDEN);
    }
    getChipSetState() {
        let state = null;
        const chipSet = walkUpUntil(this._component, node => node && node.nodeName === CHIP_SET_CONSTANTS.elementName.toUpperCase());
        if (chipSet) {
            state = {
                type: chipSet.type,
                disabled: chipSet.disabled,
                dense: chipSet.dense
            };
        }
        return state;
    }
    _createDeleteButton(listener) {
        const el = document.createElement(ICON_CONSTANTS.elementName);
        el.id = 'remove-button';
        el.name = 'cancel';
        el.tabIndex = -1;
        el.setAttribute('aria-hidden', 'false');
        el.setAttribute('aria-label', `Remove ${this._component.innerText}`);
        el.setAttribute('role', 'button');
        el.classList.add(CHIP_CONSTANTS.classes.DELETE_BUTTON);
        el.addEventListener('keydown', listener);
        return el;
    }
    _createDeleteButtonTouchTarget(listener) {
        const el = document.createElement('div');
        el.classList.add(CHIP_CONSTANTS.classes.DELETE_BUTTON_TOUCH_TARGET);
        el.addEventListener('keydown', listener);
        el.addEventListener('click', listener);
        return el;
    }
    setFocus() {
        this._buttonElement.focus();
    }
    tryFocusDelete() {
        if (this._deleteButton) {
            this._deleteButton.focus();
        }
        else {
            this.setFocus();
        }
    }
    setEmulatedFocus(value) {
        this._buttonElement.classList.toggle('mdc-ripple-upgraded--background-focused', value);
    }
    tryMoveFocusNext() {
        const activeElement = getActiveElement(this._component.ownerDocument);
        if (activeElement === this._buttonElement) {
            if (this._deleteButton) {
                this._deleteButton.focus();
            }
            else {
                this.emitHostEvent(CHIP_CONSTANTS.events.FOCUS_NEXT);
            }
        }
        else if (activeElement === this._deleteButton) {
            this.emitHostEvent(CHIP_CONSTANTS.events.FOCUS_NEXT);
        }
    }
    tryMoveFocusPrevious() {
        const activeElement = getActiveElement(this._component.ownerDocument);
        if (activeElement === this._deleteButton) {
            this._buttonElement.focus();
        }
        else if (activeElement === this._buttonElement) {
            this.emitHostEvent(CHIP_CONSTANTS.events.FOCUS_PREVIOUS);
        }
    }
}
