/**
 * Type-specific predicates that vary between regular lists and task lists.
 */

/**
 * Flattens a list-like PM structure (regular list or task list) into an
 * array of content-bearing items with computed depths.
 *
 * Uses `doc.nodesBetween` to walk the tree and delegates type-specific
 * decisions to the provided predicates. The core algorithm — selection
 * intersection, depth adjustment, index tracking — is shared.
 */
export function flattenList(options, predicates) {
  var doc = options.doc,
    rootListStart = options.rootListStart,
    rootListEnd = options.rootListEnd,
    selectionFrom = options.selectionFrom,
    selectionTo = options.selectionTo,
    indentDelta = options.indentDelta,
    maxDepth = options.maxDepth;
  var isContentNode = predicates.isContentNode,
    getSelectionBounds = predicates.getSelectionBounds,
    getDepth = predicates.getDepth;
  var items = [];
  var startIndex = -1;
  var endIndex = -1;
  var exceedsMaxDepth = false;
  var rootDepth = doc.resolve(rootListStart).depth;
  doc.nodesBetween(rootListStart, rootListEnd, function (node, pos, parent) {
    if (!isContentNode(node, parent) || parent == null) {
      return true;
    }
    var _getSelectionBounds = getSelectionBounds(node, pos),
      start = _getSelectionBounds.start,
      end = _getSelectionBounds.end;
    var isSelected = selectionFrom === selectionTo ? selectionFrom >= start && selectionFrom <= end : start < selectionTo && end > selectionFrom;
    var resolvedDepth = doc.resolve(pos).depth;
    var depth = getDepth(resolvedDepth, rootDepth) + (isSelected ? indentDelta : 0);
    items.push({
      node: node,
      pos: pos,
      depth: depth,
      isSelected: isSelected,
      listType: parent.type.name,
      parentListAttrs: parent.attrs
    });
    if (isSelected) {
      var index = items.length - 1;
      if (startIndex === -1) {
        startIndex = index;
      }
      endIndex = index;
      if (maxDepth != null && depth >= maxDepth) {
        exceedsMaxDepth = true;
      }
    }
    return true;
  });
  if (items.length === 0 || startIndex === -1 || exceedsMaxDepth) {
    return null;
  }
  return {
    items: items,
    startIndex: startIndex,
    endIndex: endIndex
  };
}