// Copyright (c) 2000-2019 Ericsson Telecom AB Telecom AB                                                       //
// All rights reserved. This program and the accompanying materials are made available under the     //
// terms of the Eclipse Public License v2.0 which accompanies this distribution, and is available at //
// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html                                                         //
///////////////////////////////////////////////////////////////////////////////////////////////////////
function JsTreeUtils() {
    "use strict";
    
    this.getPath = function(node) {
        var path = [];
        var strpath = "";
        if (node.parents == undefined) {
            return {"path": path, "strpath": strpath};
        }
        var level = node.parents.length;
        var parent = $("#" + node.id);
        path.unshift(parent.parent().children().index(parent[0]));
        strpath = node.text;
        for (var i = 0; i < level; ++i) {
            parent = parent.parent().parent();
            if (parent.children()[1] != undefined) {
                path.unshift(parent.parent().children().index(parent[0]));
                strpath = parent.children()[1].text + "." + strpath;
            }
        }
        
        return {"path": path, "strpath": strpath};
    };
    
    function findOpenNodesInList(tree, nodes, open, path) {
        for (var i = 0; i < nodes.length; ++i) {
            path.push(i);
            if (tree.jstree("is_open", nodes[i])) {
                open.push(mcopy(path));
                findOpenNodesInList(tree, tree.jstree("get_node", nodes[i]).children, open, path);
            }
            path.pop();
        }
    }
    
    this.findOpenNodes = function(tree) {
        var id = "#";
        var open = [];
        var path = [];
        var children = tree.jstree("get_node", "#").children;
        if (children != undefined) {
            findOpenNodesInList(tree, children, open, path);
        }
        return open;
    };
    
    this.openNodes = function(tree, pathList) {
        if (pathList != undefined) {
            for (var i = 0; i < pathList.length; ++i) {
                var path = mcopy(pathList[i]);
                path.push(0);
                this.expandPath(tree, path);
            }
        }
    };
    
    this.getNodeIdFromPath = function(tree, path) {
        var id = "#";
        for (var i = 0; i < path.length; ++i) {
            var children = tree.jstree("get_node", id).children;
            if ((id !== "#" && tree.jstree("is_closed", id)) || children == undefined || children[path[i]] == undefined) {
                return false;
            }
            id = children[path[i]];
        }
        return id;
    };
    
    this.getLastNodeIdFromPath = function(tree, path) {
        var id = "#";
        for (var i = 0; i < path.length; ++i) {
            var children = tree.jstree("get_node", id).children;
            if ((id !== "#" && tree.jstree("is_closed", id)) || children == undefined || children[path[i]] == undefined) {
                break;
            }
            id = children[path[i]];
        }
        return id;
    };
    
    this.expandPath = function(tree, path) {
        var id = "#";
        for (var i = 0; i < path.length; ++i) {
            if (id !== "#" && tree.jstree("is_closed", id)) {
                tree.jstree("open_node", id);
            }
            var children = tree.jstree("get_node", id).children;
            if ((id !== "#" && tree.jstree("is_closed", id)) || children == undefined || children[path[i]] == undefined) {
                break;
            }
            id = children[path[i]];
        }
        return id;
    };
    
    this.getPathOfSelection = function(tree) {
        return this.getPath(tree.jstree("get_node", tree.jstree("get_selected"))).path;
    };
    
    this.isNodeFromTree = function(node, tree) {
        return tree.jstree("get_node", node.id);
    };
    
    this.isNodeIdFromTree = function(id, tree) {
        return tree.jstree("get_node", id);
    };
    
    this.isRoot = function(node) {
        return node.id === "#";
    };
    
    this.getDepth = function(node, tree) {
        return this.getPath(tree.jstree("get_node", node.id)).path.length;
    };
    
    this.hasSameParentInTree = function(node1, node2, tree) {
        var path1 = this.getPath(tree.jstree("get_node", node1.id)).path;
        var path2 = this.getPath(tree.jstree("get_node", node2.id)).path;
        return this.isNodeFromTree(node1, tree) && this.isNodeFromTree(node2, tree) && ((path1.length === 1 && path2.length === 1) || (path1[path1.length - 2] === path2[path2.length - 2]));
    };
    
    this.isTheParentOfNode = function(node, parent, tree) {
        // we could do something similar in the function above... does it work if the parent is "#"?
        return $("#" + node.id).parent().parent()[0].id === parent.id;
    };
    
    this.getIndexOfNode = function(node, tree) {
        var path = this.getPath(tree.jstree("get_node", node.id)).path;
        return path[path.length - 1];
    };
}