///|
/// 屏幕上的一个单元格
pub struct Cell {
  char : Char
  format : ConsoleFormat
} derive(Eq)

///|
pub fn Cell::new(char : Char, format : ConsoleFormat) -> Cell {
  { char, format }
}

///|
pub impl Default for Cell with default() -> Cell {
  { char: ' ', format: ConsoleFormat::default() }
}

///|
/// 判断两个单元格是否完全一致(内容和样式)
pub fn Cell::op_equal(self : Cell, other : Cell) -> Bool {
  self.char == other.char &&
  self.format.foreground == other.format.foreground &&
  self.format.background == other.format.background &&
  self.format.bold == other.format.bold &&
  self.format.italic == other.format.italic &&
  self.format.underline == other.format.underline
}

///|
/// 虚拟屏幕缓冲区
pub struct Screen {
  rows : Array[Array[Cell]]
  width : Int
  height : Int
  mut cursor_row : Int
  mut cursor_col : Int
}

///|
pub fn Screen::set_cursor(self : Screen, row : Int, col : Int) -> Unit {
  self.cursor_row = row
  self.cursor_col = col
}

///|
/// 创建指定大小的空屏幕
pub fn Screen::new(height : Int, width : Int) -> Screen {
  let rows = Array::new(capacity=height)
  for _ in 0.. Unit {
  if row < 0 || row >= self.height {
    return
  }
  let mut current_col = col
  for ch in text {
    let w = get_char_width(ch)
    if current_col + w > self.width {
      break
    }
    if current_col >= 0 {
      self.rows[row][current_col] = Cell::new(ch, format)
      // 如果是宽字符,后续格子标记为空白以防重叠渲染逻辑出错
      if w == 2 && current_col + 1 < self.width {
        self.rows[row][current_col + 1] = Cell::new('\u{0000}', format)
      }
    }
    current_col = current_col + w
  }
}

///|
fn append_relative_cursor_move(
  output : Array[String],
  from_row : Int,
  from_col : Int,
  to_row : Int,
  to_col : Int,
) -> Unit {
  let row_delta = to_row - from_row
  if row_delta < 0 {
    output.push("\u{1b}[\{-row_delta}A")
  } else if row_delta > 0 {
    output.push("\u{1b}[\{row_delta}B")
  }

  let col_delta = to_col - from_col
  if col_delta < 0 {
    output.push("\u{1b}[\{-col_delta}D")
  } else if col_delta > 0 {
    output.push("\u{1b}[\{col_delta}C")
  }
}

///|
/// 将新旧屏幕差异输出到控制台
pub fn render_diff(
  console : &@ports.ConsolePort,
  new_screen : Screen,
  old_screen : Screen,
  base_row : Int,
  base_col : Int,
) -> Unit {
  let output = Array::new()
  let mut current_format = ConsoleFormat::default()
  output.push("\u{1b}[0m") // 重置初始样式

  // 首帧仍用绝对定位建立锚点;后续刷新使用相对移动。
  let mut cursor_row = old_screen.cursor_row
  let mut cursor_col = old_screen.cursor_col
  if old_screen.height == 0 {
    output.push("\u{1b}[\{base_row};\{base_col}H")
    cursor_row = 0
    cursor_col = 0
  }

  let max_height = if new_screen.height > old_screen.height {
    new_screen.height
  } else {
    old_screen.height
  }
  let max_width = if new_screen.width > old_screen.width {
    new_screen.width
  } else {
    old_screen.width
  }
  for r in 0..