import {mapThrough, nullMap} from "./map"

export class Step {
  constructor(name, from, to, pos, param = null) {
    this.name = name
    this.from = from
    this.to = to
    this.pos = pos
    this.param = param
  }
}

const steps = Object.create(null)

export function defineStep(name, impl) { steps[name] = impl }

export function applyStep(doc, step) {
  if (!(step.name in steps))
    throw new Error("Undefined transform " + transform.name)
  return steps[step.name].apply(doc, step)
}

export function invertStep(step, oldDoc, map) {
  return steps[step.name].invert(step, oldDoc, map)
}

export class TransformResult {
  constructor(doc, map = nullMap) {
    this.doc = doc
    this.map = map
  }
}

export class Transform {
  constructor(doc) {
    this.doc = doc
    this.docs = []
    this.steps = []
    this.maps = []
  }

  step(step, from, to, pos, param) {
    if (typeof step == "string")
      step = new Step(step, from, to, pos, param)
    let result = applyStep(this.doc, step)
    if (result) {
      this.steps.push(step)
      this.maps.push(result.map)
      this.docs.push(this.doc)
      this.doc = result.doc
    }
    return result
  }
}

export function Tr(doc) { return new Transform(doc) }

@@ -753,38 +753,41 @@
 ) %7B%0A    this.doc
+s
  = 
+%5B
 doc
+%5D
 %0A    this.docs =
@@ -776,27 +776,28 @@
 c%5D%0A    this.
-doc
+step
 s = %5B%5D%0A    t
@@ -792,35 +792,34 @@
 s = %5B%5D%0A    this.
-ste
+ma
 ps = %5B%5D%0A    this
@@ -808,39 +808,128 @@
 maps = %5B%5D%0A  
-  this.maps = %5B
+%7D%0A%0A  get doc() %7B%0A    return this.docs%5Bthis.docs.length - 1%5D%0A  %7D%0A%0A  get before() %7B%0A    return this.docs%5B0
 %5D%0A  %7D%0A%0A  ste
@@ -1190,35 +1190,8 @@
 ush(
-this.doc)%0A      this.doc = 
 resu
@@ -1196,16 +1196,17 @@
 sult.doc
+)
 %0A    %7D%0A 

Make collab tests pass again using new data structures