/// Decodes the bundled stills and draws them in the terminal with 24-bit
/// color. Each character covers two pixels: the foreground color paints
/// the upper half block and the background color paints the lower half,
/// so a 16x16 image takes eight lines and stays square.

///|
fn channel(pixel : UInt, shift : Int) -> Int {
  (pixel >> shift).reinterpret_as_int() & 0xff
}

///|
/// Composites a pixel over mid gray. Alpha has to land somewhere, and a
/// fixed gray keeps the picture readable on light and dark terminals.
fn over_gray(pixel : UInt) -> (Int, Int, Int) {
  let alpha = channel(pixel, 24)
  let rest = 255 - alpha
  (
    (channel(pixel, 16) * alpha + 96 * rest + 127) / 255,
    (channel(pixel, 8) * alpha + 96 * rest + 127) / 255,
    (channel(pixel, 0) * alpha + 96 * rest + 127) / 255,
  )
}

///|
fn render(width : Int, height : Int, pixels : Array[UInt]) -> Unit {
  let mut y = 0
  while y < height {
    let line = StringBuilder()
    let mut top_painted : (Int, Int, Int) = (-1, -1, -1)
    let mut bottom_painted : (Int, Int, Int) = (-1, -1, -1)
    for x in 0.. (Int, Int) {
  let mut clear = 0
  let mut translucent = 0
  for pixel in pixels {
    let alpha = channel(pixel, 24)
    if alpha == 0 {
      clear = clear + 1
    } else if alpha < 255 {
      translucent = translucent + 1
    }
  }
  (clear, translucent)
}

///|
fn main raise {
  let samples : Array[(String, Bytes)] = [
    ("still.webp", @fixtures.still),
    ("alpha.webp", @fixtures.alpha),
  ]
  for sample in samples {
    let (name, bytes) = sample
    let image = @webp.decode_webp(bytes)
    let (clear, translucent) = alpha_stats(image.pixels)
    println(
      "\{name}: \{image.width} x \{image.height}, \{clear} transparent, " +
      "\{translucent} translucent",
    )
    render(image.width, image.height, image.pixels)
    println("")
  }
  println("translucent pixels are composited over gray")
}