/**
 * Created by Administrator on 2017/06/23.
 */

var _toString = Object.prototype.toString;

function isObject(obj) {
    return obj && _toString.call(obj) === "[object Object]";
}

function isArray(obj) {
    return Array.isArray ? Array.isArray(obj) : _toString.call(obj) === "[object Array]";
}

/**
 * 将列表转换成树结构。
 * 有第三个参数（节点映射）时，新传入的list会自动整合进原来的节点中。
 * 返回的始终为树的根节点列表（包含无法引用到父节点的节点）。
 * 其中每一个节点都有子节点属性（可能为空数组）。
 * 可以传入第三个参数（一个对象），来获取节点到ID的映射。
 * @param list
 * @param opts 字段映射配置对象。
 * @param map 一个用于接收节点HASH映射表的对象。（id到node的映射）
 * @return [Array] 根节点列表。
 */
function listToTree(list, opts, map) {
    var tree = [], isObj = isObject;
    isObj(opts) || (opts = {});
    if (isArray(list) && opts) {
        var childrenMap = {},
            nodeMap = isObj(map) ? map : {},
            i = 0, length = list.length,
            id = opts.idField || "id",
            pid = opts.pidField || "pid",
            child = opts.childField || "childNodes",
            matchRoot = opts.rootPidVal !== void 0,
            rootPidVal = opts.rootPidVal,
            node, nodeId, nodePid;
        while (i < length) {
            if (isObj(node = list[i++])) {
                if ((nodeId = node[id]) in nodeMap) {
                    // 已经存在的节点
                    // 替换为之前的节点
                    list[i - 1] = nodeMap[nodeId];
                    continue;
                }
                nodePid = node[pid];
                if (matchRoot ? nodePid === rootPidVal : (nodePid == void 0 || nodePid === "")) {
                    // 根节点
                }
                else if (nodeMap[nodePid]) {
                    // 在节点映射中已经存在父节点
                    // 将当前节点添加到其父节点的子节点列表中去
                    (childrenMap[nodePid] = nodeMap[nodePid][child] || []).push(node);
                }
                else {
                    // 将当前节点添加到其父节点的子节点列表中去
                    (childrenMap[nodePid] = childrenMap[nodePid] || []).push(node);
                }
                // 将当前节点的子节点列表引用到当前节点上
                node[child] = (childrenMap[nodeId] = childrenMap[nodeId] || []);
                nodeMap[nodeId] = node;
            }
            else {
                list[i - 1] = null;
            }
        }
        // 映射节点的父节点
        // 并合并出子树
        i = length;
        while (i--) {
            if (node = list[i]) {
                // 再次判定根节点是否为空
                if (node[pid] === null) {
                    // 根节点
                    tree.unshift(node);
                }
            }
            else {
                // 清除非有效的节点
                list.splice(i, 1);
            }
        }
        nodeMap = null;
    }
    else {

    }
    return tree;
}


export default listToTree;



