"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.calcTableColumnWidths = calcTableColumnWidths;
exports.convertProsemirrorTableNodeToArrayOfRows = convertProsemirrorTableNodeToArrayOfRows;
exports.getColumnWidths = getColumnWidths;
exports.hasMergedCell = hasMergedCell;
exports.isPositionNearTableRow = isPositionNearTableRow;
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
/**
 * Returns an array of column widths (0 if column width is undefined) of a given table node by scanning the **entire table**.
 *
 * Warning: the entire table is scanned and should only be used if where the table can be in a broken state such that rows have different number of cells (e.g. in **renderer**).
 * @param node - Table node
 * @example
 * ```ts
 * const columnWidths = getColumnWidths(tableNode);
 * console.log(columnWidths);
 * // Output: [100, 200, 300]
 * ```
 * @returns Array<number>
 */
function getColumnWidths(node) {
  var tableColumnWidths = [];
  node.forEach(function (row) {
    var currentTableWidth = [];
    row.forEach(function (cell) {
      var _ref = cell.attrs,
        colspan = _ref.colspan,
        colwidth = _ref.colwidth;
      // column has been resized, colWidth will be an array, can safely take values even if cell is merged
      if (Array.isArray(colwidth)) {
        currentTableWidth.push.apply(currentTableWidth, (0, _toConsumableArray2.default)(colwidth));
        // table has merged cells but no colWidth, so columns haven't been resized, default to 0
      } else if (colspan !== undefined && colspan > 1) {
        currentTableWidth.push.apply(currentTableWidth, (0, _toConsumableArray2.default)(Array(colspan).fill(0)));
        // no merged cells, no column resized, default to 0
      } else {
        currentTableWidth.push(0);
      }
    });
    if (currentTableWidth.length > tableColumnWidths.length) {
      tableColumnWidths = currentTableWidth;
    }
  });
  return tableColumnWidths;
}

/**
 * Returns an array of column widths (0 if column width is undefined) of a given table node by scanning the **first row**.
 *
 * Warning: is preferred and should be used if the table is not in a broken state (e.g. in **editor**).
 * @param node - Table node
 * @example
 * ```ts
 * const columnWidths = calcTableColumnWidths(tableNode);
 * console.log(columnWidths);
 * // Output: [100, 200, 300]
 * ```
 * @returns Array<number>
 */
function calcTableColumnWidths(node) {
  var firstRow = node.firstChild;
  var tableColumnWidths = [];
  if (firstRow) {
    firstRow.forEach(function (cell) {
      var _cell$attrs = cell.attrs,
        colspan = _cell$attrs.colspan,
        colwidth = _cell$attrs.colwidth;
      // column has been resized, colWidth will be an array, can safely take values even if cell is merged
      if (Array.isArray(colwidth)) {
        tableColumnWidths.push.apply(tableColumnWidths, (0, _toConsumableArray2.default)(colwidth));
        // table has merged cells but no colWidth, so columns haven't been resized, default to 0
      } else if (colspan > 1) {
        tableColumnWidths.push.apply(tableColumnWidths, (0, _toConsumableArray2.default)(Array(colspan).fill(0)));
        // no merged cells, no column resized, default to 0
      } else {
        tableColumnWidths.push(0);
      }
    });
  }
  return tableColumnWidths;
}

/**
 *
 * @param tableNode
 * @example
 */
function hasMergedCell(tableNode) {
  var hasSpan = false;
  tableNode.descendants(function (node) {
    if (node.type.name === 'tableRow') {
      return true;
    }
    var _node$attrs = node.attrs,
      colspan = _node$attrs.colspan,
      rowspan = _node$attrs.rowspan;
    if (colspan > 1 || rowspan > 1) {
      hasSpan = true;
    }
    return false;
  });
  return hasSpan;
}

/**
 *
 * @param tableNode
 * @example
 */
function convertProsemirrorTableNodeToArrayOfRows(tableNode) {
  var result = [];
  tableNode.forEach(function (rowNode) {
    if (rowNode.type.name === 'tableRow') {
      var row = [];
      rowNode.forEach(function (n) {
        return row.push(n);
      });
      result.push(row);
    }
  });
  return result;
}

/*
  isPositionNearTableRow()
  Returns true when a sibling node, or any  of the parent's sibling
  nodes are a tableRow
 */
/**
 *
 * @param pos
 * @param schema
 * @param direction
 * @example
 */
function isPositionNearTableRow(pos, schema, direction) {
  if (!schema.nodes.tableRow) {
    return false;
  }
  var doc = pos.doc;
  var resolved = pos;
  var sibling = direction === 'before' ? 'nodeBefore' : 'nodeAfter';
  while (resolved.depth > 0) {
    var _resolved$sibling;
    var siblingType = (_resolved$sibling = resolved[sibling]) === null || _resolved$sibling === void 0 ? void 0 : _resolved$sibling.type;
    if (siblingType === schema.nodes.tableRow) {
      return true;
    }
    resolved = doc.resolve(resolved[direction]());
  }
  return false;
}