///|
/// Additional spatial statistics for crop, quality, and scene detection.
pub(all) struct SpatialStats {
  center : Rgba
  corners : Array[Rgba]
  quadrant_luma : Array[Int]
  opaque_bounds : GifRect?
  variance_milli : Int
} derive(Debug)

///|
pub fn SpatialStats::center(self : SpatialStats) -> Rgba {
  self.center
}

///|
pub fn SpatialStats::corners(self : SpatialStats) -> ArrayView[Rgba] {
  self.corners[:]
}

///|
pub fn SpatialStats::quadrant_luma(self : SpatialStats) -> ArrayView[Int] {
  self.quadrant_luma[:]
}

///|
pub fn SpatialStats::opaque_bounds(self : SpatialStats) -> GifRect? {
  self.opaque_bounds
}

///|
pub fn SpatialStats::variance_milli(self : SpatialStats) -> Int {
  self.variance_milli
}

///|
/// Calculate center, corner, quadrant, and luma variance in one scan.
pub fn Canvas::spatial_stats(self : Canvas) -> SpatialStats {
  let center = if self.width == 0 || self.height == 0 {
    rgba(0, 0, 0, 0)
  } else {
    self.pixels[self.width / 2 + self.height / 2 * self.width]
  }
  let corners : Array[Rgba] = []
  if self.width > 0 && self.height > 0 {
    corners.push(self.pixels[0])
    corners.push(self.pixels[self.width - 1])
    corners.push(self.pixels[(self.height - 1) * self.width])
    corners.push(self.pixels[self.width * self.height - 1])
  }
  let totals = Array::make(4, 0)
  let counts = Array::make(4, 0)
  let mut total = 0
  let mut total_squared = 0
  for y in 0.. Int {
  let stats = self.spatial_stats()
  let values = stats.quadrant_luma()
  let mut selected = 0
  for i in 1.. values[selected] {
      selected = i
    }
  }
  selected
}

///|
/// Compare two images by structural statistics before running a full diff.
pub fn spatial_similarity(left : Canvas, right : Canvas) -> Int {
  let a = left.spatial_stats()
  let b = right.spatial_stats()
  let mut difference = a.center().distance(b.center())
  let left_quadrants = a.quadrant_luma()
  let right_quadrants = b.quadrant_luma()
  for i in 0..<4 {
    difference += (left_quadrants[i] - right_quadrants[i]).abs()
  }
  let value = 1000 - difference * 1000 / 2000
  if value < 0 {
    0
  } else {
    value
  }
}