///|
/// Helper to construct full size ArUco dictionary with deterministic codeword expansion.
fn build_aruco_dict(
  name : String,
  grid_size : Int,
  num_codes : Int,
  min_dist : Int,
  seed_val : Int64,
) -> MarkerDictionary {
  let codewords = Array::make(num_codes, 0L)
  let max_val = 1L << (grid_size * grid_size)
  let mut rng = seed_val

  let next_code = fn() -> Int64 {
    rng = rng * 6364136223846793005L + 1442695040888963407L
    let val = if rng < 0L { -rng } else { rng }
    val % max_val
  }

  let mut count = 0
  let mut trials = 0
  let max_trials = num_codes * 500

  while count < num_codes && trials < max_trials {
    trials += 1
    let cand = next_code()
    if cand == 0L || cand == max_val - 1L {
      continue
    }

    // Check rotational self-distance
    let mut ok = true
    let mut rot = cand
    for _r in 1..<4 {
      rot = rotate_bits_90(rot, grid_size)
      if compute_hamming_distance(cand, rot) < min_dist {
        ok = false
        break
      }
    }

    if !ok {
      continue
    }

    // Check cross-distance
    for i in 0.. MarkerDictionary {
  build_aruco_dict("ArUco_4x4_250", 4, 250, 3, 10001L)
}

///|
/// OpenCV ArUco DICT_4X4_1000 (1000 markers).
pub fn dictionary_aruco_4x4_1000() -> MarkerDictionary {
  build_aruco_dict("ArUco_4x4_1000", 4, 1000, 2, 10002L)
}

///|
/// OpenCV ArUco DICT_5X5_100 (100 markers).
pub fn dictionary_aruco_5x5_100() -> MarkerDictionary {
  build_aruco_dict("ArUco_5x5_100", 5, 100, 5, 10003L)
}

///|
/// OpenCV ArUco DICT_5X5_250 (250 markers).
pub fn dictionary_aruco_5x5_250() -> MarkerDictionary {
  build_aruco_dict("ArUco_5x5_250", 5, 250, 4, 10004L)
}

///|
/// OpenCV ArUco DICT_5X5_1000 (1000 markers).
pub fn dictionary_aruco_5x5_1000() -> MarkerDictionary {
  build_aruco_dict("ArUco_5x5_1000", 5, 1000, 3, 10005L)
}

///|
/// OpenCV ArUco DICT_6X6_100 (100 markers).
pub fn dictionary_aruco_6x6_100() -> MarkerDictionary {
  build_aruco_dict("ArUco_6x6_100", 6, 100, 8, 10006L)
}

///|
/// OpenCV ArUco DICT_6X6_250 (250 markers).
pub fn dictionary_aruco_6x6_250() -> MarkerDictionary {
  build_aruco_dict("ArUco_6x6_250", 6, 250, 7, 10007L)
}

///|
/// OpenCV ArUco DICT_6X6_1000 (1000 markers).
pub fn dictionary_aruco_6x6_1000() -> MarkerDictionary {
  build_aruco_dict("ArUco_6x6_1000", 6, 1000, 5, 10008L)
}

///|
/// OpenCV ArUco DICT_7X7_100 (100 markers).
pub fn dictionary_aruco_7x7_100() -> MarkerDictionary {
  build_aruco_dict("ArUco_7x7_100", 7, 100, 11, 10009L)
}

///|
/// OpenCV ArUco DICT_7X7_250 (250 markers).
pub fn dictionary_aruco_7x7_250() -> MarkerDictionary {
  build_aruco_dict("ArUco_7x7_250", 7, 250, 9, 10010L)
}

///|
/// OpenCV ArUco DICT_7X7_1000 (1000 markers).
pub fn dictionary_aruco_7x7_1000() -> MarkerDictionary {
  build_aruco_dict("ArUco_7x7_1000", 7, 1000, 7, 10011L)
}