import focus from '@dojo/framework/core/middleware/focus';
import i18n from '@dojo/framework/core/middleware/i18n';
import { createICacheMiddleware } from '@dojo/framework/core/middleware/icache';
import theme from '../middleware/theme';
import { create, tsx } from '@dojo/framework/core/vdom';
import Icon from '../icon';
import bundle from './nls/TabContainer';
import { formatAriaProperties, Keys } from '../common/util';
import * as css from '../theme/default/tab-container.m.css';
import offscreen from '../middleware/offscreen';
const factory = create({
    focus,
    i18n,
    icache: createICacheMiddleware(),
    theme,
    offscreen
}).properties();
export const TabContainer = factory(function TabContainer({ children, id, middleware: { focus, i18n, icache, theme, offscreen }, properties }) {
    const { alignButtons = 'top', aria = {}, initialActiveIndex = 0, tabs, onActiveIndex, onClose, theme: themeProp, classes, variant, fixed = true } = properties();
    let { activeIndex } = properties();
    const themeCss = theme.classes(css);
    const { messages } = i18n.localize(bundle);
    if (activeIndex === undefined) {
        activeIndex = icache.getOrSet('activeIndex', initialActiveIndex);
    }
    function closeTab(index) {
        onClose && onClose(index);
        setActiveIndex(0);
    }
    function setActiveIndex(index) {
        focus.focus();
        onActiveIndex && onActiveIndex(index);
        icache.set('activeIndex', index);
    }
    function onKeyDown(event, { closeable, disabled }, index) {
        event.stopPropagation();
        const total = tabs.length;
        switch (event.which) {
            case Keys.Escape:
                if (closeable && !disabled) {
                    closeTab(index);
                }
                break;
            case Keys.Left:
            case Keys.Up:
                event.preventDefault();
                setActiveIndex((index - 1 + total) % total);
                break;
            case Keys.Right:
            case Keys.Down:
                event.preventDefault();
                setActiveIndex((index + 1) % total);
                break;
            case Keys.Home:
                event.preventDefault();
                setActiveIndex(0);
                break;
            case Keys.End:
                event.preventDefault();
                setActiveIndex(tabs.length - 1);
                break;
        }
    }
    const renderTab = (tab, index) => {
        const { closeable, disabled, name } = tab;
        const active = index === activeIndex;
        return (tsx("div", { "aria-controls": `${id}-tab-${index}`, "aria-disabled": disabled ? 'true' : 'false', "aria-selected": active ? 'true' : 'false', classes: [
                themeCss.tabButton,
                active ? themeCss.activeTabButton : null,
                closeable ? themeCss.closeable : null,
                disabled ? themeCss.disabledTabButton : null
            ], focus: active ? focus.shouldFocus : () => false, id: `${id}-tabbutton-${index}`, key: `${index}-tabbutton`, onclick: () => {
                if (!disabled) {
                    setActiveIndex(index);
                }
            }, onkeydown: (event) => onKeyDown(event, tab, index), role: "tab", tabIndex: active ? 0 : -1 },
            tsx("span", { key: "tabButtonContent", classes: [themeCss.tabButtonContent, active && themeCss.activeTabButtonLabel] },
                name,
                closeable ? (tsx("button", { disabled: disabled, tabIndex: active ? 0 : -1, classes: themeCss.close, key: `${index}-tabbutton-close`, type: "button", onclick: (event) => {
                        event.stopPropagation();
                        if (!disabled) {
                            closeTab(index);
                        }
                    } },
                    tsx(Icon, { type: "closeIcon", altText: messages.close, size: "small", theme: themeProp, classes: classes, variant: variant }))) : null,
                tsx("span", { classes: [themeCss.indicator, active && themeCss.indicatorActive] },
                    tsx("span", { classes: themeCss.indicatorContent })))));
    };
    const renderedTabs = tabs.map(renderTab);
    const horizontalScrollbarHeight = icache.getOrSet('horizontalScrollbarHeight', () => {
        return offscreen(() => tsx("div", { classes: [themeCss.scrollTest] }), (node) => node.offsetHeight - node.clientHeight);
    });
    let content = [
        fixed ? (tsx("div", { key: "buttons", classes: themeCss.tabButtons }, renderedTabs)) : (tsx("div", { key: "scrollArea", classes: [themeCss.scrollArea, themeCss.scroll], styles: { marginBottom: `${horizontalScrollbarHeight}px` } },
            tsx("div", { key: "buttons", classes: [themeCss.tabButtons, themeCss.scrollContent] }, renderedTabs))),
        tsx("div", { key: "tabs", classes: themeCss.tabs }, children().map((child, index) => {
            const disabled = tabs[index].disabled;
            const active = activeIndex === index && !disabled;
            return (tsx("div", { classes: active ? themeCss.tab : undefined, hidden: !active }, child));
        }))
    ];
    let alignClass;
    let orientation = 'horizontal';
    switch (alignButtons) {
        case 'right':
            alignClass = themeCss.alignRight;
            orientation = 'vertical';
            content.reverse();
            break;
        case 'bottom':
            alignClass = themeCss.alignBottom;
            content.reverse();
            break;
        case 'left':
            alignClass = themeCss.alignLeft;
            orientation = 'vertical';
            break;
    }
    return (tsx("div", Object.assign({}, formatAriaProperties(aria), { key: "root", "aria-orientation": orientation, classes: [
            theme.variant(),
            alignClass || null,
            themeCss.root,
            fixed ? themeCss.fixed : themeCss.scroller
        ], role: "tablist" }), content));
});
export default TabContainer;

/*# sourceMappingURL=index.mjs.map*/