// Ported from topojson-client v3.1.0 src/transform.js (ISC; see LICENSE).

///|
fn Topology::point(self : Topology, p : Json) -> Array[Double] {
  let out = array(p).map(number)
  let tr = field(self.data, "transform")
  if tr != Json::null() {
    let s = array(field(tr, "scale"))
    let t = array(field(tr, "translate"))
    out[0] = out[0] * number(s[0]) + number(t[0])
    out[1] = out[1] * number(s[1]) + number(t[1])
  }
  out
}

///|
/// Decode one signed arc. Negative i means reverse arc -i-1 after delta decoding.
pub fn Topology::arc(
  self : Topology,
  index : Int,
) -> Array[Array[Double]] raise TopoError {
  let arcs = array(field(self.data, "arcs"))
  if index < -arcs.length() || index >= arcs.length() {
    raise Invalid("arc.index")
  }
  let id = if index < 0 { -index - 1 } else { index }
  let input = array(arcs[id])
  let tr = field(self.data, "transform")
  let mut x = 0.0
  let mut y = 0.0
  let out = input.map(fn(p) {
    if tr == Json::null() {
      array(p).map(number)
    } else {
      let v = array(p).map(number)
      x += v[0]
      y += v[1]
      v[0] = x
      v[1] = y
      self.point(v.to_json())
    }
  })
  if index < 0 {
    out.rev()
  } else {
    out
  }
}