import '../models/cell.dart';
import '../models/grid.dart';
import '../models/piece.dart';

/// Whether [piece] fits with its anchor at ([x], [y]).
bool canPlace(GridState grid, Piece piece, int x, int y) {
  for (final (dx, dy) in piece.offsets) {
    final px = x + dx;
    final py = y + dy;
    if (px < 0 || px >= GridState.size || py < 0 || py >= GridState.size) {
      return false;
    }
    if (grid.isOccupied(px, py)) return false;
  }
  return true;
}

/// Places [piece] at ([x], [y]); caller must check [canPlace] first.
GridState place(GridState grid, Piece piece, int x, int y) {
  var next = grid;
  for (final (dx, dy) in piece.offsets) {
    next = next.withCell(
      x + dx,
      y + dy,
      Cell(CellType.filled, colorId: piece.colorId),
    );
  }
  return next;
}

/// Whether at least one of [pieces] has at least one legal placement.
bool anyPlacementExists(GridState grid, List<Piece> pieces) {
  for (final piece in pieces) {
    for (var y = 0; y < GridState.size; y++) {
      for (var x = 0; x < GridState.size; x++) {
        if (canPlace(grid, piece, x, y)) return true;
      }
    }
  }
  return false;
}
