///|
/// A four segment ragdoll hanging from a static mount, then kicked sideways.
///
/// ```bash
/// moon run examples/ragdoll
/// ```
///
/// It shows the whole joint workflow: add bodies, remember their indices, then
/// wire them up with revolute joints on shared anchor points.
fn main {
  let world = @moonphys.World::new()
  let mount = world.add_body(
    @moonphys.Body::fixed(@moonphys.Shape::box(0.2, 0.1)).at(0.0, 6.0),
  )
  // Head, torso, thigh, shin: each one hangs one joint below the previous.
  let head = world.add_body(
    @moonphys.Body::box(0.3, 0.3).at(0.0, 5.4).with_density(0.6),
  )
  let torso = world.add_body(@moonphys.Body::box(0.3, 0.55).at(0.0, 4.5))
  let thigh = world.add_body(@moonphys.Body::box(0.18, 0.45).at(0.0, 3.45))
  let shin = world.add_body(@moonphys.Body::box(0.16, 0.4).at(0.0, 2.5))
  world.add_revolve_joint(mount, head, @moonphys.Vec2::new(0.0, 5.75))
  world.add_revolve_joint(head, torso, @moonphys.Vec2::new(0.0, 5.0))
  world.add_revolve_joint(torso, thigh, @moonphys.Vec2::new(0.0, 3.9))
  world.add_revolve_joint(thigh, shin, @moonphys.Vec2::new(0.0, 3.0))
  // A kick to the shin gets the whole chain swinging.
  world
  .body(shin)
  .apply_impulse(@moonphys.Vec2::new(6.0, 1.0), @moonphys.Vec2::new(0.0, -0.3))
  println("joints=" + world.joint_count().to_string())
  for step in 0..<600 {
    world.step(1.0 / 60.0)
    if step % 120 == 119 {
      println(
        "t=" +
        round(world.time(), 10.0).to_string() +
        " head.x=" +
        round(world.body(head).position().x(), 100.0).to_string() +
        " shin.x=" +
        round(world.body(shin).position().x(), 100.0).to_string(),
      )
    }
  }
}

///|
/// Round `value` to `scale` steps per unit.
fn round(value : Double, scale : Double) -> Double {
  (value * scale).round() / scale
}