
import { __decorate, __param } from '../../../../../../../external/tslib/tslib.es6.js';
import { $ as $$1, append } from '../../../../base/browser/dom.js';
import { RenderIndentGuides } from '../../../../base/browser/ui/tree/abstractTree.js';
import { ObjectTreeElementCollapseState } from '../../../../base/browser/ui/tree/tree.js';
import { Emitter } from '../../../../base/common/event.js';
import { Disposable } from '../../../../base/common/lifecycle.js';
import { IInstantiationService } from '../../../instantiation/common/instantiation.js';
import { WorkbenchObjectTree } from '../../../list/browser/listService.js';
import { QuickPickFocus } from '../../common/quickInput.js';
import { QuickInputTreeDelegate } from './quickInputDelegate.js';
import { getParentNodeState } from './quickInputTree.js';
import { QuickTreeAccessibilityProvider } from './quickInputTreeAccessibilityProvider.js';
import { QuickInputTreeFilter } from './quickInputTreeFilter.js';
import { QuickInputTreeRenderer } from './quickInputTreeRenderer.js';
import { QuickInputTreeSorter } from './quickInputTreeSorter.js';

const $ = $$1;
let QuickInputTreeController = class QuickInputTreeController extends Disposable {
    constructor(container, hoverDelegate, instantiationService) {
        super();
        this.instantiationService = instantiationService;
        this._onDidTriggerButton = this._register(( new Emitter()));
        this.onDidTriggerButton = this._onDidTriggerButton.event;
        this._onDidChangeCheckboxState = this._register(( new Emitter()));
        this.onDidChangeCheckboxState = this._onDidChangeCheckboxState.event;
        this._onDidCheckedLeafItemsChange = this._register(( new Emitter()));
        this.onDidChangeCheckedLeafItems = this._onDidCheckedLeafItemsChange.event;
        this._onLeave = ( new Emitter());
        this.onLeave = this._onLeave.event;
        this._onDidAccept = this._register(( new Emitter()));
        this.onDidAccept = this._onDidAccept.event;
        this._container = append(container, $('.quick-input-tree'));
        this._renderer = this._register(this.instantiationService.createInstance(QuickInputTreeRenderer, hoverDelegate, this._onDidTriggerButton, this.onDidChangeCheckboxState));
        this._filter = this.instantiationService.createInstance(QuickInputTreeFilter);
        this._sorter = this._register(( new QuickInputTreeSorter()));
        this._tree = this._register(this.instantiationService.createInstance((WorkbenchObjectTree), 'QuickInputTree', this._container, ( new QuickInputTreeDelegate()), [this._renderer], {
            accessibilityProvider: ( new QuickTreeAccessibilityProvider(this.onDidChangeCheckboxState)),
            horizontalScrolling: false,
            multipleSelectionSupport: false,
            findWidgetEnabled: false,
            alwaysConsumeMouseWheel: true,
            hideTwistiesOfChildlessElements: true,
            renderIndentGuides: RenderIndentGuides.None,
            expandOnDoubleClick: true,
            expandOnlyOnTwistieClick: true,
            disableExpandOnSpacebar: true,
            sorter: this._sorter,
            filter: this._filter
        }));
        this.registerOnOpenListener();
    }
    get tree() {
        return this._tree;
    }
    get renderer() {
        return this._renderer;
    }
    get displayed() {
        return this._container.style.display !== 'none';
    }
    set displayed(value) {
        this._container.style.display = value ? '' : 'none';
    }
    get sortByLabel() {
        return this._sorter.sortByLabel;
    }
    set sortByLabel(value) {
        this._sorter.sortByLabel = value;
        this._tree.resort(null, true);
    }
    getActiveDescendant() {
        return this._tree.getHTMLElement().getAttribute('aria-activedescendant');
    }
    filter(input) {
        this._filter.filterValue = input;
        this._tree.refilter();
    }
    updateFilterOptions(options) {
        if (options.matchOnLabel !== undefined) {
            this._filter.matchOnLabel = options.matchOnLabel;
        }
        if (options.matchOnDescription !== undefined) {
            this._filter.matchOnDescription = options.matchOnDescription;
        }
        this._tree.refilter();
    }
    setTreeData(treeData) {
        const createTreeElement = (item) => {
            let children;
            if (item.children) {
                children = ( item.children.map(child => createTreeElement(child)));
                item.checked = getParentNodeState(children);
            }
            return {
                element: item,
                children,
                collapsible: !!children,
                collapsed: item.collapsed ?? ObjectTreeElementCollapseState.PreserveOrExpanded
            };
        };
        const treeElements = ( treeData.map(item => createTreeElement(item)));
        this._tree.setChildren(null, treeElements);
    }
    layout(maxHeight) {
        this._tree.getHTMLElement().style.maxHeight = maxHeight ? `${
        Math.floor(maxHeight / 44) * 44
            + 6}px` : '';
        this._tree.layout();
    }
    focus(what) {
        switch (what) {
            case QuickPickFocus.First:
                this._tree.scrollTop = 0;
                this._tree.focusFirst();
                break;
            case QuickPickFocus.Second: {
                this._tree.scrollTop = 0;
                let isSecondItem = false;
                this._tree.focusFirst(undefined, (e) => {
                    if (isSecondItem) {
                        return true;
                    }
                    isSecondItem = !isSecondItem;
                    return false;
                });
                break;
            }
            case QuickPickFocus.Last:
                this._tree.scrollTop = this._tree.scrollHeight;
                this._tree.focusLast();
                break;
            case QuickPickFocus.Next: {
                const prevFocus = this._tree.getFocus();
                this._tree.focusNext(undefined, false, undefined, (e) => {
                    this._tree.reveal(e.element);
                    return true;
                });
                const currentFocus = this._tree.getFocus();
                if (prevFocus.length && prevFocus[0] === currentFocus[0]) {
                    this._onLeave.fire();
                }
                break;
            }
            case QuickPickFocus.Previous: {
                const prevFocus = this._tree.getFocus();
                this._tree.focusPrevious(undefined, false, undefined, (e) => {
                    this._tree.reveal(e.element);
                    return true;
                });
                const currentFocus = this._tree.getFocus();
                if (prevFocus.length && prevFocus[0] === currentFocus[0]) {
                    this._onLeave.fire();
                }
                break;
            }
            case QuickPickFocus.NextPage:
                this._tree.focusNextPage(undefined, (e) => {
                    this._tree.reveal(e.element);
                    return true;
                });
                break;
            case QuickPickFocus.PreviousPage:
                this._tree.focusPreviousPage(undefined, (e) => {
                    this._tree.reveal(e.element);
                    return true;
                });
                break;
            case QuickPickFocus.NextSeparator:
            case QuickPickFocus.PreviousSeparator:
                return;
        }
    }
    registerOnOpenListener() {
        this._register(this._tree.onDidOpen(e => {
            const item = e.element;
            if (!item) {
                return;
            }
            if (item.disabled) {
                return;
            }
            if (item.pickable === false) {
                this._tree.setFocus([item]);
                this._onDidAccept.fire();
                return;
            }
            const newState = item.checked !== true;
            if ((item.checked ?? false) === newState) {
                return;
            }
            item.checked = newState;
            this._tree.rerender(item);
            const updateSet = ( new Set());
            const toUpdate = [...this._tree.getNode(item).children];
            while (toUpdate.length) {
                const pop = toUpdate.shift();
                if (pop?.element && !( updateSet.has(pop.element))) {
                    updateSet.add(pop.element);
                    if ((pop.element.checked ?? false) !== item.checked) {
                        pop.element.checked = item.checked;
                        this._tree.rerender(pop.element);
                    }
                    toUpdate.push(...pop.children);
                }
            }
            let parent = this._tree.getParentElement(item);
            while (parent) {
                const parentChildren = [...this._tree.getNode(parent).children];
                const newState = getParentNodeState(parentChildren);
                if ((parent.checked ?? false) !== newState) {
                    parent.checked = newState;
                    this._tree.rerender(parent);
                }
                parent = this._tree.getParentElement(parent);
            }
            this._onDidChangeCheckboxState.fire({
                item,
                checked: item.checked ?? false
            });
            this._onDidCheckedLeafItemsChange.fire(this.getCheckedLeafItems());
        }));
    }
    getCheckedLeafItems() {
        const lookedAt = ( new Set());
        const toLookAt = [...this._tree.getNode().children];
        const checkedItems = ( new Array());
        while (toLookAt.length) {
            const lookAt = toLookAt.shift();
            if (!lookAt?.element || ( lookedAt.has(lookAt.element))) {
                continue;
            }
            if (lookAt.element.checked) {
                lookedAt.add(lookAt.element);
                toLookAt.push(...lookAt.children);
                if (!lookAt.element.children) {
                    checkedItems.push(lookAt.element);
                }
            }
        }
        return checkedItems;
    }
    getActiveItems() {
        return this._tree.getFocus().filter((item) => item !== null);
    }
    check(element, checked) {
        if (element.checked === checked) {
            return;
        }
        element.checked = checked;
        this._onDidCheckedLeafItemsChange.fire(this.getCheckedLeafItems());
    }
    checkAll(checked) {
        const updated = ( new Set());
        const toUpdate = [...this._tree.getNode().children];
        let fireCheckedChangeEvent = false;
        while (toUpdate.length) {
            const update = toUpdate.shift();
            if (!update?.element || ( updated.has(update.element))) {
                continue;
            }
            if (update.element.checked !== checked) {
                fireCheckedChangeEvent = true;
                update.element.checked = checked;
                toUpdate.push(...update.children);
                updated.add(update.element);
                this._tree.rerender(update.element);
                this._onDidChangeCheckboxState.fire({
                    item: update.element,
                    checked: update.element.checked
                });
            }
        }
        if (fireCheckedChangeEvent) {
            this._onDidCheckedLeafItemsChange.fire(this.getCheckedLeafItems());
        }
    }
};
QuickInputTreeController = ( __decorate([
    ( __param(2, IInstantiationService))
], QuickInputTreeController));

export { QuickInputTreeController };
