// GPX 导出:KML 文档 → GPX 1.1。
//
// 点、线都映射为 trkpt/rtept;面不做映射(GPX 无面)。

///|
/// 追加一个字符串(XML 转义)。
fn push_xml_escaped(out : Array[Byte], text : String) -> Unit {
  let data = @utf8.encode(text)
  let mut i = 0
  while i < data.length() {
    let b = data[i]
    if b == b'&' {
      push_lit(out, "&")
    } else if b == b'<' {
      push_lit(out, "<")
    } else if b == b'>' {
      push_lit(out, ">")
    } else {
      out.push(b)
    }
    i = i + 1
  }
}

///|
/// 追加一个坐标对。
fn push_trkpt(out : Array[Byte], p : KmlPoint) -> Unit {
  push_lit(out, "")
  match p.alt {
    Some(a) => {
      push_lit(out, "")
      push_lit(out, a.to_string())
      push_lit(out, "")
    }
    None => ()
  }
  push_lit(out, "")
}

///|
/// 追加一个 track。
fn push_trkseg(out : Array[Byte], ls : KmlLineString) -> Unit {
  push_lit(out, "")
  let mut i = 0
  while i < ls.points.length() {
    push_trkpt(out, ls.points[i])
    i = i + 1
  }
  push_lit(out, "")
}

///|
/// 把 KML 文档导出为 GPX 1.1。
pub fn to_gpx(doc : KmlDocument) -> String {
  let out : Array[Byte] = []
  push_lit(out, "")
  push_newline(out)
  push_lit(
    out, "",
  )
  push_newline(out)
  if doc.name != "" {
    push_lit(out, "")
    push_xml_escaped(out, doc.name)
    push_lit(out, "")
    push_newline(out)
  }
  let mut i = 0
  while i < doc.placemarks.length() {
    let pm = doc.placemarks[i]
    match pm.geometry {
      Some(Geometry::Point(p)) => {
        push_lit(out, "")
        push_xml_escaped(out, pm.name)
        push_lit(out, "")
      }
      Some(Geometry::LineString(ls)) => push_trkseg(out, ls)
      _ => ()
    }
    push_newline(out)
    i = i + 1
  }
  push_lit(out, "")
  @utf8.decode_lossy(Bytes::from_array(out))
}