import { TableMap } from "./tablemap.js";
import { findTable } from "./utilities/find-table.js";
import { isRicosCellSelection } from "./utilities/is-selection-type.js";
class TableQuery {
  static of(selection) {
    const table = findTable(selection);
    if (!table) {
      return null;
    }
    return new TableQuery(selection, table);
  }
  constructor(selection, table) {
    this.selection = selection;
    this.table = table;
    this.map = TableMap.get(this.table.node);
  }
  getStartPos() {
    return this.table.start;
  }
  getHeight() {
    return this.map.height;
  }
  getWidth() {
    return this.map.width;
  }
  getMap() {
    return this.map.map;
  }
  getNode() {
    return this.table.node;
  }
  getRowsIndexesInSelection() {
    const rows = [];
    if (this.selection && isRicosCellSelection(this.selection)) {
      this.selection.forEachCell((node, pos) => {
        const cell = this.map.findCell(pos - this.getStartPos());
        !rows.includes(cell.row) && rows.push(cell.row);
      });
    }
    return rows;
  }
  getColsIndexesInSelection() {
    const cols = [];
    if (this.selection && isRicosCellSelection(this.selection)) {
      this.selection.forEachCell((node, pos) => {
        const cell = this.map.findCell(pos - this.getStartPos());
        !cols.includes(cell.col) && cols.push(cell.col);
      });
    }
    return cols;
  }
  getSelectionRowRange() {
    if (!this.selection || !isRicosCellSelection(this.selection)) {
      return null;
    }
    let first = Infinity;
    let last = -1;
    this.selection.forEachCell((node, pos) => {
      const cell = this.map.findCell(pos - this.getStartPos());
      first = Math.min(first, cell.row);
      last = Math.max(last, cell.row + cell.rowspan - 1);
    });
    return first <= last ? { first, last } : null;
  }
  getSelectionColRange() {
    if (!this.selection || !isRicosCellSelection(this.selection)) {
      return null;
    }
    let first = Infinity;
    let last = -1;
    this.selection.forEachCell((node, pos) => {
      const cell = this.map.findCell(pos - this.getStartPos());
      first = Math.min(first, cell.col);
      last = Math.max(last, cell.col + cell.colspan - 1);
    });
    return first <= last ? { first, last } : null;
  }
  getDomWidthInSelection(view) {
    const cols = this.getColsIndexesInSelection();
    let totalWidth = 0;
    const dom = view.domAtPos(this.getStartPos() - 1);
    const tableNode = dom.node.childNodes[dom.offset].firstChild;
    if (tableNode) {
      const colsgroup = tableNode.firstChild;
      Array.from(colsgroup?.childNodes || []).forEach(
        (col, index) => cols.includes(index) && (totalWidth += col.offsetWidth)
      );
    }
    return totalWidth;
  }
  getCellNeighbors(cellPos) {
    const cellRelativePos = cellPos - this.getStartPos();
    const map = this.getMap();
    const cellIndex = map.indexOf(cellRelativePos);
    const width = this.getWidth();
    const height = this.getHeight();
    const neighbors = {};
    cellIndex % width !== 0 && (neighbors.left = map[cellIndex - 1]);
    (cellIndex + 1) % width !== 0 && (neighbors.right = map[cellIndex + 1]);
    cellIndex >= width && (neighbors.top = map[cellIndex - width]);
    cellIndex < height * width - width && (neighbors.bottom = map[cellIndex + width]);
    return neighbors;
  }
  isRectSelected(rect) {
    const map = this.map;
    const start = this.getStartPos();
    const cells = map.cellsInRect(rect);
    if (this.selection && isRicosCellSelection(this.selection)) {
      const selectedCells = this.selection.cellPositions;
      return cells.every((cell) => selectedCells.has(cell + start));
    }
    return false;
  }
  isColumnSelected(columnIndex) {
    const map = this.map;
    return this.isRectSelected({
      left: columnIndex,
      right: columnIndex + 1,
      top: 0,
      bottom: map.height
    });
  }
  isRowSelected(rowIndex) {
    const map = this.map;
    return this.isRectSelected({
      left: 0,
      right: map.width,
      top: rowIndex,
      bottom: rowIndex + 1
    });
  }
  isTableSelected() {
    const map = this.map;
    return this.isRectSelected({
      left: 0,
      right: map.width,
      top: 0,
      bottom: map.height
    });
  }
  getRowsHeight(view) {
    const dom = view.domAtPos(this.getStartPos() - 1);
    const tableNode = dom.node.childNodes[dom.offset].firstChild;
    return tableNode ? Array.from(tableNode.querySelectorAll("tbody > tr")).map(
      (node) => node.offsetHeight
    ) : [];
  }
  getTableRect() {
    return {
      map: this.map,
      tableStart: this.getStartPos(),
      table: this.getNode(),
      left: 0,
      right: this.getWidth(),
      top: 0,
      bottom: this.getHeight()
    };
  }
  getColumnWidth(view) {
    const dom = view.domAtPos(this.getStartPos());
    return dom.node?.parentElement ? Array.from(dom.node.parentElement.children[0].children)?.map(
      (node) => node.offsetWidth
    ) : [];
  }
}
export {
  TableQuery
};
//# sourceMappingURL=table-query.js.map
