///|
/// PCD mass spectrometry format parser demo.
///
/// Demonstrates the PCD (Proteomics Computational Data) module for:
///   - Parsing PCD mass spectrometry data files
///   - Spectrum manipulation and querying
///   - Chromatogram generation (TIC, BPC)
///   - Peak filtering and metadata extraction
///   - Serialization (round-trip write/read)
///
/// Inspired by Biopython's Bio.PCD and related mass spec modules.
/// Run: moon run examples/pcd_demo
fn main {
  println("=== PCD Mass Spectrometry Parser Demo ===")
  println("Mass spectrometry data analysis tools")
  println("Reference: Biopython Bio.PCD")
  println("")

  // ------------------------------------------------------------------
  // 1. Parse PCD sample data
  // ------------------------------------------------------------------
  println("=== 1. Parsing PCD Sample Data ===")
  let content = @bio.pcd_sample()
  println("Input content (first 150 chars):")
  println(content[0:150].to_owned())
  println("")

  let file = @bio.pcd_parse(content)
  println("Parsed PCD file:")
  println("  Version: " + file.version)
  println("  Number of spectra: " + file.num_spectra.to_string())
  println("  Total peaks: " + file.num_peaks.to_string())
  println("")

  // ------------------------------------------------------------------
  // 2. List all spectra
  // ------------------------------------------------------------------
  println("=== 2. Spectrum Details ===")
  let mut i = 1
  while i <= file.num_spectra {
    match file.get_spectrum(i) {
      Some(spec) => {
        println("  Spectrum " + spec.scan_number.to_string() + ":")
        println("    Retention time: " + spec.rt.to_string() + " min")
        println("    Number of peaks: " + spec.num_peaks().to_string())
        println("    Total intensity: " + spec.total_intensity().to_string())
        match spec.precursor_mz {
          Some(mz) => println("    Precursor m/z: " + mz.to_string())
          None => println("    Precursor m/z: N/A")
        }
        match spec.precursor_charge {
          Some(z) => println("    Precursor charge: " + z.to_string())
          None => println("    Precursor charge: N/A")
        }

        // Show top 3 peaks
        println("    Top peaks (m/z, intensity):")
        let mut p = 0
        while p < spec.num_peaks() && p < 3 {
          let mz = spec.mz_values[p]
          let intensity = spec.intensity_values[p]
          println("      " + mz.to_string() + " -> " + intensity.to_string())
          p = p + 1
        }
        println("")
      }
      None => ()
    }
    i = i + 1
  }

  // ------------------------------------------------------------------
  // 3. Chromatogram generation
  // ------------------------------------------------------------------
  println("=== 3. Chromatogram Generation ===")

  // Total Ion Chromatogram (TIC)
  let tic = @bio.pcd_tic(file)
  println("Total Ion Chromatogram (TIC):")
  println("  Data points: " + tic.length().to_string())
  let mut max_tic = tic[0]
  let mut t = 1
  while t < tic.length() {
    if tic[t] > max_tic {
      max_tic = tic[t]
    }
    t = t + 1
  }
  println("  Max intensity: " + max_tic.to_string())
  println("")

  // Base Peak Chromatogram (BPC)
  let bpc = @bio.pcd_bpc(file)
  println("Base Peak Chromatogram (BPC):")
  println("  Data points: " + bpc.length().to_string())
  println("")

  // ------------------------------------------------------------------
  // 4. Spectrum querying
  // ------------------------------------------------------------------
  println("=== 4. Spectrum Querying ===")

  // Get spectrum by scan number
  println("Looking up spectrum #1:")
  match file.get_spectrum(1) {
    Some(spec) =>
      println(
        "  Found spectrum with " + spec.num_peaks().to_string() + " peaks",
      )
    None => println("  Not found")
  }

  // Filter by m/z range
  println("")
  println("Filtering spectrum #1 for m/z in range 500-600:")
  match file.get_spectrum(1) {
    Some(spec) => {
      let filtered = @bio.pcd_spectrum_by_mz(spec, 500.0, 600.0)
      println("  Peaks after filtering: " + filtered.num_peaks().to_string())
    }
    None => println("  Spectrum not found")
  }
  println("")

  // Total peaks in file
  println(
    "Total peaks across all spectra: " + @bio.pcd_total_peaks(file).to_string(),
  )
  println("Number of spectra: " + @bio.pcd_num_spectra(file).to_string())
  println("")

  // ------------------------------------------------------------------
  // 5. Round-trip serialization
  // ------------------------------------------------------------------
  println("=== 5. Round-trip Serialization ===")
  let written = @bio.pcd_write(file)
  println("Serialized PCD content (first 200 chars):")
  println(written[0:200].to_owned())
  println("")

  // Parse back and verify
  let file2 = @bio.pcd_parse(written)
  println("Re-parsed PCD file:")
  println(
    "  Spectra count match: " +
    (file.num_spectra == file2.num_spectra).to_string(),
  )
  println(
    "  Peak count match: " + (file.num_peaks == file2.num_peaks).to_string(),
  )
  println("")

  // ------------------------------------------------------------------
  // 6. Summary report
  // ------------------------------------------------------------------
  println("=== 6. Summary Report ===")
  let summary = @bio.pcd_summary(file)
  println(summary)

  println("=== PCD Demo Complete ===")
}