///|
/// Renders an SVG overlay containing marker quads, ID labels, 3D coordinate axes, and bounding cubes.
pub fn render_detection_svg(
  img : Image,
  detections : Array[MarkerDetection],
  camera : CameraIntrinsics?,
  axis_length : Double,
) -> String {
  let buf = StringBuilder()
  buf.write_string(
    "\n",
  )

  // Background rect
  buf.write_string(
    "  \n",
  )

  for i in 0..\n",
      )

      // Top-Left corner indicator (Red dot)
      buf.write_string(
        "  \n",
      )

      // ID label text
      let cx = (p0.x + p1.x + p2.x + p3.x) / 4.0
      let cy = (p0.y + p1.y + p2.y + p3.y) / 4.0
      buf.write_string(
        "  ID: \{det.id}\n",
      )

      // Render 3D coordinate axes if pose and camera intrinsics are available
      match (det.pose, camera) {
        (Some(pose), Some(cam)) => {
          let origin_2d = project_3d_point(
            { x: 0.0, y: 0.0, z: 0.0 },
            pose,
            cam,
          )
          let axis_x_2d = project_3d_point(
            { x: axis_length, y: 0.0, z: 0.0 },
            pose,
            cam,
          )
          let axis_y_2d = project_3d_point(
            { x: 0.0, y: axis_length, z: 0.0 },
            pose,
            cam,
          )
          let axis_z_2d = project_3d_point(
            { x: 0.0, y: 0.0, z: axis_length },
            pose,
            cam,
          )

          // X axis (Red)
          buf.write_string(
            "  \n",
          )
          // Y axis (Green)
          buf.write_string(
            "  \n",
          )
          // Z axis (Blue)
          buf.write_string(
            "  \n",
          )
        }
        _ => ()
      }
    }
  }

  buf.write_string("\n")
  buf.to_string()
}

///|
/// Generates a synthetic fiducial marker image for ArUco or AprilTag dictionaries.
pub fn generate_synthetic_marker_image(
  id : Int,
  dict : MarkerDictionary,
  marker_pixel_size : Int,
  margin_pixels : Int,
) -> Image? {
  if id < 0 || id >= dict.codewords.length() || marker_pixel_size <= 0 {
    return None
  }

  let total_img_size = marker_pixel_size + margin_pixels * 2
  let canvas = Image::new(total_img_size, total_img_size)
  canvas.fill(255) // White background

  let codeword = dict.codewords[id]
  let data_grid_size = dict.grid_size
  let total_grid_cells = data_grid_size + 2
  let cell_size = marker_pixel_size / total_grid_cells

  // Draw black outer border + payload grid
  for r in 0..> bit_idx) & 1L) == 0L
      }

      let color = if is_black { 0 } else { 255 }
      let start_x = margin_pixels + c * cell_size
      let start_y = margin_pixels + r * cell_size

      for py in 0..