"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TreeStateWatcher = void 0;
const ide_utils_1 = require("@opensumi/ide-utils");
const types_1 = require("./types");
class TreeStateWatcher {
    constructor(treeState, atSurfaceExpandedDirsOnly = false) {
        this._disposed = false;
        this.disposables = new ide_utils_1.DisposableCollection();
        this.onDidTreeStateChangeEmitter = new ide_utils_1.Emitter();
        this.currentState = {
            specVersion: 1,
            scrollPosition: 0,
            expandedDirectories: {
                atSurface: [],
                buried: [],
            },
        };
        this.disposables.push(treeState.onChangeScrollOffset((newOffset) => {
            this.currentState.scrollPosition = newOffset;
            this.onDidTreeStateChangeEmitter.fire(types_1.TreeStateWatcherChangeType.ScrollOffset);
        }));
        this.disposables.push(treeState.onDidChangeRelativePath(({ prevPath, newPath }) => {
            let shouldNotify = false;
            const surfaceSets = new Set(this.currentState.expandedDirectories.atSurface);
            if (surfaceSets.has(prevPath)) {
                surfaceSets.delete(prevPath);
                surfaceSets.add(newPath);
                shouldNotify = true;
            }
            this.currentState.expandedDirectories.atSurface = Array.from(surfaceSets);
            if (atSurfaceExpandedDirsOnly) {
                const buriedSets = new Set(this.currentState.expandedDirectories.buried);
                if (buriedSets.has(prevPath)) {
                    surfaceSets.delete(prevPath);
                    surfaceSets.add(newPath);
                    shouldNotify = true;
                }
                this.currentState.expandedDirectories.buried = Array.from(buriedSets);
            }
            if (shouldNotify) {
                this.onDidTreeStateChangeEmitter.fire(types_1.TreeStateWatcherChangeType.PathsUpdated);
            }
        }));
        this.disposables.push(treeState.onDidChangeExpansionState(({ relativePath, isExpanded, isVisibleAtSurface }) => {
            let shouldNotify = false;
            const surfaceSets = new Set(this.currentState.expandedDirectories.atSurface);
            const buriedSets = new Set(this.currentState.expandedDirectories.buried);
            if (surfaceSets.has(relativePath) && (!isExpanded || !isVisibleAtSurface)) {
                surfaceSets.delete(relativePath);
                // 该目录下的子目录需要变为buried状态
                const restSurfaceArray = Array.from(surfaceSets);
                const pathsShouldBeBuried = restSurfaceArray.filter((rest) => rest.indexOf(relativePath) >= 0);
                for (const path of pathsShouldBeBuried) {
                    surfaceSets.delete(path);
                    if (!buriedSets.has(path)) {
                        buriedSets.add(path);
                    }
                }
                shouldNotify = true;
            }
            else if (isExpanded && isVisibleAtSurface) {
                surfaceSets.add(relativePath);
                shouldNotify = true;
            }
            this.currentState.expandedDirectories.atSurface = Array.from(surfaceSets);
            if (!atSurfaceExpandedDirsOnly) {
                if (buriedSets.has(relativePath) && (!isExpanded || isVisibleAtSurface)) {
                    buriedSets.delete(relativePath);
                    shouldNotify = true;
                }
                else if (isExpanded && !isVisibleAtSurface) {
                    buriedSets.add(relativePath);
                    shouldNotify = true;
                }
                this.currentState.expandedDirectories.buried = Array.from(buriedSets);
            }
            if (shouldNotify) {
                this.onDidTreeStateChangeEmitter.fire(types_1.TreeStateWatcherChangeType.DirExpansionState);
            }
        }));
    }
    get onDidChange() {
        return this.onDidTreeStateChangeEmitter.event;
    }
    dispose() {
        if (this._disposed) {
            return;
        }
        this._disposed = true;
        this.disposables.dispose();
    }
    snapshot() {
        return {
            ...this.currentState,
            expandedDirectories: {
                atSurface: this.currentState.expandedDirectories.atSurface.slice(),
                buried: this.currentState.expandedDirectories.buried.slice(),
            },
        };
    }
    toString() {
        return JSON.stringify(this.currentState);
    }
}
exports.TreeStateWatcher = TreeStateWatcher;
//# sourceMappingURL=TreeStateWatcher.js.map