///|
/// MMTF (Macromolecular Transmission Format) demo.
///
/// Demonstrates loading an MMTF structure, inspecting the hierarchy
/// (models/chains/groups/atoms), run-length and delta encoding,
/// text serialization round-trip, and conversion to a PDB Structure.
///
/// Run: moon run examples/mmtf_demo --target wasm-gc
fn main {
  // Load the sample MMTF structure
  let structure = @bio.mmtf_sample()

  println("=== MMTF Structure Demo ===")
  println("")

  // === Structure info ===
  println("1. Structure Info")
  let header = structure.get_header()
  let xtal = structure.get_xtal_info()
  println("   ID: \{structure.structure_id}")
  println("   Title: \{header.title}")
  println("   Resolution: \{header.resolution} Å")
  println("   R-Work: \{header.r_work}")
  println("   R-Free: \{header.r_free}")
  println("   Deposition Date: \{header.deposition_date}")
  println("   Release Date: \{header.release_date}")
  println("   Experimental Methods: \{header.experimental_methods.length()}")
  for m in header.experimental_methods {
    println("     - \{m}")
  }
  println("   Space Group: \{xtal.space_group}")
  println(
    "   Unit Cell: a=\{xtal.unit_cell[0]}, b=\{xtal.unit_cell[1]}, c=\{xtal.unit_cell[2]}",
  )
  println("")

  // === Models, chains, groups, atoms ===
  println("2. Hierarchy")
  println("   Models: \{structure.get_num_models()}")
  println("   Chains (all models): \{structure.count_chains()}")
  println("   Groups (all models): \{structure.count_groups()}")
  println("   Atoms (all models): \{structure.count_atoms()}")
  println("   Bonds: \{structure.bonds.length()}")
  println("   Entities: \{structure.entities.length()}")
  println("")

  // === Detail per model/chain/group ===
  println("3. Detail")
  let models = structure.get_models()
  for mi = 0; mi < models.length(); mi = mi + 1 {
    let model = models[mi]
    println("   Model \{model.model_id}:")
    let chains = model.get_chains()
    for ci = 0; ci < chains.length(); ci = ci + 1 {
      let chain = chains[ci]
      let seq = @bio.mmtf_chain_sequence(chain)
      println(
        "     Chain \{chain.chain_id} (name=\{chain.chain_name}): \{chain.get_num_groups()} groups, sequence='\{seq}'",
      )
      let groups = chain.get_groups()
      for gi = 0; gi < groups.length(); gi = gi + 1 {
        let group = groups[gi]
        println(
          "       Group \{group.group_name} \{group.group_number} (\{group.single_letter_code}) ss=\{group.sec_struct.to_string()} atoms=\{group.get_num_atoms()}",
        )
        let atoms = group.get_atoms()
        for ai = 0; ai < atoms.length(); ai = ai + 1 {
          let atom = atoms[ai]
          println(
            "         Atom \{atom.name} serial=\{atom.serial} (\{atom.x}, \{atom.y}, \{atom.z}) element=\{atom.element}",
          )
        }
      }
    }
  }
  println("")

  // === Run-length encoding/decoding ===
  println("4. Run-Length Encoding")
  let chain_id_list = [0, 0, 0, 1, 1, 2, 2, 2, 2]
  let encoded = @bio.mmtf_encode_run_length(chain_id_list)
  println("   Original: \{chain_id_list.length()} values")
  println("   Encoded: \{encoded.length()} values (pairs of value,count)")
  let decoded = @bio.mmtf_decode_run_length(encoded)
  println("   Decoded: \{decoded.length()} values")
  // Verify round-trip
  let mut rle_ok = true
  if decoded.length() != chain_id_list.length() {
    rle_ok = false
  } else {
    for i = 0; i < chain_id_list.length(); i = i + 1 {
      if decoded[i] != chain_id_list[i] {
        rle_ok = false
      }
    }
  }
  println("   Round-trip OK: \{rle_ok}")
  println("")

  // === Delta encoding/decoding ===
  println("5. Delta Encoding")
  let coords = [100, 101, 103, 106, 110, 115]
  let delta_encoded = @bio.mmtf_encode_delta(coords)
  println("   Original: \{Repr(coords)}")
  println("   Delta-encoded: \{Repr(delta_encoded)}")
  let delta_decoded = @bio.mmtf_decode_delta(delta_encoded)
  println("   Decoded: \{Repr(delta_decoded)}")
  println("")

  // === Text serialization round-trip ===
  println("6. Text Serialization")
  let text = @bio.mmtf_write_text(structure)
  println("   Written \{text.length()} chars of text")
  let parsed = @bio.mmtf_read_text(text)
  println("   Parsed back: ID=\{parsed.structure_id}")
  println("   Parsed models: \{parsed.get_num_models()}")
  println("   Parsed chains: \{parsed.count_chains()}")
  println("   Parsed groups: \{parsed.count_groups()}")
  println("   Parsed atoms: \{parsed.count_atoms()}")
  println("   Parsed bonds: \{parsed.bonds.length()}")
  println("")

  // === Convert to PDB Structure ===
  println("7. Convert to PDB Structure")
  let pdb = @bio.mmtf_to_pdb_structure(structure)
  println("   PDB ID: \{pdb.get_id()}")
  println("   PDB Models: \{pdb.get_num_models()}")
  println("   PDB Chains: \{pdb.get_num_chains()}")
  println("   PDB Residues: \{pdb.get_num_residues()}")
  println("   PDB Atoms: \{pdb.get_num_atoms()}")
  // Show first few residues
  let residues = pdb.get_residues()
  let limit = if residues.length() < 3 { residues.length() } else { 3 }
  for i = 0; i < limit; i = i + 1 {
    let r = residues[i]
    println(
      "   Residue[\{i}]: \{r.resname} \{r.chainid}\{r.resseq} atoms=\{r.get_num_atoms()} het=\{r.is_het()}",
    )
  }
  println("")

  // === Summary ===
  println("8. Summary")
  let summary = @bio.mmtf_summary(structure)
  println(summary)

  println("=== Done ===")
}