"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var Logger_1 = require("./Logger");
var Logger = Logger_1.Logger.createSubLogger("Updater");
/**
 * Updates articles inside of the gfx scene
 *
 * A single generation consists of either positionally unrelated elements (root elements to be specific) or an elements children + right neighbor
 * Articles of one generation will be updated in parallel
 *
 * @param {UpdateSceneParams} params
 * @returns {Promise<void>} A list of all articles which have been added to the scene
 */
exports.updateArticles = function (_a) {
    var snapshot = _a.snapshot, articles = _a.articles, loadGeometry = _a.loadGeometry, executeParentActions = _a.executeParentActions, executeNeighborActions = _a.executeNeighborActions, deleteArticleAndChildren = _a.deleteArticleAndChildren, updateArticlePosition = _a.updateArticlePosition;
    return tslib_1.__awaiter(void 0, void 0, void 0, function () {
        var promises, updateTree, entryRoots;
        return tslib_1.__generator(this, function (_b) {
            switch (_b.label) {
                case 0:
                    promises = [];
                    updateTree = function (snapshot, comIds, level, parentPromise) {
                        var e_1, _a;
                        var _loop_1 = function (comId) {
                            // every article that has been changed requires a gfx update regardless of later changes
                            var requiresGfxUpdate = articles.indexOf(comId) > -1;
                            // the snapshotted original node
                            var node = snapshot.getNode(comId);
                            var updatePromise = parentPromise
                                .then(function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
                                var postParentUpdateConnectionInfo, didChange, didChange, postUpdateConnectionInfo, err_1;
                                return tslib_1.__generator(this, function (_a) {
                                    switch (_a.label) {
                                        case 0:
                                            postParentUpdateConnectionInfo = snapshot.getNewConnectionInfo(comId);
                                            // check for a valid connection info and a level of larger than 0
                                            if (level > 0 &&
                                                postParentUpdateConnectionInfo !== "none" &&
                                                node.snapPoint.type === "family") {
                                                // every article beyond level 0 has to have some kind of relation with the parent. if a connection is missing -> the parent has been deleted or the point is invalid
                                                if (postParentUpdateConnectionInfo === "missing") {
                                                    Logger.error("Did not find previous attach point for " + comId);
                                                    return [2 /*return*/, deleteArticleAndChildren(comId)];
                                                }
                                            }
                                            if (!(typeof postParentUpdateConnectionInfo === "object" &&
                                                postParentUpdateConnectionInfo.parentPoint
                                                    .componentId !== undefined)) return [3 /*break*/, 2];
                                            return [4 /*yield*/, executeParentActions(postParentUpdateConnectionInfo.parentPoint
                                                    .componentId, comId)];
                                        case 1:
                                            didChange = _a.sent();
                                            // if the configuration updated as a result of the action execution -> the gfx has to be updateed regardless of initial value
                                            requiresGfxUpdate = requiresGfxUpdate || didChange;
                                            _a.label = 2;
                                        case 2:
                                            if (!(typeof postParentUpdateConnectionInfo === "object")) return [3 /*break*/, 4];
                                            return [4 /*yield*/, executeNeighborActions(comId)];
                                        case 3:
                                            didChange = _a.sent();
                                            requiresGfxUpdate = requiresGfxUpdate || didChange;
                                            _a.label = 4;
                                        case 4:
                                            postUpdateConnectionInfo = postParentUpdateConnectionInfo;
                                            if (!requiresGfxUpdate) return [3 /*break*/, 8];
                                            _a.label = 5;
                                        case 5:
                                            _a.trys.push([5, 7, , 8]);
                                            return [4 /*yield*/, loadGeometry(comId)];
                                        case 6:
                                            _a.sent();
                                            postUpdateConnectionInfo = snapshot.getNewConnectionInfo(comId);
                                            return [3 /*break*/, 8];
                                        case 7:
                                            err_1 = _a.sent();
                                            throw err_1;
                                        case 8:
                                            // if there was a connection and a previous gfx representation -> update the article's position according to the snap point
                                            if (typeof postUpdateConnectionInfo === "object") {
                                                updateArticlePosition(postUpdateConnectionInfo.parentComId, postUpdateConnectionInfo.ownComId, postUpdateConnectionInfo.parentPoint, postUpdateConnectionInfo.ownPoint);
                                            }
                                            return [2 /*return*/];
                                    }
                                });
                            }); })
                                .catch(function (err) { return Logger.error(err); });
                            // add this promise to the list of all promises
                            promises.push(updatePromise);
                            // if an element has children -> update the children
                            if (node && node.children && node.children.length > 0) {
                                updateTree(snapshot, node.children, level + 1, updatePromise);
                            }
                        };
                        try {
                            for (var comIds_1 = tslib_1.__values(comIds), comIds_1_1 = comIds_1.next(); !comIds_1_1.done; comIds_1_1 = comIds_1.next()) {
                                var comId = comIds_1_1.value;
                                _loop_1(comId);
                            }
                        }
                        catch (e_1_1) { e_1 = { error: e_1_1 }; }
                        finally {
                            try {
                                if (comIds_1_1 && !comIds_1_1.done && (_a = comIds_1.return)) _a.call(comIds_1);
                            }
                            finally { if (e_1) throw e_1.error; }
                        }
                    };
                    entryRoots = snapshot.getRootElements();
                    // start updating the tree starting with the root elements
                    updateTree(snapshot, entryRoots, 0, Promise.resolve());
                    return [4 /*yield*/, Promise.all(promises)];
                case 1:
                    _b.sent();
                    return [2 /*return*/];
            }
        });
    });
};
