(function (factory) {
    if (typeof module === "object" && typeof module.exports === "object") {
        var v = factory(require, exports);
        if (v !== undefined) module.exports = v;
    }
    else if (typeof define === "function" && define.amd) {
        define(["require", "exports", "tslib"], factory);
    }
})(function (require, exports) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.changeTitle = exports.moveNode = void 0;
    var tslib_1 = require("tslib");
    var removeNode = function (tree, targetId) {
        var removedNode;
        if (!tree) {
            return undefined;
        }
        var walkOnTree = function (walkTree, walkTargetId) {
            var filteredTree = walkTree === null || walkTree === void 0 ? void 0 : walkTree.filter(function (node) {
                if (node.id === walkTargetId) {
                    removedNode = node;
                    return false;
                }
                return true;
            });
            return filteredTree === null || filteredTree === void 0 ? void 0 : filteredTree.map(function (node) {
                var elements = node.elements, nodeWithoutElements = (0, tslib_1.__rest)(node, ["elements"]);
                var returnObj = (0, tslib_1.__assign)((0, tslib_1.__assign)({}, nodeWithoutElements), { elements: [] });
                if (elements === null || elements === void 0 ? void 0 : elements.length) {
                    returnObj.elements = walkOnTree(elements, walkTargetId);
                }
                else {
                    returnObj.elements = [];
                }
                return returnObj;
            });
        };
        var treeWithoutRemovedNode = walkOnTree(tree, targetId);
        if (removedNode && treeWithoutRemovedNode) {
            return [removedNode, treeWithoutRemovedNode];
        }
        return undefined;
    };
    var insertNodeIntoAnotherNode = function (tree, nodeToInsert, whereToInsertId) {
        var walkOnTree = function (walkTree, walkNodeToInsert, walkWhereToInsert) {
            return walkTree.map(function (node) {
                var elements = node.elements, nodeWithoutElements = (0, tslib_1.__rest)(node, ["elements"]);
                var newNodeState = (0, tslib_1.__assign)({}, nodeWithoutElements);
                newNodeState.elements = [];
                if (elements && node.id === walkWhereToInsert) {
                    newNodeState.elements = (0, tslib_1.__spreadArray)((0, tslib_1.__spreadArray)([], (0, tslib_1.__read)(elements), false), [walkNodeToInsert], false);
                }
                else if (elements && elements.length) {
                    newNodeState.elements = walkOnTree(elements, walkNodeToInsert, walkWhereToInsert);
                }
                else {
                    newNodeState.elements = [];
                }
                return newNodeState;
            });
        };
        if (whereToInsertId === "root") {
            tree.push(nodeToInsert);
        }
        return walkOnTree(tree, nodeToInsert, whereToInsertId);
    };
    var moveNode = function (tree, whatToMoveId, whereToMoveId) {
        if (whatToMoveId && whereToMoveId) {
            var newTree = removeNode(tree, +whatToMoveId);
            if (newTree) {
                var _a = (0, tslib_1.__read)(newTree, 2), nodeWithGivenUniqueId = _a[0], treeWithoutNodeWithGivenId = _a[1];
                return insertNodeIntoAnotherNode(treeWithoutNodeWithGivenId, nodeWithGivenUniqueId, whereToMoveId);
            }
        }
        return undefined;
    };
    exports.moveNode = moveNode;
    var changeTitle = function (tree, nodeId, newTitle) {
        return tree === null || tree === void 0 ? void 0 : tree.map(function (node) {
            if (node.id === nodeId) {
                return (0, tslib_1.__assign)((0, tslib_1.__assign)({}, node), { title: newTitle });
            }
            else if (node.elements) {
                return (0, tslib_1.__assign)((0, tslib_1.__assign)({}, node), { elements: (0, exports.changeTitle)(node.elements, nodeId, newTitle) });
            }
            else {
                return node;
            }
        });
    };
    exports.changeTitle = changeTitle;
});
