const START_INDEX = -1;
var DIRECTION;
(function (DIRECTION) {
    DIRECTION[DIRECTION["Up"] = -1] = "Up";
    DIRECTION[DIRECTION["Down"] = 1] = "Down";
})(DIRECTION || (DIRECTION = {}));
export class NavigationController {
    get input() {
        return this.host.singleSelect ? this.host._input : this.host._searchInput;
    }
    get dataState() {
        return this.state.dataState;
    }
    show() {
        this.host._show(true);
    }
    hide() {
        this.host._hide(true);
    }
    toggleSelect(index) {
        this.host.toggleSelect(index);
    }
    select(index) {
        this.host.selectByIndex(index);
    }
    get currentItem() {
        const item = this.active;
        return item === START_INDEX ? START_INDEX : item;
    }
    get firstItem() {
        return this.dataState.findIndex((i) => i.header !== true);
    }
    get lastItem() {
        return this.dataState.length - 1;
    }
    scrollToActive(container, behavior = 'auto') {
        container.element(this.active)?.scrollIntoView({
            block: 'center',
            behavior,
        });
        container.requestUpdate();
    }
    get active() {
        return this._active;
    }
    set active(node) {
        this._active = node;
        this.host.requestUpdate();
    }
    constructor(host, state) {
        this.host = host;
        this.state = state;
        this.hostHandlers = new Map(Object.entries({
            Escape: this.escape,
        }));
        this.mainInputHandlers = new Map(Object.entries({
            Escape: this.escape,
            ArrowUp: this.hide,
            ArrowDown: this.mainInputArrowDown,
            Tab: this.tab,
            Enter: this.enter,
        }));
        this.searchInputHandlers = new Map(Object.entries({
            Escape: this.escape,
            ArrowUp: this.escape,
            ArrowDown: this.inputArrowDown,
            Tab: this.inputArrowDown,
        }));
        this.listHandlers = new Map(Object.entries({
            ArrowDown: this.arrowDown,
            ArrowUp: this.arrowUp,
            ' ': this.space,
            Enter: this.enter,
            Escape: this.escape,
            Tab: this.tab,
            Home: this.home,
            End: this.end,
        }));
        this._active = START_INDEX;
        this.host.addController(this);
    }
    home(container) {
        this.active = this.firstItem;
        this.scrollToActive(container, 'smooth');
    }
    end(container) {
        this.active = this.lastItem;
        this.scrollToActive(container, 'smooth');
    }
    space() {
        if (this.active === START_INDEX) {
            return;
        }
        const item = this.dataState[this.active];
        if (!item.header) {
            this.toggleSelect(this.active);
        }
    }
    escape() {
        this.hide();
        this.host.focus();
    }
    enter() {
        if (this.active === START_INDEX) {
            return;
        }
        const item = this.dataState[this.active];
        if (!item.header && this.host.singleSelect) {
            this.select(this.active);
        }
        this.hide();
        requestAnimationFrame(() => this.input.select());
        this.host.focus();
    }
    inputArrowDown(container) {
        container.focus();
        this.arrowDown(container);
    }
    async mainInputArrowDown(container) {
        this.show();
        await container.updateComplete;
        if (this.host.singleSelect) {
            container.focus();
            this.arrowDown(container);
        }
    }
    tab() {
        this.hide();
        this.host.blur();
    }
    arrowDown(container) {
        this.getNextItem(DIRECTION.Down);
        this.scrollToActive(container);
    }
    arrowUp(container) {
        this.getNextItem(DIRECTION.Up);
        this.scrollToActive(container);
    }
    getNextItem(direction) {
        const next = this.getNearestItem(this.currentItem, direction);
        if (next === -1) {
            if (this.active === this.firstItem) {
                this.input.focus();
                this.active = START_INDEX;
            }
            return;
        }
        this.active = next;
    }
    getNearestItem(startIndex, direction) {
        let index = startIndex;
        const items = this.dataState;
        while (items[index + direction]?.header) {
            index += direction;
        }
        index += direction;
        if (index >= 0 && index < items.length) {
            return index;
        }
        return -1;
    }
    hostConnected() { }
    hostDisconnected() {
        this.active = START_INDEX;
    }
    navigateTo(item, container) {
        this.active = this.dataState.indexOf(item);
        this.scrollToActive(container, 'smooth');
    }
    navigateHost(event) {
        if (this.hostHandlers.has(event.key)) {
            event.preventDefault();
            this.hostHandlers.get(event.key).call(this);
        }
    }
    navigateMainInput(event, container) {
        event.stopPropagation();
        if (this.mainInputHandlers.has(event.key)) {
            event.preventDefault();
            this.mainInputHandlers.get(event.key).call(this, container);
        }
    }
    navigateSearchInput(event, container) {
        event.stopPropagation();
        if (this.searchInputHandlers.has(event.key)) {
            event.preventDefault();
            this.searchInputHandlers.get(event.key).call(this, container);
        }
    }
    navigateList(event, container) {
        event.stopPropagation();
        if (this.listHandlers.has(event.key)) {
            event.preventDefault();
            this.listHandlers.get(event.key).call(this, container);
        }
    }
}
//# sourceMappingURL=navigation.js.map