'use strict';

var filter = require('../../../../../../lodash-es@4.17.23/node_modules/lodash-es/filter.js');
var max = require('../../../../../../lodash-es@4.17.23/node_modules/lodash-es/max.js');
var map = require('../../../../../../lodash-es@4.17.23/node_modules/lodash-es/map.js');
var range = require('../../../../../../lodash-es@4.17.23/node_modules/lodash-es/range.js');
var sortBy = require('../../../../../../lodash-es@4.17.23/node_modules/lodash-es/sortBy.js');
var forEach = require('../../../../../../lodash-es@4.17.23/node_modules/lodash-es/forEach.js');
var has = require('../../../../../../lodash-es@4.17.23/node_modules/lodash-es/has.js');

/*
 * Assigns an initial order value for each node by performing a DFS search
 * starting from nodes in the first rank. Nodes are assigned an order in their
 * rank as they are first visited.
 *
 * This approach comes from Gansner, et al., "A Technique for Drawing Directed
 * Graphs."
 *
 * Returns a layering matrix with an array per layer and each layer sorted by
 * the order of its nodes.
 */
function initOrder(g) {
  var visited = {};
  var simpleNodes = filter.default(g.nodes(), function (v) {
    return !g.children(v).length;
  });
  var maxRank = max.default(
    map.default(simpleNodes, function (v) {
      return g.node(v).rank;
    }),
  );
  var layers = map.default(range.default(maxRank + 1), function () {
    return [];
  });

  function dfs(v) {
    if (has.default(visited, v)) return;
    visited[v] = true;
    var node = g.node(v);
    layers[node.rank].push(v);
    forEach.default(g.successors(v), dfs);
  }

  var orderedVs = sortBy.default(simpleNodes, function (v) {
    return g.node(v).rank;
  });
  forEach.default(orderedVs, dfs);

  return layers;
}

exports.initOrder = initOrder;
