///|
/// Integer color-space conversions for export and palette preparation.
pub(all) struct YuvColor {
  y : Int
  u : Int
  v : Int
  alpha : Byte
} derive(Eq, Debug)

///|
pub fn YuvColor::luma(self : YuvColor) -> Int {
  self.y
}

///|
pub fn YuvColor::chrominance_u(self : YuvColor) -> Int {
  self.u
}

///|
pub fn YuvColor::chrominance_v(self : YuvColor) -> Int {
  self.v
}

///|
pub fn YuvColor::alpha(self : YuvColor) -> Byte {
  self.alpha
}

///|
fn clamp_space_byte(value : Int) -> Byte {
  (if value < 0 { 0 } else if value > 255 { 255 } else { value }).to_byte()
}

///|
pub fn Rgba::to_yuv(self : Rgba) -> YuvColor {
  let red = self.red().to_int()
  let green = self.green().to_int()
  let blue = self.blue().to_int()
  YuvColor::{
    y: (299 * red + 587 * green + 114 * blue) / 1000,
    u: (-169 * red - 331 * green + 500 * blue) / 1000,
    v: (500 * red - 419 * green - 81 * blue) / 1000,
    alpha: self.alpha(),
  }
}

///|
pub fn rgba_from_yuv(color : YuvColor) -> Rgba {
  let red = color.y + 1402 * color.v / 1000
  let green = color.y - 344 * color.u / 1000 - 714 * color.v / 1000
  let blue = color.y + 1772 * color.u / 1000
  rgba(
    clamp_space_byte(red),
    clamp_space_byte(green),
    clamp_space_byte(blue),
    color.alpha,
  )
}

///|
/// Convert a canvas through YUV with a configurable chroma subsampling step.
pub fn Canvas::yuv_roundtrip(self : Canvas) -> Canvas {
  let result = self.copy()
  for i in 0.. Canvas {
  let result = self.copy()
  for i in 0.. Canvas {
  let result = self.copy()
  for i in 0.. Canvas {
  let result = self.copy()
  for i in 0.. Canvas {
  let safe = if strength < 0 {
    0
  } else if strength > 1000 {
    1000
  } else {
    strength
  }
  let result = self.copy()
  for i in 0.. Canvas {
  let safe = if bands < 2 { 2 } else if bands > 256 { 256 } else { bands }
  let result = self.copy()
  for i in 0.. Canvas {
  self
  .temperature(warmth)
  .adjust(
    ColorAdjustment::default().contrast(contrast).saturation(contrast / 2),
  )
}