///|
/// Pixel buffer for 2D rendering (RGBA format)
pub struct Pixmap {
  width : Int
  height : Int
  pixels : FixedArray[Byte]
} derive(Debug)

///|
pub extend Pixmap with Debug::{to_repr}

///|
/// Sampling mode used when scaling source pixmaps.
pub(all) enum ImageSampling {
  Nearest
  Bilinear
  Bicubic
} derive(Eq, Debug)

///|
pub extend ImageSampling with Debug::{to_repr}

///|
pub extend ImageSampling with Eq::{not_equal, equal}

///|
/// Image quality strategy for callers that prefer intent over a concrete
/// sampling algorithm.
pub(all) enum ImageQuality {
  Fast
  Balanced
  High
} derive(Eq, Debug)

///|
pub extend ImageQuality with Debug::{to_repr}

///|
pub extend ImageQuality with Eq::{not_equal, equal}

///|
/// Return the concrete sampling mode selected by this quality strategy.
pub fn ImageQuality::to_sampling(self : ImageQuality) -> ImageSampling {
  match self {
    Fast => Nearest
    Balanced => Bilinear
    High => Bicubic
  }
}

///|
/// Insets used for nine-patch image scaling.
pub struct NinePatchInsets {
  left : Int
  top : Int
  right : Int
  bottom : Int
} derive(Eq, Debug)

///|
pub extend NinePatchInsets with Debug::{to_repr}

///|
pub extend NinePatchInsets with Eq::{not_equal, equal}

///|
pub fn NinePatchInsets::new(
  left~ : Int,
  top~ : Int,
  right~ : Int,
  bottom~ : Int,
) -> NinePatchInsets {
  { left, top, right, bottom, }
}

///|
struct NinePatchSlices {
  src_left : Int
  src_right : Int
  src_top : Int
  src_bottom : Int
  dst_left : Int
  dst_right : Int
  dst_top : Int
  dst_bottom : Int
} derive(Debug)

///|
pub extend NinePatchSlices with Debug::{to_repr}

///|
/// Create a new pixmap filled with transparent pixels
pub fn Pixmap::new(width : Int, height : Int) -> Pixmap {
  let size = width * height * 4
  { width, height, pixels: FixedArray::make(size, 0), }
}

///|
/// Get the width of the pixmap
pub fn Pixmap::get_width(self : Pixmap) -> Int {
  self.width
}

///|
/// Get the height of the pixmap
pub fn Pixmap::get_height(self : Pixmap) -> Int {
  self.height
}

///|
/// Get the raw pixel data
pub fn Pixmap::get_pixels(self : Pixmap) -> FixedArray[Byte] {
  self.pixels
}

///|
/// Copy this pixmap and its raw pixel storage.
pub fn Pixmap::copy(self : Pixmap) -> Pixmap {
  { width: self.width, height: self.height, pixels: copy_pixmap_pixels(self), }
}

///|
/// Return a deterministic lightweight checksum of the raw RGBA pixel bytes.
/// This is intended for compact regression assertions and smoke telemetry, not
/// for cryptographic or collision-resistant validation.
pub fn Pixmap::checksum(self : Pixmap) -> Int {
  checksum_rgba_bytes(self.pixels)
}

///|
/// Set a pixel at the given coordinates
pub fn Pixmap::set_pixel(
  self : Pixmap,
  x : Int,
  y : Int,
  color : Color,
) -> Unit {
  guard x >= 0 && x < self.width && y >= 0 && y < self.height else { return }
  let idx = (y * self.width + x) * 4
  self.pixels[idx] = color.r
  self.pixels[idx + 1] = color.g
  self.pixels[idx + 2] = color.b
  self.pixels[idx + 3] = color.a
}

///|
fn copy_pixmap_pixels(pixmap : Pixmap) -> FixedArray[Byte] {
  let src = pixmap.get_pixels()
  let dst : FixedArray[Byte] = FixedArray::make(src.length(), 0)
  for i in 0.. Int {
  let mut checksum = 0
  for i in 0.. Unit {
  guard x >= 0 && x < self.width && y >= 0 && y < self.height else { return }
  self.set_pixel(x, y, color.blend_over(self.get_pixel(x, y)))
}

///|
fn Pixmap::blend_pixel_with_mode(
  self : Pixmap,
  x : Int,
  y : Int,
  color : Color,
  blend_mode : BlendMode,
) -> Unit {
  guard x >= 0 && x < self.width && y >= 0 && y < self.height else { return }
  self.set_pixel(x, y, color.blend_with(self.get_pixel(x, y), blend_mode))
}

///|
/// Get the color at the given coordinates
pub fn Pixmap::get_pixel(self : Pixmap, x : Int, y : Int) -> Color {
  guard x >= 0 && x < self.width && y >= 0 && y < self.height else {
    return Color::transparent()
  }
  let idx = (y * self.width + x) * 4
  Color::new(
    r=self.pixels[idx],
    g=self.pixels[idx + 1],
    b=self.pixels[idx + 2],
    a=self.pixels[idx + 3],
  )
}

///|
/// Clear the pixmap with a color
pub fn Pixmap::clear(self : Pixmap, color : Color) -> Unit {
  for y in 0.. Unit {
  for dy in 0.. Unit {
  for dy in 0.. Unit {
  for dy in 0.. Unit {
  guard width > 0 && height > 0 && mask.length() >= width * height else {
    return
  }
  for my in 0.. 0 {
        let alpha = (color.a.to_int() * coverage + 127) / 255
        self.blend_pixel(x + mx, y + my, color.with_alpha(clamp_byte(alpha)))
      }
    }
  }
}

///|
/// Composite a source rectangle from a grayscale coverage mask over this pixmap.
pub fn Pixmap::blend_mask_rect(
  self : Pixmap,
  x : Int,
  y : Int,
  mask_width : Int,
  mask_height : Int,
  mask : FixedArray[Byte],
  src_rect : PixelRect,
  color : Color,
) -> Unit {
  guard mask_width > 0 &&
    mask_height > 0 &&
    mask.length() >= mask_width * mask_height else {
    return
  }
  let mask_bounds = PixelRect::new(
    x=0,
    y=0,
    width=mask_width,
    height=mask_height,
  )
  match src_rect.clip_to(mask_bounds) {
    Some(clipped_src) => {
      let dst_x = x + clipped_src.x - src_rect.x
      let dst_y = y + clipped_src.y - src_rect.y
      let x_start = dst_x.max(0)
      let y_start = dst_y.max(0)
      let x_end = (dst_x + clipped_src.width).min(self.width)
      let y_end = (dst_y + clipped_src.height).min(self.height)
      guard x_start < x_end && y_start < y_end else { return }
      for py in y_start.. 0 {
            let alpha = (color.a.to_int() * coverage + 127) / 255
            self.blend_pixel(px, py, color.with_alpha(clamp_byte(alpha)))
          }
        }
      }
    }
    None => ()
  }
}

///|
/// Composite another pixmap over this pixmap at the given destination position.
pub fn Pixmap::blend_pixmap(
  self : Pixmap,
  x : Int,
  y : Int,
  src : Pixmap,
  opacity : Double,
) -> Unit {
  guard src.get_width() > 0 && src.get_height() > 0 else { return }
  let x_start = x.max(0)
  let y_start = y.max(0)
  let x_end = (x + src.get_width()).min(self.width)
  let y_end = (y + src.get_height()).min(self.height)
  guard x_start < x_end && y_start < y_end else { return }
  for py in y_start.. 0 {
        self.blend_pixel(px, py, src_color)
      }
    }
  }
}

///|
/// Composite a source pixmap rectangle over this pixmap at the destination
/// position corresponding to the requested source rectangle's top-left corner.
pub fn Pixmap::blend_pixmap_rect(
  self : Pixmap,
  x : Int,
  y : Int,
  src : Pixmap,
  src_rect : PixelRect,
  opacity : Double,
) -> Unit {
  guard src.get_width() > 0 && src.get_height() > 0 else { return }
  let src_bounds = PixelRect::new(
    x=0,
    y=0,
    width=src.get_width(),
    height=src.get_height(),
  )
  match src_rect.clip_to(src_bounds) {
    Some(clipped_src) => {
      let dst_x = x + clipped_src.x - src_rect.x
      let dst_y = y + clipped_src.y - src_rect.y
      let x_start = dst_x.max(0)
      let y_start = dst_y.max(0)
      let x_end = (dst_x + clipped_src.width).min(self.width)
      let y_end = (dst_y + clipped_src.height).min(self.height)
      guard x_start < x_end && y_start < y_end else { return }
      for py in y_start.. 0 {
            self.blend_pixel(px, py, src_color)
          }
        }
      }
    }
    None => ()
  }
}

///|
/// Composite another pixmap scaled to the given destination size.
pub fn Pixmap::blend_scaled_pixmap(
  self : Pixmap,
  x : Int,
  y : Int,
  width : Int,
  height : Int,
  src : Pixmap,
  opacity : Double,
) -> Unit {
  guard width > 0 && height > 0 else { return }
  guard src.get_width() > 0 && src.get_height() > 0 else { return }
  let x_start = x.max(0)
  let y_start = y.max(0)
  let x_end = (x + width).min(self.width)
  let y_end = (y + height).min(self.height)
  guard x_start < x_end && y_start < y_end else { return }
  ignore(
    blend_scaled_pixmap_region(
      self,
      x,
      y,
      width,
      height,
      src,
      opacity,
      None,
      SourceOver,
      x_start,
      y_start,
      x_end,
      y_end,
    ),
  )
}

///|
/// Composite another pixmap scaled with bilinear sampling.
pub fn Pixmap::blend_scaled_pixmap_bilinear(
  self : Pixmap,
  x : Int,
  y : Int,
  width : Int,
  height : Int,
  src : Pixmap,
  opacity : Double,
) -> Unit {
  guard width > 0 && height > 0 else { return }
  guard src.get_width() > 0 && src.get_height() > 0 else { return }
  let x_start = x.max(0)
  let y_start = y.max(0)
  let x_end = (x + width).min(self.width)
  let y_end = (y + height).min(self.height)
  guard x_start < x_end && y_start < y_end else { return }
  ignore(
    blend_scaled_pixmap_bilinear_region(
      self,
      x,
      y,
      width,
      height,
      src,
      opacity,
      None,
      SourceOver,
      x_start,
      y_start,
      x_end,
      y_end,
    ),
  )
}

///|
/// Composite another pixmap scaled with bicubic sampling.
pub fn Pixmap::blend_scaled_pixmap_bicubic(
  self : Pixmap,
  x : Int,
  y : Int,
  width : Int,
  height : Int,
  src : Pixmap,
  opacity : Double,
) -> Unit {
  guard width > 0 && height > 0 else { return }
  guard src.get_width() > 0 && src.get_height() > 0 else { return }
  let x_start = x.max(0)
  let y_start = y.max(0)
  let x_end = (x + width).min(self.width)
  let y_end = (y + height).min(self.height)
  guard x_start < x_end && y_start < y_end else { return }
  ignore(
    blend_scaled_pixmap_bicubic_region(
      self,
      x,
      y,
      width,
      height,
      src,
      opacity,
      None,
      SourceOver,
      x_start,
      y_start,
      x_end,
      y_end,
    ),
  )
}

///|
/// Composite another pixmap scaled with an explicit sampling mode.
pub fn Pixmap::blend_sampled_pixmap(
  self : Pixmap,
  x : Int,
  y : Int,
  width : Int,
  height : Int,
  src : Pixmap,
  opacity : Double,
  sampling : ImageSampling,
) -> Unit {
  match sampling {
    Nearest => self.blend_scaled_pixmap(x, y, width, height, src, opacity)
    Bilinear =>
      self.blend_scaled_pixmap_bilinear(x, y, width, height, src, opacity)
    Bicubic =>
      self.blend_scaled_pixmap_bicubic(x, y, width, height, src, opacity)
  }
}

///|
/// Composite another pixmap scaled with a quality strategy.
pub fn Pixmap::blend_quality_pixmap(
  self : Pixmap,
  x : Int,
  y : Int,
  width : Int,
  height : Int,
  src : Pixmap,
  opacity : Double,
  quality : ImageQuality,
) -> Unit {
  self.blend_sampled_pixmap(
    x,
    y,
    width,
    height,
    src,
    opacity,
    quality.to_sampling(),
  )
}

///|
/// Composite a source pixmap rectangle scaled to the given destination size.
pub fn Pixmap::blend_scaled_pixmap_rect(
  self : Pixmap,
  x : Int,
  y : Int,
  width : Int,
  height : Int,
  src : Pixmap,
  src_rect : PixelRect,
  opacity : Double,
) -> Unit {
  self.blend_sampled_pixmap_rect(
    x,
    y,
    width,
    height,
    src,
    src_rect,
    opacity,
    Nearest,
  )
}

///|
/// Composite a source pixmap rectangle scaled with bilinear sampling.
pub fn Pixmap::blend_scaled_pixmap_rect_bilinear(
  self : Pixmap,
  x : Int,
  y : Int,
  width : Int,
  height : Int,
  src : Pixmap,
  src_rect : PixelRect,
  opacity : Double,
) -> Unit {
  self.blend_sampled_pixmap_rect(
    x,
    y,
    width,
    height,
    src,
    src_rect,
    opacity,
    Bilinear,
  )
}

///|
/// Composite a source pixmap rectangle scaled with bicubic sampling.
pub fn Pixmap::blend_scaled_pixmap_rect_bicubic(
  self : Pixmap,
  x : Int,
  y : Int,
  width : Int,
  height : Int,
  src : Pixmap,
  src_rect : PixelRect,
  opacity : Double,
) -> Unit {
  self.blend_sampled_pixmap_rect(
    x,
    y,
    width,
    height,
    src,
    src_rect,
    opacity,
    Bicubic,
  )
}

///|
/// Composite a source pixmap rectangle scaled with an explicit sampling mode.
pub fn Pixmap::blend_sampled_pixmap_rect(
  self : Pixmap,
  x : Int,
  y : Int,
  width : Int,
  height : Int,
  src : Pixmap,
  src_rect : PixelRect,
  opacity : Double,
  sampling : ImageSampling,
) -> Unit {
  guard width > 0 && height > 0 else { return }
  guard src.get_width() > 0 && src.get_height() > 0 else { return }
  let src_bounds = PixelRect::new(
    x=0,
    y=0,
    width=src.get_width(),
    height=src.get_height(),
  )
  match src_rect.clip_to(src_bounds) {
    Some(clipped_src) => {
      let x_start = x.max(0)
      let y_start = y.max(0)
      let x_end = (x + width).min(self.width)
      let y_end = (y + height).min(self.height)
      guard x_start < x_end && y_start < y_end else { return }
      ignore(
        blend_sampled_pixmap_rect_region(
          self,
          x,
          y,
          width,
          height,
          src,
          clipped_src,
          opacity,
          None,
          sampling,
          SourceOver,
          x_start,
          y_start,
          x_end,
          y_end,
        ),
      )
    }
    None => ()
  }
}

///|
/// Composite a source pixmap rectangle scaled with a quality strategy.
pub fn Pixmap::blend_quality_pixmap_rect(
  self : Pixmap,
  x : Int,
  y : Int,
  width : Int,
  height : Int,
  src : Pixmap,
  src_rect : PixelRect,
  opacity : Double,
  quality : ImageQuality,
) -> Unit {
  self.blend_sampled_pixmap_rect(
    x,
    y,
    width,
    height,
    src,
    src_rect,
    opacity,
    quality.to_sampling(),
  )
}

///|
/// Composite a source pixmap rectangle repeatedly into the destination area.
pub fn Pixmap::blend_tiled_pixmap_rect(
  self : Pixmap,
  x : Int,
  y : Int,
  width : Int,
  height : Int,
  src : Pixmap,
  src_rect : PixelRect,
  opacity : Double,
) -> Unit {
  guard width > 0 && height > 0 else { return }
  guard src.get_width() > 0 && src.get_height() > 0 else { return }
  let src_bounds = PixelRect::new(
    x=0,
    y=0,
    width=src.get_width(),
    height=src.get_height(),
  )
  match src_rect.clip_to(src_bounds) {
    Some(clipped_src) => {
      let x_start = x.max(0)
      let y_start = y.max(0)
      let x_end = (x + width).min(self.width)
      let y_end = (y + height).min(self.height)
      guard x_start < x_end && y_start < y_end else { return }
      ignore(
        blend_tiled_pixmap_rect_region(
          self,
          x,
          y,
          width,
          height,
          src,
          clipped_src,
          opacity,
          None,
          SourceOver,
          x_start,
          y_start,
          x_end,
          y_end,
        ),
      )
    }
    None => ()
  }
}

///|
/// Composite a source pixmap using nine-patch scaling.
pub fn Pixmap::blend_nine_patch_pixmap(
  self : Pixmap,
  x : Int,
  y : Int,
  width : Int,
  height : Int,
  src : Pixmap,
  insets : NinePatchInsets,
  opacity : Double,
  sampling : ImageSampling,
) -> Unit {
  guard width > 0 && height > 0 else { return }
  guard src.get_width() > 0 && src.get_height() > 0 else { return }
  let x_start = x.max(0)
  let y_start = y.max(0)
  let x_end = (x + width).min(self.width)
  let y_end = (y + height).min(self.height)
  guard x_start < x_end && y_start < y_end else { return }
  ignore(
    blend_nine_patch_pixmap_region(
      self,
      x,
      y,
      width,
      height,
      src,
      insets,
      opacity,
      None,
      sampling,
      SourceOver,
      x_start,
      y_start,
      x_end,
      y_end,
    ),
  )
}

///|
/// Composite a source pixmap using nine-patch scaling and a quality strategy.
pub fn Pixmap::blend_quality_nine_patch_pixmap(
  self : Pixmap,
  x : Int,
  y : Int,
  width : Int,
  height : Int,
  src : Pixmap,
  insets : NinePatchInsets,
  opacity : Double,
  quality : ImageQuality,
) -> Unit {
  self.blend_nine_patch_pixmap(
    x,
    y,
    width,
    height,
    src,
    insets,
    opacity,
    quality.to_sampling(),
  )
}

///|
fn blend_nine_patch_pixmap_region(
  dst : Pixmap,
  x : Int,
  y : Int,
  width : Int,
  height : Int,
  src : Pixmap,
  insets : NinePatchInsets,
  opacity : Double,
  filter : PaintFilter?,
  sampling : ImageSampling,
  blend_mode : BlendMode,
  x_start : Int,
  y_start : Int,
  x_end : Int,
  y_end : Int,
) -> Bool {
  let slices = make_nine_patch_slices(
    src.get_width(),
    src.get_height(),
    width,
    height,
    insets,
  )
  let mut did_blend = false
  if blend_nine_patch_segment(
      dst,
      x,
      y,
      0,
      0,
      slices.dst_left,
      slices.dst_top,
      src,
      PixelRect::new(x=0, y=0, width=slices.src_left, height=slices.src_top),
      opacity,
      filter,
      sampling,
      blend_mode,
      x_start,
      y_start,
      x_end,
      y_end,
    ) {
    did_blend = true
  }
  if blend_nine_patch_segment(
      dst,
      x,
      y,
      slices.dst_left,
      0,
      width - slices.dst_left - slices.dst_right,
      slices.dst_top,
      src,
      PixelRect::new(
        x=slices.src_left,
        y=0,
        width=src.get_width() - slices.src_left - slices.src_right,
        height=slices.src_top,
      ),
      opacity,
      filter,
      sampling,
      blend_mode,
      x_start,
      y_start,
      x_end,
      y_end,
    ) {
    did_blend = true
  }
  if blend_nine_patch_segment(
      dst,
      x,
      y,
      width - slices.dst_right,
      0,
      slices.dst_right,
      slices.dst_top,
      src,
      PixelRect::new(
        x=src.get_width() - slices.src_right,
        y=0,
        width=slices.src_right,
        height=slices.src_top,
      ),
      opacity,
      filter,
      sampling,
      blend_mode,
      x_start,
      y_start,
      x_end,
      y_end,
    ) {
    did_blend = true
  }
  if blend_nine_patch_segment(
      dst,
      x,
      y,
      0,
      slices.dst_top,
      slices.dst_left,
      height - slices.dst_top - slices.dst_bottom,
      src,
      PixelRect::new(
        x=0,
        y=slices.src_top,
        width=slices.src_left,
        height=src.get_height() - slices.src_top - slices.src_bottom,
      ),
      opacity,
      filter,
      sampling,
      blend_mode,
      x_start,
      y_start,
      x_end,
      y_end,
    ) {
    did_blend = true
  }
  if blend_nine_patch_segment(
      dst,
      x,
      y,
      slices.dst_left,
      slices.dst_top,
      width - slices.dst_left - slices.dst_right,
      height - slices.dst_top - slices.dst_bottom,
      src,
      PixelRect::new(
        x=slices.src_left,
        y=slices.src_top,
        width=src.get_width() - slices.src_left - slices.src_right,
        height=src.get_height() - slices.src_top - slices.src_bottom,
      ),
      opacity,
      filter,
      sampling,
      blend_mode,
      x_start,
      y_start,
      x_end,
      y_end,
    ) {
    did_blend = true
  }
  if blend_nine_patch_segment(
      dst,
      x,
      y,
      width - slices.dst_right,
      slices.dst_top,
      slices.dst_right,
      height - slices.dst_top - slices.dst_bottom,
      src,
      PixelRect::new(
        x=src.get_width() - slices.src_right,
        y=slices.src_top,
        width=slices.src_right,
        height=src.get_height() - slices.src_top - slices.src_bottom,
      ),
      opacity,
      filter,
      sampling,
      blend_mode,
      x_start,
      y_start,
      x_end,
      y_end,
    ) {
    did_blend = true
  }
  if blend_nine_patch_segment(
      dst,
      x,
      y,
      0,
      height - slices.dst_bottom,
      slices.dst_left,
      slices.dst_bottom,
      src,
      PixelRect::new(
        x=0,
        y=src.get_height() - slices.src_bottom,
        width=slices.src_left,
        height=slices.src_bottom,
      ),
      opacity,
      filter,
      sampling,
      blend_mode,
      x_start,
      y_start,
      x_end,
      y_end,
    ) {
    did_blend = true
  }
  if blend_nine_patch_segment(
      dst,
      x,
      y,
      slices.dst_left,
      height - slices.dst_bottom,
      width - slices.dst_left - slices.dst_right,
      slices.dst_bottom,
      src,
      PixelRect::new(
        x=slices.src_left,
        y=src.get_height() - slices.src_bottom,
        width=src.get_width() - slices.src_left - slices.src_right,
        height=slices.src_bottom,
      ),
      opacity,
      filter,
      sampling,
      blend_mode,
      x_start,
      y_start,
      x_end,
      y_end,
    ) {
    did_blend = true
  }
  if blend_nine_patch_segment(
      dst,
      x,
      y,
      width - slices.dst_right,
      height - slices.dst_bottom,
      slices.dst_right,
      slices.dst_bottom,
      src,
      PixelRect::new(
        x=src.get_width() - slices.src_right,
        y=src.get_height() - slices.src_bottom,
        width=slices.src_right,
        height=slices.src_bottom,
      ),
      opacity,
      filter,
      sampling,
      blend_mode,
      x_start,
      y_start,
      x_end,
      y_end,
    ) {
    did_blend = true
  }
  did_blend
}

///|
fn make_nine_patch_slices(
  src_width : Int,
  src_height : Int,
  dst_width : Int,
  dst_height : Int,
  insets : NinePatchInsets,
) -> NinePatchSlices {
  let (src_left, src_right) = clamp_edge_pair(
    src_width,
    insets.left,
    insets.right,
  )
  let (src_top, src_bottom) = clamp_edge_pair(
    src_height,
    insets.top,
    insets.bottom,
  )
  let (dst_left, dst_right) = clamp_edge_pair(dst_width, src_left, src_right)
  let (dst_top, dst_bottom) = clamp_edge_pair(dst_height, src_top, src_bottom)
  {
    src_left,
    src_right,
    src_top,
    src_bottom,
    dst_left,
    dst_right,
    dst_top,
    dst_bottom,
  }
}

///|
fn clamp_edge_pair(total : Int, start : Int, end : Int) -> (Int, Int) {
  guard total > 0 else { return (0, 0) }
  let clamped_start = start.max(0).min(total)
  let clamped_end = end.max(0).min(total - clamped_start)
  (clamped_start, clamped_end)
}

///|
fn blend_nine_patch_segment(
  dst : Pixmap,
  patch_x : Int,
  patch_y : Int,
  dst_offset_x : Int,
  dst_offset_y : Int,
  dst_width : Int,
  dst_height : Int,
  src : Pixmap,
  src_rect : PixelRect,
  opacity : Double,
  filter : PaintFilter?,
  sampling : ImageSampling,
  blend_mode : BlendMode,
  x_start : Int,
  y_start : Int,
  x_end : Int,
  y_end : Int,
) -> Bool {
  guard dst_width > 0 && dst_height > 0 else { return false }
  guard src_rect.width > 0 && src_rect.height > 0 else { return false }
  let dst_x = patch_x + dst_offset_x
  let dst_y = patch_y + dst_offset_y
  let segment_x_start = x_start.max(dst_x)
  let segment_y_start = y_start.max(dst_y)
  let segment_x_end = x_end.min(dst_x + dst_width)
  let segment_y_end = y_end.min(dst_y + dst_height)
  guard segment_x_start < segment_x_end && segment_y_start < segment_y_end else {
    return false
  }
  blend_sampled_pixmap_rect_region(
    dst, dst_x, dst_y, dst_width, dst_height, src, src_rect, opacity, filter, sampling,
    blend_mode, segment_x_start, segment_y_start, segment_x_end, segment_y_end,
  )
}

///|
fn blend_sampled_pixmap_rect_region(
  dst : Pixmap,
  x : Int,
  y : Int,
  width : Int,
  height : Int,
  src : Pixmap,
  src_rect : PixelRect,
  opacity : Double,
  filter : PaintFilter?,
  sampling : ImageSampling,
  blend_mode : BlendMode,
  x_start : Int,
  y_start : Int,
  x_end : Int,
  y_end : Int,
) -> Bool {
  match sampling {
    Nearest =>
      blend_scaled_pixmap_rect_region(
        dst, x, y, width, height, src, src_rect, opacity, filter, blend_mode, x_start,
        y_start, x_end, y_end,
      )
    Bilinear =>
      blend_scaled_pixmap_rect_bilinear_region(
        dst, x, y, width, height, src, src_rect, opacity, filter, blend_mode, x_start,
        y_start, x_end, y_end,
      )
    Bicubic =>
      blend_scaled_pixmap_rect_bicubic_region(
        dst, x, y, width, height, src, src_rect, opacity, filter, blend_mode, x_start,
        y_start, x_end, y_end,
      )
  }
}

///|
fn blend_tiled_pixmap_rect_region(
  dst : Pixmap,
  x : Int,
  y : Int,
  width : Int,
  height : Int,
  src : Pixmap,
  src_rect : PixelRect,
  opacity : Double,
  filter : PaintFilter?,
  blend_mode : BlendMode,
  x_start : Int,
  y_start : Int,
  x_end : Int,
  y_end : Int,
) -> Bool {
  guard width > 0 && height > 0 else { return false }
  guard src_rect.width > 0 && src_rect.height > 0 else { return false }
  let mut did_blend = false
  for py in y_start.. Bool {
  guard width > 0 && height > 0 else { return false }
  guard src_rect.width > 0 && src_rect.height > 0 else { return false }
  let mut did_blend = false
  for py in y_start.. Bool {
  guard width > 0 && height > 0 else { return false }
  guard src_rect.width > 0 && src_rect.height > 0 else { return false }
  let mut did_blend = false
  for py in y_start.. Bool {
  guard width > 0 && height > 0 else { return false }
  guard src_rect.width > 0 && src_rect.height > 0 else { return false }
  let mut did_blend = false
  for py in y_start.. Bool {
  let mut did_blend = false
  for py in y_start.. Int {
  guard dst_size > 0 && src_size > 0 else { return 0 }
  let numerator = (dst_offset * 2 + 1) * src_size
  let denominator = dst_size * 2
  (numerator / denominator).max(0).min(src_size - 1)
}

///|
fn blend_scaled_pixmap_bilinear_region(
  dst : Pixmap,
  x : Int,
  y : Int,
  width : Int,
  height : Int,
  src : Pixmap,
  opacity : Double,
  filter : PaintFilter?,
  blend_mode : BlendMode,
  x_start : Int,
  y_start : Int,
  x_end : Int,
  y_end : Int,
) -> Bool {
  let mut did_blend = false
  for py in y_start.. Bool {
  let mut did_blend = false
  for py in y_start.. Bool {
  guard should_blend_source_color(color, blend_mode) else { return false }
  dst.blend_pixel_with_mode(x, y, color, blend_mode)
  true
}

///|
fn scaled_source_position(
  dst_offset : Int,
  dst_size : Int,
  src_size : Int,
) -> Double {
  guard dst_size > 0 && src_size > 0 else { return 0.0 }
  (dst_offset.to_double() + 0.5) * src_size.to_double() / dst_size.to_double() -
  0.5
}

///|
fn sample_bilinear(src : Pixmap, x : Double, y : Double) -> Color {
  let x_floor = floor_to_int(x)
  let y_floor = floor_to_int(y)
  let x0 = x_floor.max(0).min(src.get_width() - 1)
  let y0 = y_floor.max(0).min(src.get_height() - 1)
  let x1 = (x_floor + 1).max(0).min(src.get_width() - 1)
  let y1 = (y_floor + 1).max(0).min(src.get_height() - 1)
  let tx = (x - x_floor.to_double()).max(0.0).min(1.0)
  let ty = (y - y_floor.to_double()).max(0.0).min(1.0)
  let c00 = src.get_pixel(x0, y0)
  let c10 = src.get_pixel(x1, y0)
  let c01 = src.get_pixel(x0, y1)
  let c11 = src.get_pixel(x1, y1)
  let alpha = bilinear_value(
    c00.a.to_int().to_double(),
    c10.a.to_int().to_double(),
    c01.a.to_int().to_double(),
    c11.a.to_int().to_double(),
    tx,
    ty,
  )
  Color::new(
    r=unpremul_channel(
      bilinear_value(
        premul_channel(c00.r, c00.a),
        premul_channel(c10.r, c10.a),
        premul_channel(c01.r, c01.a),
        premul_channel(c11.r, c11.a),
        tx,
        ty,
      ),
      alpha,
    ),
    g=unpremul_channel(
      bilinear_value(
        premul_channel(c00.g, c00.a),
        premul_channel(c10.g, c10.a),
        premul_channel(c01.g, c01.a),
        premul_channel(c11.g, c11.a),
        tx,
        ty,
      ),
      alpha,
    ),
    b=unpremul_channel(
      bilinear_value(
        premul_channel(c00.b, c00.a),
        premul_channel(c10.b, c10.a),
        premul_channel(c01.b, c01.a),
        premul_channel(c11.b, c11.a),
        tx,
        ty,
      ),
      alpha,
    ),
    a=round_to_byte(alpha),
  )
}

///|
fn sample_bilinear_rect(
  src : Pixmap,
  x : Double,
  y : Double,
  rect : PixelRect,
) -> Color {
  let x_floor = floor_to_int(x)
  let y_floor = floor_to_int(y)
  let left = rect.x.max(0).min(src.get_width() - 1)
  let top = rect.y.max(0).min(src.get_height() - 1)
  let right = rect.right().max(left + 1).min(src.get_width())
  let bottom = rect.bottom().max(top + 1).min(src.get_height())
  let x0 = x_floor.max(left).min(right - 1)
  let y0 = y_floor.max(top).min(bottom - 1)
  let x1 = (x_floor + 1).max(left).min(right - 1)
  let y1 = (y_floor + 1).max(top).min(bottom - 1)
  let tx = (x - x_floor.to_double()).max(0.0).min(1.0)
  let ty = (y - y_floor.to_double()).max(0.0).min(1.0)
  let c00 = src.get_pixel(x0, y0)
  let c10 = src.get_pixel(x1, y0)
  let c01 = src.get_pixel(x0, y1)
  let c11 = src.get_pixel(x1, y1)
  let alpha = bilinear_value(
    c00.a.to_int().to_double(),
    c10.a.to_int().to_double(),
    c01.a.to_int().to_double(),
    c11.a.to_int().to_double(),
    tx,
    ty,
  )
  Color::new(
    r=unpremul_channel(
      bilinear_value(
        premul_channel(c00.r, c00.a),
        premul_channel(c10.r, c10.a),
        premul_channel(c01.r, c01.a),
        premul_channel(c11.r, c11.a),
        tx,
        ty,
      ),
      alpha,
    ),
    g=unpremul_channel(
      bilinear_value(
        premul_channel(c00.g, c00.a),
        premul_channel(c10.g, c10.a),
        premul_channel(c01.g, c01.a),
        premul_channel(c11.g, c11.a),
        tx,
        ty,
      ),
      alpha,
    ),
    b=unpremul_channel(
      bilinear_value(
        premul_channel(c00.b, c00.a),
        premul_channel(c10.b, c10.a),
        premul_channel(c01.b, c01.a),
        premul_channel(c11.b, c11.a),
        tx,
        ty,
      ),
      alpha,
    ),
    a=round_to_byte(alpha),
  )
}

///|
fn sample_bicubic(src : Pixmap, x : Double, y : Double) -> Color {
  let x_floor = floor_to_int(x)
  let y_floor = floor_to_int(y)
  sample_bicubic_clamped(
    src,
    x_floor,
    y_floor,
    (x - x_floor.to_double()).max(0.0).min(1.0),
    (y - y_floor.to_double()).max(0.0).min(1.0),
    0,
    0,
    src.get_width(),
    src.get_height(),
  )
}

///|
fn sample_bicubic_rect(
  src : Pixmap,
  x : Double,
  y : Double,
  rect : PixelRect,
) -> Color {
  let x_floor = floor_to_int(x)
  let y_floor = floor_to_int(y)
  let left = rect.x.max(0).min(src.get_width() - 1)
  let top = rect.y.max(0).min(src.get_height() - 1)
  let right = rect.right().max(left + 1).min(src.get_width())
  let bottom = rect.bottom().max(top + 1).min(src.get_height())
  sample_bicubic_clamped(
    src,
    x_floor,
    y_floor,
    (x - x_floor.to_double()).max(0.0).min(1.0),
    (y - y_floor.to_double()).max(0.0).min(1.0),
    left,
    top,
    right,
    bottom,
  )
}

///|
fn sample_bicubic_clamped(
  src : Pixmap,
  x_floor : Int,
  y_floor : Int,
  tx : Double,
  ty : Double,
  left : Int,
  top : Int,
  right : Int,
  bottom : Int,
) -> Color {
  let x0 = (x_floor - 1).max(left).min(right - 1)
  let x1 = x_floor.max(left).min(right - 1)
  let x2 = (x_floor + 1).max(left).min(right - 1)
  let x3 = (x_floor + 2).max(left).min(right - 1)
  let y0 = (y_floor - 1).max(top).min(bottom - 1)
  let y1 = y_floor.max(top).min(bottom - 1)
  let y2 = (y_floor + 1).max(top).min(bottom - 1)
  let y3 = (y_floor + 2).max(top).min(bottom - 1)
  let c00 = src.get_pixel(x0, y0)
  let c10 = src.get_pixel(x1, y0)
  let c20 = src.get_pixel(x2, y0)
  let c30 = src.get_pixel(x3, y0)
  let c01 = src.get_pixel(x0, y1)
  let c11 = src.get_pixel(x1, y1)
  let c21 = src.get_pixel(x2, y1)
  let c31 = src.get_pixel(x3, y1)
  let c02 = src.get_pixel(x0, y2)
  let c12 = src.get_pixel(x1, y2)
  let c22 = src.get_pixel(x2, y2)
  let c32 = src.get_pixel(x3, y2)
  let c03 = src.get_pixel(x0, y3)
  let c13 = src.get_pixel(x1, y3)
  let c23 = src.get_pixel(x2, y3)
  let c33 = src.get_pixel(x3, y3)
  let alpha = bicubic_grid_value(
      c00.a.to_int().to_double(),
      c10.a.to_int().to_double(),
      c20.a.to_int().to_double(),
      c30.a.to_int().to_double(),
      c01.a.to_int().to_double(),
      c11.a.to_int().to_double(),
      c21.a.to_int().to_double(),
      c31.a.to_int().to_double(),
      c02.a.to_int().to_double(),
      c12.a.to_int().to_double(),
      c22.a.to_int().to_double(),
      c32.a.to_int().to_double(),
      c03.a.to_int().to_double(),
      c13.a.to_int().to_double(),
      c23.a.to_int().to_double(),
      c33.a.to_int().to_double(),
      tx,
      ty,
    )
    .max(0.0)
    .min(255.0)
  Color::new(
    r=unpremul_channel(
      clamp_premul_channel(
        bicubic_grid_value(
          premul_channel(c00.r, c00.a),
          premul_channel(c10.r, c10.a),
          premul_channel(c20.r, c20.a),
          premul_channel(c30.r, c30.a),
          premul_channel(c01.r, c01.a),
          premul_channel(c11.r, c11.a),
          premul_channel(c21.r, c21.a),
          premul_channel(c31.r, c31.a),
          premul_channel(c02.r, c02.a),
          premul_channel(c12.r, c12.a),
          premul_channel(c22.r, c22.a),
          premul_channel(c32.r, c32.a),
          premul_channel(c03.r, c03.a),
          premul_channel(c13.r, c13.a),
          premul_channel(c23.r, c23.a),
          premul_channel(c33.r, c33.a),
          tx,
          ty,
        ),
        alpha,
      ),
      alpha,
    ),
    g=unpremul_channel(
      clamp_premul_channel(
        bicubic_grid_value(
          premul_channel(c00.g, c00.a),
          premul_channel(c10.g, c10.a),
          premul_channel(c20.g, c20.a),
          premul_channel(c30.g, c30.a),
          premul_channel(c01.g, c01.a),
          premul_channel(c11.g, c11.a),
          premul_channel(c21.g, c21.a),
          premul_channel(c31.g, c31.a),
          premul_channel(c02.g, c02.a),
          premul_channel(c12.g, c12.a),
          premul_channel(c22.g, c22.a),
          premul_channel(c32.g, c32.a),
          premul_channel(c03.g, c03.a),
          premul_channel(c13.g, c13.a),
          premul_channel(c23.g, c23.a),
          premul_channel(c33.g, c33.a),
          tx,
          ty,
        ),
        alpha,
      ),
      alpha,
    ),
    b=unpremul_channel(
      clamp_premul_channel(
        bicubic_grid_value(
          premul_channel(c00.b, c00.a),
          premul_channel(c10.b, c10.a),
          premul_channel(c20.b, c20.a),
          premul_channel(c30.b, c30.a),
          premul_channel(c01.b, c01.a),
          premul_channel(c11.b, c11.a),
          premul_channel(c21.b, c21.a),
          premul_channel(c31.b, c31.a),
          premul_channel(c02.b, c02.a),
          premul_channel(c12.b, c12.a),
          premul_channel(c22.b, c22.a),
          premul_channel(c32.b, c32.a),
          premul_channel(c03.b, c03.a),
          premul_channel(c13.b, c13.a),
          premul_channel(c23.b, c23.a),
          premul_channel(c33.b, c33.a),
          tx,
          ty,
        ),
        alpha,
      ),
      alpha,
    ),
    a=round_to_byte(alpha),
  )
}

///|
fn floor_to_int(value : Double) -> Int {
  let truncated = value.to_int()
  if truncated.to_double() > value {
    truncated - 1
  } else {
    truncated
  }
}

///|
fn positive_mod(value : Int, modulus : Int) -> Int {
  guard modulus > 0 else { return 0 }
  let mut result = value % modulus
  if result < 0 {
    result = result + modulus
  }
  result
}

///|
fn bilinear_value(
  v00 : Double,
  v10 : Double,
  v01 : Double,
  v11 : Double,
  tx : Double,
  ty : Double,
) -> Double {
  let top = v00 * (1.0 - tx) + v10 * tx
  let bottom = v01 * (1.0 - tx) + v11 * tx
  top * (1.0 - ty) + bottom * ty
}

///|
fn bicubic_grid_value(
  v00 : Double,
  v10 : Double,
  v20 : Double,
  v30 : Double,
  v01 : Double,
  v11 : Double,
  v21 : Double,
  v31 : Double,
  v02 : Double,
  v12 : Double,
  v22 : Double,
  v32 : Double,
  v03 : Double,
  v13 : Double,
  v23 : Double,
  v33 : Double,
  tx : Double,
  ty : Double,
) -> Double {
  bicubic_value(
    bicubic_value(v00, v10, v20, v30, tx),
    bicubic_value(v01, v11, v21, v31, tx),
    bicubic_value(v02, v12, v22, v32, tx),
    bicubic_value(v03, v13, v23, v33, tx),
    ty,
  )
}

///|
fn bicubic_value(
  v0 : Double,
  v1 : Double,
  v2 : Double,
  v3 : Double,
  t : Double,
) -> Double {
  let t2 = t * t
  let t3 = t2 * t
  0.5 *
  (
    2.0 * v1 +
    (v2 - v0) * t +
    (2.0 * v0 - 5.0 * v1 + 4.0 * v2 - v3) * t2 +
    (-v0 + 3.0 * v1 - 3.0 * v2 + v3) * t3
  )
}

///|
fn premul_channel(channel : Byte, alpha : Byte) -> Double {
  channel.to_int().to_double() * alpha.to_int().to_double() / 255.0
}

///|
fn clamp_premul_channel(premul : Double, alpha : Double) -> Double {
  premul.max(0.0).min(alpha)
}

///|
fn unpremul_channel(premul : Double, alpha : Double) -> Byte {
  guard alpha > 0.0 else { return clamp_byte(0) }
  round_to_byte(premul * 255.0 / alpha)
}

///|
fn round_to_byte(value : Double) -> Byte {
  clamp_byte((value + 0.5).to_int())
}