 import os
 
 struct UCell: Codable {
-
   var string: String
   var attrId: Int
 

  }

  #if DEBUG
  func dump() throws {
    let encoder = JSONEncoder()
    encoder.outputFormatting = .prettyPrinted

    let data = try encoder.encode(self)
    try data.write(to: URL(fileURLWithPath: "/tmp/ugrid.dump.json"))
  }
  #endif

  var description: String {
    let result = "UGrid.flatCharIndex:\n" + self.cells.reduce("") { result, row in
      return result + "(\(row[0].flatCharIndex...row[self.size.width - 1].flatCharIndex)), "
    }

    return result
  }
  var hasData: Bool {
    return !self.cells.isEmpty
  }

  func unmarkCell(at position: Position) {
    let attrId = self.cells[position.row][position.column].attrId

    guard attrId < CellAttributesCollection.defaultAttributesId
          || attrId == CellAttributesCollection.reversedDefaultAttributesId
      else {
      return
    }

    let newAttrsId: Int
    if attrId == CellAttributesCollection.reversedDefaultAttributesId {

  func isNextCellEmpty(_ position: Position) -> Bool {
    guard self.isSane(position) else { return false }
    guard position.column + 1 < self.size.width else { return false }
    guard !self.cells[position.row][position.column].string.isEmpty else { return false }

    if self.cells[position.row][position.column + 1].string.isEmpty { return true }

    return false
  }

  func isSane(_ position: Position) -> Bool {
    if position.column < 0
      || position.column >= self.size.width
      || position.row < 0
      || position.row >= self.size.height
    { return false }

    return true
  }

  func clear() {
    let emptyRow = Array(
      repeating: UCell(string: clearString, attrId: CellAttributesCollection.defaultAttributesId),
      count: self.size.width
    )
    self.cells = Array(repeating: emptyRow, count: self.size.height)
  }

  func clear(region: Region) {
    // FIXME: sometimes clearRegion gets called without first resizing the Grid.
    // Should we handle this?
    guard self.hasData else { return }

    let clearedCell = UCell(string: " ", attrId: CellAttributesCollection.defaultAttributesId)
    let clearedRow = Array(repeating: clearedCell, count: region.right - region.left + 1)
    for i in region.top...region.bottom {
      self.cells[i].replaceSubrange(region.left...region.right, with: clearedRow)
    }
  }

