import { buildGenerationTree, GENERATION_TREE_ROOT_NAME, } from "./GenerationTree";
export class SceneSnapshot {
    constructor(options) {
        this.snapshot = buildGenerationTree(options);
        this.apiUtil = options.apiUtil;
    }
    /**
     * Replaces all references to a comId with another one inside the snapshot
     *
     * @param {string} targetComId
     * @param {string} overwriteComId
     * @returns
     */
    replaceComId(targetComId, overwriteComId) {
        const node = this.getNode(targetComId);
        if (node === undefined) {
            return;
        }
        node.comId = overwriteComId;
        this.snapshot.set(overwriteComId, node);
        this.snapshot.delete(targetComId);
        if (node.children !== undefined) {
            for (const childComId of node.children) {
                const childNode = this.getNode(childComId);
                if (childNode.snapPoint !== undefined) {
                    childNode.snapPoint.foreignComId = overwriteComId;
                }
            }
        }
        for (const [, treeNode] of this.snapshot) {
            if (treeNode.children !== undefined) {
                for (let index = 0; index < treeNode.children.length; index++) {
                    if (treeNode.children[index] === targetComId) {
                        treeNode.children[index] = overwriteComId;
                        return;
                    }
                }
            }
        }
    }
    getRootElements() {
        return this.snapshot.get(GENERATION_TREE_ROOT_NAME).children;
    }
    getNode(comId) {
        return this.snapshot.get(comId);
    }
    getNewConnectionInfo(comId) {
        const node = this.snapshot.get(comId);
        if (node === undefined || node.snapPoint === undefined) {
            return "none";
        }
        const parentPoint = this.apiUtil.getPointByKey(node.snapPoint.foreignComId, node.snapPoint.foreignPointKey);
        const ownPoint = this.apiUtil.getPointByKey(comId, node.snapPoint.ownPointKey);
        if (ownPoint === undefined || parentPoint === undefined) {
            return "missing";
        }
        return {
            parentPoint,
            parentComId: node.snapPoint.foreignComId,
            ownPoint,
            ownComId: comId,
        };
    }
    restorePositionRecursively(comId) {
        this.restorePosition(comId);
        const node = this.getNode(comId);
        if (node && node.children) {
            for (const child of node.children) {
                this.restorePositionRecursively(child);
            }
        }
    }
    restorePosition(comId) {
        const connectionInfo = this.getNewConnectionInfo(comId);
        if (connectionInfo === "none" || connectionInfo === "missing") {
            return false;
        }
        this.apiUtil.placeArticleAtAttachPoint(connectionInfo.parentComId, connectionInfo.ownComId, connectionInfo.parentPoint, connectionInfo.ownPoint);
        return true;
    }
}
