"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.findOrderInTremauxTree = void 0;
/**
 * This is used to determine the start and end of a selection range so
 * we can get the nodes between the two border nodes.
 *
 * It finds the nodes' common ancestor using
 * a naive implementation of a lowest common ancestor algorithm
 * (https://en.wikipedia.org/wiki/Lowest_common_ancestor).
 * Then compares the ancestor's 2 children that are ancestors of nodeA and NodeB
 * so we can compare their indexes to work out which node comes first in a depth first search.
 * (https://en.wikipedia.org/wiki/Depth-first_search)
 *
 * Another way to put it is which node is shallower in a trémaux tree
 * https://en.wikipedia.org/wiki/Tr%C3%A9maux_tree
 */
const findOrderInTremauxTree = (instance, nodeAId, nodeBId) => {
  if (nodeAId === nodeBId) {
    return [nodeAId, nodeBId];
  }
  const nodeA = instance.getNode(nodeAId);
  const nodeB = instance.getNode(nodeBId);
  if (nodeA.parentId === nodeB.id || nodeB.parentId === nodeA.id) {
    return nodeB.parentId === nodeA.id ? [nodeA.id, nodeB.id] : [nodeB.id, nodeA.id];
  }
  const aFamily = [nodeA.id];
  const bFamily = [nodeB.id];
  let aAncestor = nodeA.parentId;
  let bAncestor = nodeB.parentId;
  let aAncestorIsCommon = bFamily.indexOf(aAncestor) !== -1;
  let bAncestorIsCommon = aFamily.indexOf(bAncestor) !== -1;
  let continueA = true;
  let continueB = true;
  while (!bAncestorIsCommon && !aAncestorIsCommon) {
    if (continueA) {
      aFamily.push(aAncestor);
      aAncestorIsCommon = bFamily.indexOf(aAncestor) !== -1;
      continueA = aAncestor !== null;
      if (!aAncestorIsCommon && continueA) {
        aAncestor = instance.getNode(aAncestor).parentId;
      }
    }
    if (continueB && !aAncestorIsCommon) {
      bFamily.push(bAncestor);
      bAncestorIsCommon = aFamily.indexOf(bAncestor) !== -1;
      continueB = bAncestor !== null;
      if (!bAncestorIsCommon && continueB) {
        bAncestor = instance.getNode(bAncestor).parentId;
      }
    }
  }
  const commonAncestor = aAncestorIsCommon ? aAncestor : bAncestor;
  const ancestorFamily = instance.getChildrenIds(commonAncestor);
  const aSide = aFamily[aFamily.indexOf(commonAncestor) - 1];
  const bSide = bFamily[bFamily.indexOf(commonAncestor) - 1];
  return ancestorFamily.indexOf(aSide) < ancestorFamily.indexOf(bSide) ? [nodeAId, nodeBId] : [nodeBId, nodeAId];
};
exports.findOrderInTremauxTree = findOrderInTremauxTree;