/**
 * @license
 * Copyright 2023 Tyler Technologies, Inc. 
 * License: Apache-2.0
 */
import { MDCTabScroller } from '@material/tab-scroller';
import { getShadowElement, removeClass, isFunction, getActiveElement, toggleClass } from '@tylertech/forge-core';
import { BaseAdapter } from '../../core/base/base-adapter';
import { TAB_BAR_CONSTANTS } from './tab-bar-constants';
import { TAB_CONSTANTS } from '../tab/tab-constants';
export class TabBarAdapter extends BaseAdapter {
    constructor(component) {
        super(component);
        this._tabs = [];
        this._rootElement = getShadowElement(this._component, TAB_BAR_CONSTANTS.selectors.ROOT);
        this._tabScrollElement = getShadowElement(this._component, TAB_BAR_CONSTANTS.selectors.TAB_SCROLLER);
        this._tabScrollAreaElement = getShadowElement(this._component, TAB_BAR_CONSTANTS.selectors.TAB_SCROLLER_AREA);
        this._tabScrollContentElement = getShadowElement(this._component, TAB_BAR_CONSTANTS.selectors.TAB_SCROLLER_CONTENT);
        this._defaultSlotElement = getShadowElement(this._component, TAB_CONSTANTS.selectors.DEFAULT_SLOT);
        this._prevButtonContainerElement = getShadowElement(this._component, TAB_BAR_CONSTANTS.selectors.PREV_BUTTON_CONTAINER);
        this._prevButtonElement = getShadowElement(this._component, TAB_BAR_CONSTANTS.selectors.PREV_BUTTON);
        this._nextButtonContainerElement = getShadowElement(this._component, TAB_BAR_CONSTANTS.selectors.NEXT_BUTTON_CONTAINER);
        this._nextButtonElement = getShadowElement(this._component, TAB_BAR_CONSTANTS.selectors.NEXT_BUTTON);
    }
    initializeTabs(activeTabIndex, stretch) {
        this._tabs = this._getTabs();
        if (!this._tabs.length) {
            return;
        }
        this._tabs.forEach(tab => {
            tab.active = false;
            tab.stretch = stretch;
        });
        // Set the initial active tab
        if (activeTabIndex >= 0 && activeTabIndex < this._tabs.length) {
            this._tabs[activeTabIndex].active = true;
        }
        else {
            this.ensureFocusableTab();
        }
    }
    initializeTabScroller() {
        this._tabScroller = new MDCTabScroller(this._tabScrollElement);
    }
    initializeAccessibility() {
        if (!this._component.hasAttribute('role')) {
            this._component.setAttribute('role', 'tablist');
        }
    }
    destroyTabScroller() {
        if (this._tabScroller) {
            this._tabScroller.destroy();
        }
    }
    addTabChangeListener(listener) {
        this._defaultSlotElement.addEventListener('slotchange', listener);
    }
    removeTabChangeListener(listener) {
        this._defaultSlotElement.removeEventListener('slotchange', listener);
    }
    addScrollListener(listener) {
        this._tabScrollAreaElement.addEventListener('scroll', listener);
    }
    getTabIndex(tab) {
        return this._tabs.indexOf(tab);
    }
    getTabCount() {
        return this._tabs.length;
    }
    activateTab(index, previousTabBounds) {
        const tab = this._getTabByIndex(index);
        if (tab) {
            tab.activate(previousTabBounds);
        }
    }
    deactivateTab(index) {
        const tab = this._getTabByIndex(index);
        if (tab) {
            tab.deactivate();
        }
    }
    syncTabIndex(index) {
        const tabs = this._getTabs();
        const activeTab = tabs[index];
        tabs.filter(t => t !== activeTab)
            .forEach(t => t.setTabIndex(-1));
    }
    getTabBounds(index) {
        const tab = this._getTabByIndex(index);
        if (tab) {
            return tab.computeIndicatorBounds();
        }
        return undefined;
    }
    setUnderline(value) {
        toggleClass(this._rootElement, value, TAB_BAR_CONSTANTS.classes.UNDERLINED);
    }
    setStacked(value) {
        toggleClass(this._rootElement, value, TAB_BAR_CONSTANTS.classes.STACKED);
    }
    scrollTo(scrollX) {
        if (this._tabScroller) {
            this._tabScroller.scrollTo(scrollX);
        }
    }
    getScrollContentWidth() {
        return this._tabScroller ? this._tabScroller.getScrollContentWidth() : 0;
    }
    getScrollPosition() {
        return this._tabScroller ? this._tabScroller.getScrollPosition() : 0;
    }
    getOffsetWidth() {
        return this._tabScrollElement.offsetWidth;
    }
    getTabDimensionsAtIndex(index) {
        const tab = this._getTabByIndex(index);
        if (tab) {
            return tab.computeDimensions();
        }
        return {
            rootLeft: 0,
            rootRight: 0,
            contentLeft: 0,
            contentRight: 0
        };
    }
    incrementScroll(scrollXIncrement) {
        if (this._tabScroller) {
            this._tabScroller.incrementScroll(scrollXIncrement);
        }
    }
    isScrolled() {
        const position = this._tabScrollAreaElement.scrollLeft;
        return position > 0;
    }
    isScrolledEnd() {
        const position = Math.round(this._tabScrollAreaElement.scrollLeft);
        const scrollWidth = Math.round(this._tabScrollContentElement.scrollWidth - this._tabScrollElement.offsetWidth);
        return position >= scrollWidth;
    }
    getFocusedTabIndex() {
        const activeElement = getActiveElement(this._component.ownerDocument);
        return this._tabs.findIndex(tab => {
            if (tab === activeElement) {
                return true;
            }
            return !!tab.shadowRoot.contains(activeElement);
        });
    }
    focusTabAtIndex(index) {
        const tab = this._getTabByIndex(index);
        if (tab) {
            return tab.focus();
        }
    }
    setLayoutMode(value) {
        const isFixed = value === 'fixed';
        toggleClass(this._rootElement, isFixed, TAB_BAR_CONSTANTS.classes.FIXED);
        this._tabs.forEach(tab => tab.stretch = isFixed);
    }
    setLayoutAlign(value) {
        removeClass([
            TAB_BAR_CONSTANTS.classes.ALIGN_CENTER,
            TAB_BAR_CONSTANTS.classes.ALIGN_END
        ], this._rootElement);
        switch (value) {
            case 'center':
                this._rootElement.classList.add(TAB_BAR_CONSTANTS.classes.ALIGN_CENTER);
                break;
            case 'end':
                this._rootElement.classList.add(TAB_BAR_CONSTANTS.classes.ALIGN_END);
                break;
        }
    }
    setPreviousButtonVisibility(value) {
        if (value) {
            this._prevButtonContainerElement.style.removeProperty('display');
        }
        else {
            this._prevButtonContainerElement.style.display = 'none';
        }
    }
    setPreviousButtonEnabled(value) {
        this._prevButtonElement.disabled = !value;
    }
    setNextButtonVisibility(value) {
        if (value) {
            this._nextButtonContainerElement.style.removeProperty('display');
        }
        else {
            this._nextButtonContainerElement.style.display = 'none';
        }
    }
    setNextButtonEnabled(value) {
        this._nextButtonElement.disabled = !value;
    }
    addScrollPreviousListener(type, listener) {
        this._prevButtonElement.addEventListener(type, listener);
    }
    addScrollNextListener(type, listener) {
        this._nextButtonElement.addEventListener(type, listener);
    }
    isTabDisabled(index) {
        const tab = this._getTabByIndex(index);
        return tab ? tab.disabled : true;
    }
    ensureFocusableTab() {
        const tabs = this._getTabs();
        const hasActiveTab = tabs.some(tab => tab.active);
        if (!hasActiveTab && tabs.length) {
            const firstTab = tabs[0];
            if (isFunction(firstTab.setTabIndex)) {
                tabs[0].setTabIndex(0);
            }
        }
    }
    _getTabs() {
        return Array.from(this._component.querySelectorAll(TAB_CONSTANTS.elementName));
    }
    _getTabByIndex(index) {
        return this._tabs[index];
    }
}
