///|
// Dot system for 3D Pacman

///|
struct Dot {
  x : Double
  y : Double
  collected : Bool
}

///|
// Global dot storage
let dots : Array[Dot] = []

///|
// Initialize dots in the maze (place them in empty spaces)
fn init_dots() -> Unit {
  dots.clear()
  let map = get_map()
  for y in 0.. Int? {
  for i, dot in dots {
    if !dot.collected {
      let dx = dot.x - x
      let dy = dot.y - y
      let distance = (dx * dx + dy * dy).sqrt()
      if distance < radius {
        return Some(i)
      }
    }
  }
  None
}

///|
// Collect a dot
fn collect_dot(index : Int) -> Unit {
  if index < dots.length() {
    dots[index] = { ..dots[index], collected: true }
    @audio.play_audio("assets/coin.wav")
  }
}

///|
// Get total number of dots in current level
fn get_total_dots() -> Int {
  dots.length()
}

///|
// Get number of collected dots
fn get_collected_dots() -> Int {
  dots.filter(fn(dot) { dot.collected }).length()
}

///|
// Check if half or more dots have been collected (for minimap visibility)
fn half_dots_collected() -> Bool {
  let total = get_total_dots()
  let collected = get_collected_dots()
  if total == 0 {
    return false
  }
  collected >= total / 2
}

///|
// Check if all dots have been collected
fn all_dots_collected() -> Bool {
  for dot in dots {
    if !dot.collected {
      return false
    }
  }
  return true
}

///|
// Check if player is near a dot and collect it
fn check_dot_collection() -> Unit {
  let collection_radius = 20.0 // Distance to collect dot
  match get_dot_at(player_state.x, player_state.y, collection_radius) {
    Some(index) => {
      collect_dot(index)
      // Check if all dots collected and advance level
      if all_dots_collected() {
        next_level()
        reset_level()
      }
    }
    None => ()
  }
}