"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var resolve_cell_borders_exports = {};
__export(resolve_cell_borders_exports, {
  calculateBorderPadding: () => calculateBorderPadding,
  getCornerOffset: () => getCornerOffset,
  getDisplayedBorderOnSide: () => getDisplayedBorderOnSide,
  resolveCellBorders: () => resolveCellBorders,
  resolveCellBordersPm: () => resolveCellBordersPm
});
module.exports = __toCommonJS(resolve_cell_borders_exports);
var import_colors = require("./../../_shared/colors.js");
var import_tablemap = require("../tiptap/tablemap.js");
const DEFAULT_COLOR = "var(--ricos-internal-table-border-color)";
const DEFAULT_WIDTH = 1;
const isTransparent = (color) => !color || color === import_colors.TRANSPARENT_HEX_COLOR;
const getCornerOffset = ({
  thisZ,
  perpZ,
  parallelZ,
  extAmount,
  isHorizontal,
  isStartCorner
}) => {
  if (extAmount === 0) {
    return 0;
  }
  if (parallelZ > 0) {
    if (parallelZ > thisZ) {
      return extAmount;
    } else if (parallelZ === thisZ) {
      if (perpZ > thisZ) {
        return extAmount;
      }
      return isStartCorner ? -extAmount : extAmount;
    }
  }
  if (thisZ > perpZ) {
    return -extAmount;
  } else if (thisZ < perpZ) {
    return extAmount;
  } else {
    return isHorizontal ? -extAmount : extAmount;
  }
};
function resolveCandidates(a, b) {
  if (!a && !b) {
    return null;
  }
  if (a && !b) {
    return a;
  }
  if (b && !a) {
    return b;
  }
  const ca = a;
  const cb = b;
  const aTransparent = isTransparent(ca.color);
  const bTransparent = isTransparent(cb.color);
  const aWidth = ca.width ?? 0;
  const bWidth = cb.width ?? 0;
  const aAbsent = aTransparent || aWidth === 0;
  const bAbsent = bTransparent || bWidth === 0;
  if (aTransparent && ca.isExplicit && !cb.isExplicit) {
    return ca;
  }
  if (bTransparent && cb.isExplicit && !ca.isExplicit) {
    return cb;
  }
  if (aAbsent && !bAbsent) {
    return cb;
  }
  if (!aAbsent && bAbsent) {
    return ca;
  }
  if (aAbsent && bAbsent) {
    return null;
  }
  if (aWidth !== bWidth) {
    return aWidth > bWidth ? ca : cb;
  }
  if (ca.isExplicit && !cb.isExplicit) {
    return ca;
  }
  if (!ca.isExplicit && cb.isExplicit) {
    return cb;
  }
  if (ca.spanSpecificity !== cb.spanSpecificity) {
    return ca.spanSpecificity < cb.spanSpecificity ? ca : cb;
  }
  const aPref = ca.side === "top" || ca.side === "left";
  const bPref = cb.side === "top" || cb.side === "left";
  if (aPref !== bPref) {
    return aPref ? ca : cb;
  }
  return ca.cellRef < cb.cellRef ? ca : cb;
}
function buildCellGrid(tableNode) {
  const rows = tableNode.nodes || [];
  const height = rows.length;
  if (height === 0) {
    return { cells: [], width: 0, height: 0, cellAt: () => null };
  }
  const gridInput = rows.map(
    (row) => (row.nodes || []).map((cell) => ({
      colspan: cell.tableCellData?.colspan ?? 1,
      rowspan: cell.tableCellData?.rowspan ?? 1
    }))
  );
  const map = import_tablemap.TableMap.fromGrid(gridInput);
  const cells = [];
  let cellIndex = 0;
  for (const rowNode of rows) {
    for (const cellNode of rowNode.nodes || []) {
      const placement = map.findCell(cellIndex);
      cells.push({
        ref: cellNode.id || `${placement.row}-${placement.col}`,
        row: placement.row,
        col: placement.col,
        rowspan: placement.rowspan,
        colspan: placement.colspan,
        colors: cellNode.tableCellData?.borderColors || {},
        widths: cellNode.tableCellData?.borderWidths || {}
      });
      cellIndex++;
    }
  }
  const cellAt = (row, col) => {
    if (row < 0 || row >= map.height || col < 0 || col >= map.width) {
      return null;
    }
    const idx = map.map[row * map.width + col];
    return cells[idx] ?? null;
  };
  return { cells, width: map.width, height: map.height, cellAt };
}
function createCandidate(cell, side, drawDefaultGrid, isHorizontal) {
  const colorKey = side;
  const widthKey = side;
  const color = cell.colors[colorKey] ?? (drawDefaultGrid ? DEFAULT_COLOR : "");
  const width = cell.widths[widthKey] ?? (drawDefaultGrid ? DEFAULT_WIDTH : 0);
  const spanSpecificity = isHorizontal ? cell.colspan : cell.rowspan;
  return {
    cellRef: cell.ref,
    side,
    color,
    width,
    spanSpecificity,
    isExplicit: cell.colors[colorKey] !== void 0 || cell.widths[widthKey] !== void 0,
    zIndex: calculateZIndex(width, color, isHorizontal)
  };
}
function resolveHorizontalEdge(above, below, drawDefaultGrid) {
  const candA = above ? createCandidate(above, "bottom", drawDefaultGrid, true) : null;
  const candB = below ? createCandidate(below, "top", drawDefaultGrid, true) : null;
  return resolveCandidates(candA, candB);
}
function resolveVerticalEdge(left, right, drawDefaultGrid) {
  const candL = left ? createCandidate(left, "right", drawDefaultGrid, false) : null;
  const candR = right ? createCandidate(right, "left", drawDefaultGrid, false) : null;
  return resolveCandidates(candL, candR);
}
function calculateZIndex(width, color, isHorizontal) {
  const isExplicit = color !== DEFAULT_COLOR;
  return Math.round(width * 100) + (isExplicit ? 50 : 0) + (isHorizontal ? 1 : 0);
}
function makeBorder({
  color,
  width,
  isHorizontal,
  extendStart,
  extendEnd,
  perpStartZ,
  perpEndZ,
  parallelStartZ,
  parallelEndZ
}) {
  if (width <= 0 || isTransparent(color)) {
    return null;
  }
  return {
    color,
    width,
    zIndex: calculateZIndex(width, color, isHorizontal),
    extendStart,
    extendEnd,
    perpStartZ,
    perpEndZ,
    parallelStartZ,
    parallelEndZ
  };
}
function resolveCellBordersSpacingMode(cells, drawDefaultGrid) {
  const result = /* @__PURE__ */ new Map();
  const def = drawDefaultGrid;
  cells.forEach((cell) => {
    const w = {
      top: cell.widths.top ?? (def ? DEFAULT_WIDTH : 0),
      bottom: cell.widths.bottom ?? (def ? DEFAULT_WIDTH : 0),
      left: cell.widths.left ?? (def ? DEFAULT_WIDTH : 0),
      right: cell.widths.right ?? (def ? DEFAULT_WIDTH : 0)
    };
    const c = {
      top: cell.colors.top ?? (def ? DEFAULT_COLOR : ""),
      bottom: cell.colors.bottom ?? (def ? DEFAULT_COLOR : ""),
      left: cell.colors.left ?? (def ? DEFAULT_COLOR : ""),
      right: cell.colors.right ?? (def ? DEFAULT_COLOR : "")
    };
    const leftZ = calculateZIndex(w.left, c.left, false);
    const rightZ = calculateZIndex(w.right, c.right, false);
    const topZ = calculateZIndex(w.top, c.top, true);
    const bottomZ = calculateZIndex(w.bottom, c.bottom, true);
    result.set(cell.ref, {
      top: makeBorder({
        color: c.top,
        width: w.top,
        isHorizontal: true,
        extendStart: w.left / 2,
        extendEnd: w.right / 2,
        perpStartZ: leftZ,
        perpEndZ: rightZ,
        parallelStartZ: 0,
        parallelEndZ: 0
      }),
      bottom: makeBorder({
        color: c.bottom,
        width: w.bottom,
        isHorizontal: true,
        extendStart: w.left / 2,
        extendEnd: w.right / 2,
        perpStartZ: leftZ,
        perpEndZ: rightZ,
        parallelStartZ: 0,
        parallelEndZ: 0
      }),
      left: makeBorder({
        color: c.left,
        width: w.left,
        isHorizontal: false,
        extendStart: w.top / 2,
        extendEnd: w.bottom / 2,
        perpStartZ: topZ,
        perpEndZ: bottomZ,
        parallelStartZ: 0,
        parallelEndZ: 0
      }),
      right: makeBorder({
        color: c.right,
        width: w.right,
        isHorizontal: false,
        extendStart: w.top / 2,
        extendEnd: w.bottom / 2,
        perpStartZ: topZ,
        perpEndZ: bottomZ,
        parallelStartZ: 0,
        parallelEndZ: 0
      })
    });
  });
  return result;
}
function resolveBordersFromGrid(cells, W, H, cellAt, drawDefaultGrid) {
  const result = /* @__PURE__ */ new Map();
  for (const cell of cells) {
    result.set(cell.ref, { top: null, right: null, bottom: null, left: null });
  }
  const horizontalEdges = [];
  const verticalEdges = [];
  for (let er = 0; er <= H; er++) {
    horizontalEdges[er] = new Array(W).fill(null);
  }
  for (let r = 0; r < H; r++) {
    verticalEdges[r] = new Array(W + 1).fill(null);
  }
  for (let er = 0; er <= H; er++) {
    for (let c = 0; c < W; c++) {
      const above = er > 0 ? cellAt(er - 1, c) : null;
      const below = er < H ? cellAt(er, c) : null;
      if (above && below && above.ref === below.ref) {
        continue;
      }
      horizontalEdges[er][c] = resolveHorizontalEdge(above, below, drawDefaultGrid);
    }
  }
  for (let r = 0; r < H; r++) {
    for (let ec = 0; ec <= W; ec++) {
      const left = ec > 0 ? cellAt(r, ec - 1) : null;
      const right = ec < W ? cellAt(r, ec) : null;
      if (left && right && left.ref === right.ref) {
        continue;
      }
      verticalEdges[r][ec] = resolveVerticalEdge(left, right, drawDefaultGrid);
    }
  }
  const getVerticalBorderExtension = (edgeRow, edgeCol) => {
    const above = edgeRow > 0 ? verticalEdges[edgeRow - 1]?.[edgeCol] : null;
    const below = edgeRow < H ? verticalEdges[edgeRow]?.[edgeCol] : null;
    const aboveWidth = above && !isTransparent(above.color) ? above.width : 0;
    const belowWidth = below && !isTransparent(below.color) ? below.width : 0;
    return Math.max(aboveWidth, belowWidth) / 2;
  };
  const getHorizontalBorderExtension = (edgeRow, edgeCol) => {
    const left = edgeCol > 0 ? horizontalEdges[edgeRow]?.[edgeCol - 1] : null;
    const right = edgeCol < W ? horizontalEdges[edgeRow]?.[edgeCol] : null;
    const leftWidth = left && !isTransparent(left.color) ? left.width : 0;
    const rightWidth = right && !isTransparent(right.color) ? right.width : 0;
    return Math.max(leftWidth, rightWidth) / 2;
  };
  const getVerticalMaxZ = (edgeRow, edgeCol) => {
    const vAbove = edgeRow > 0 ? verticalEdges[edgeRow - 1]?.[edgeCol] : null;
    const vBelow = edgeRow < H ? verticalEdges[edgeRow]?.[edgeCol] : null;
    const vAboveZ = vAbove && !isTransparent(vAbove.color) && vAbove.width > 0 ? vAbove.zIndex : 0;
    const vBelowZ = vBelow && !isTransparent(vBelow.color) && vBelow.width > 0 ? vBelow.zIndex : 0;
    return Math.max(vAboveZ, vBelowZ);
  };
  const getHorizontalMaxZ = (edgeRow, edgeCol) => {
    const hLeft = edgeCol > 0 ? horizontalEdges[edgeRow]?.[edgeCol - 1] : null;
    const hRight = edgeCol < W ? horizontalEdges[edgeRow]?.[edgeCol] : null;
    const hLeftZ = hLeft && !isTransparent(hLeft.color) && hLeft.width > 0 ? hLeft.zIndex : 0;
    const hRightZ = hRight && !isTransparent(hRight.color) && hRight.width > 0 ? hRight.zIndex : 0;
    return Math.max(hLeftZ, hRightZ);
  };
  const getAdjacentHorizontalZ = (row, col, atLeftCorner) => {
    const adjacent = atLeftCorner ? col > 0 ? horizontalEdges[row]?.[col - 1] : null : col < W ? horizontalEdges[row]?.[col] : null;
    return adjacent && !isTransparent(adjacent.color) && adjacent.width > 0 ? adjacent.zIndex : 0;
  };
  const getAdjacentVerticalZ = (row, col, atTopCorner) => {
    const adjacent = atTopCorner ? row > 0 ? verticalEdges[row - 1]?.[col] : null : row < H ? verticalEdges[row]?.[col] : null;
    return adjacent && !isTransparent(adjacent.color) && adjacent.width > 0 ? adjacent.zIndex : 0;
  };
  const findHorizontalEdgeWinner = (edgeRow, startCol, colSpan, cellRef) => {
    for (let c = startCol; c < startCol + colSpan; c++) {
      const edge = horizontalEdges[edgeRow]?.[c];
      if (edge && edge.cellRef === cellRef && !isTransparent(edge.color) && edge.width > 0) {
        return edge;
      }
    }
    return null;
  };
  const findVerticalEdgeWinner = (edgeCol, startRow, rowSpan, cellRef) => {
    for (let r = startRow; r < startRow + rowSpan; r++) {
      const edge = verticalEdges[r]?.[edgeCol];
      if (edge && edge.cellRef === cellRef && !isTransparent(edge.color) && edge.width > 0) {
        return edge;
      }
    }
    return null;
  };
  for (const cell of cells) {
    const borders = result.get(cell.ref);
    const { row, col, rowspan, colspan } = cell;
    const topEdge = findHorizontalEdgeWinner(row, col, colspan, cell.ref);
    if (topEdge) {
      borders.top = makeBorder({
        color: topEdge.color,
        width: topEdge.width,
        isHorizontal: true,
        extendStart: getVerticalBorderExtension(row, col),
        extendEnd: getVerticalBorderExtension(row, col + colspan),
        perpStartZ: getVerticalMaxZ(row, col),
        perpEndZ: getVerticalMaxZ(row, col + colspan),
        parallelStartZ: getAdjacentHorizontalZ(row, col, true),
        parallelEndZ: getAdjacentHorizontalZ(row, col + colspan, false)
      });
    }
    const bottomEdge = findHorizontalEdgeWinner(row + rowspan, col, colspan, cell.ref);
    if (bottomEdge) {
      borders.bottom = makeBorder({
        color: bottomEdge.color,
        width: bottomEdge.width,
        isHorizontal: true,
        extendStart: getVerticalBorderExtension(row + rowspan, col),
        extendEnd: getVerticalBorderExtension(row + rowspan, col + colspan),
        perpStartZ: getVerticalMaxZ(row + rowspan, col),
        perpEndZ: getVerticalMaxZ(row + rowspan, col + colspan),
        parallelStartZ: getAdjacentHorizontalZ(row + rowspan, col, true),
        parallelEndZ: getAdjacentHorizontalZ(row + rowspan, col + colspan, false)
      });
    }
    const leftEdge = findVerticalEdgeWinner(col, row, rowspan, cell.ref);
    if (leftEdge) {
      borders.left = makeBorder({
        color: leftEdge.color,
        width: leftEdge.width,
        isHorizontal: false,
        extendStart: getHorizontalBorderExtension(row, col),
        extendEnd: getHorizontalBorderExtension(row + rowspan, col),
        perpStartZ: getHorizontalMaxZ(row, col),
        perpEndZ: getHorizontalMaxZ(row + rowspan, col),
        parallelStartZ: getAdjacentVerticalZ(row, col, true),
        parallelEndZ: getAdjacentVerticalZ(row + rowspan, col, false)
      });
    }
    const rightEdge = findVerticalEdgeWinner(col + colspan, row, rowspan, cell.ref);
    if (rightEdge) {
      borders.right = makeBorder({
        color: rightEdge.color,
        width: rightEdge.width,
        isHorizontal: false,
        extendStart: getHorizontalBorderExtension(row, col + colspan),
        extendEnd: getHorizontalBorderExtension(row + rowspan, col + colspan),
        perpStartZ: getHorizontalMaxZ(row, col + colspan),
        perpEndZ: getHorizontalMaxZ(row + rowspan, col + colspan),
        parallelStartZ: getAdjacentVerticalZ(row, col + colspan, true),
        parallelEndZ: getAdjacentVerticalZ(row + rowspan, col + colspan, false)
      });
    }
  }
  return result;
}
function resolveCellBorders(tableNode, options = {}) {
  const { drawDefaultGrid = true, cellSpacing = 0 } = options;
  const { cells, width, height, cellAt } = buildCellGrid(tableNode);
  if (cellSpacing > 0) {
    return resolveCellBordersSpacingMode(cells, drawDefaultGrid);
  }
  return resolveBordersFromGrid(cells, width, height, cellAt, drawDefaultGrid);
}
function calculateBorderPadding(tableNode) {
  let maxStart = 1, maxEnd = 1, maxTop = 1, maxBottom = 1;
  if (tableNode.nodes) {
    const rows = tableNode.nodes;
    const firstRow = rows[0];
    const lastRow = rows[rows.length - 1];
    if (firstRow?.nodes) {
      for (const cell of firstRow.nodes) {
        maxTop = Math.max(maxTop, cell.tableCellData?.borderWidths?.top ?? 1);
      }
    }
    if (lastRow?.nodes) {
      for (const cell of lastRow.nodes) {
        maxBottom = Math.max(maxBottom, cell.tableCellData?.borderWidths?.bottom ?? 1);
      }
    }
    for (const row of rows) {
      if (!row.nodes) {
        continue;
      }
      const firstCell = row.nodes[0];
      const lastCell = row.nodes[row.nodes.length - 1];
      if (firstCell) {
        maxStart = Math.max(maxStart, firstCell.tableCellData?.borderWidths?.left ?? 1);
      }
      if (lastCell) {
        maxEnd = Math.max(maxEnd, lastCell.tableCellData?.borderWidths?.right ?? 1);
      }
    }
  }
  return {
    start: Math.ceil(maxStart / 2),
    end: Math.ceil(maxEnd / 2),
    top: Math.ceil(maxTop / 2),
    bottom: Math.ceil(maxBottom / 2)
  };
}
function buildCellGridPm(tableNode) {
  if (tableNode.childCount === 0) {
    return { cells: [], width: 0, height: 0, cellAt: () => null };
  }
  const map = import_tablemap.TableMap.get(tableNode);
  const cells = [];
  const cellsByPos = /* @__PURE__ */ new Map();
  map.forEachCell((cellPos, placement) => {
    const cellNode = tableNode.nodeAt(cellPos);
    if (!cellNode || !cellNode.type.spec.tableRole) {
      return;
    }
    const info = {
      ref: cellNode.attrs.id || `${placement.row}-${placement.col}`,
      row: placement.row,
      col: placement.col,
      rowspan: placement.rowspan,
      colspan: placement.colspan,
      colors: cellNode.attrs.borderColors || {},
      widths: cellNode.attrs.borderWidths || {}
    };
    cells.push(info);
    cellsByPos.set(cellPos, info);
  });
  const cellAt = (row, col) => {
    if (row < 0 || row >= map.height || col < 0 || col >= map.width) {
      return null;
    }
    return cellsByPos.get(map.map[row * map.width + col]) ?? null;
  };
  return { cells, width: map.width, height: map.height, cellAt };
}
function resolveCellBordersPm(tableNode, options = {}) {
  const { drawDefaultGrid = true, cellSpacing = 0 } = options;
  const { cells, width, height, cellAt } = buildCellGridPm(tableNode);
  if (cellSpacing > 0) {
    return resolveCellBordersSpacingMode(cells, drawDefaultGrid);
  }
  return resolveBordersFromGrid(cells, width, height, cellAt, drawDefaultGrid);
}
const OPPOSITE_BORDER_SIDE = {
  top: "bottom",
  bottom: "top",
  left: "right",
  right: "left"
};
function getDisplayedBorderOnSide(resolved, tableNode, cellId, cell, side) {
  const own = resolved.get(cellId)?.[side] ?? null;
  if (own) {
    return own;
  }
  const map = import_tablemap.TableMap.get(tableNode);
  const nRow = side === "top" ? cell.row - 1 : side === "bottom" ? cell.row + cell.rowspan : cell.row;
  const nCol = side === "left" ? cell.col - 1 : side === "right" ? cell.col + cell.colspan : cell.col;
  if (nRow < 0 || nRow >= map.height || nCol < 0 || nCol >= map.width) {
    return null;
  }
  const neighbour = tableNode.nodeAt(map.map[nRow * map.width + nCol]);
  const neighbourId = neighbour?.attrs.id;
  return neighbourId ? resolved.get(neighbourId)?.[OPPOSITE_BORDER_SIDE[side]] ?? null : null;
}
//# sourceMappingURL=resolve-cell-borders.js.map
