     tapp : tapp
   }
 
+#Give n position: [x,y,t] and delta: [dx,dy,dt],
+# Return position with biggest time <= t (inclusive).
+firstPositionBefore = (pos, delta, time) ->
+  # find integer i:
+  # t + i*dt < time
+  #
+  # i*dt < time - t
+  # i < (time-t)/dt
+  i0 = (time - pos[2]) / delta[2] #not integer.
+  #now find the nearest integer below
+  i = (Math.floor i0) |0
+  #and return the position
+  vecSum pos, vecScale delta, i
+  
+firstPositionAfter = (pos, delta, time) ->
+  i0 = (time - pos[2]) / delta[2] #not integer.
+  i = (Math.ceil i0) |0
+  vecSum pos, vecScale delta, i
+
+    
+#Normalize pattern and returns its rle.
 normalizedRle = (fld) ->
   ff = Cells.copy fld
   Cells.normalize ff

    time += 1
  return

class Library
  constructor: (@rule) ->
    @rle2pattern = {}

isValidOffset = ([dx, dy, dt]) -> ((dx+dt)%2 is 0) and ((dy+dt)%2 is 0)
############################

showCollision = (collision)->
  console.log "##########################################################"
  for key, value of collision
    switch key
      when "collision"
        null
      when "products"
        for p, i in value
          console.log "####       -> #{i+1}: #{JSON.stringify p}"
      when "patterns"
        [p1,p2] = collision.patterns
        console.log "####   patterns: #{Cells.to_rle p1}, #{Cells.to_rle p2}"
      else
        console.log "####   #{key}: #{JSON.stringify value}"

#### colliding with offset [0,0,0]
#### CP: {"dist":0,"npos0":[0,0,0],"npos1":[0,0,0],"tcoll":0}
#### AP: {"approach":true,"npos0":[-30,0,-180],"npos1":[0,0,-180],"tapp":-180}
#### Collision RLE: $1379bo22$2o2$2o
      

runCollider = ->
  #single rotate - for test
  rule = from_list_elem [0,2,8,3,1,5,6,7,4,9,10,11,12,13,14,15]
  
  #2-block
  pattern1 = Cells.from_rle "$2o2$2o"
  pattern2 = Cells.from_rle "o"
  
  v2 = (determinePeriod rule, pattern2, 0).delta
  v1 = (determinePeriod rule, pattern1, 0).delta
  
  library = new Library rule
  library.addRle "$2o2$2o"
  library.addRle "bo$2b2o$3bo"
  library.addRle "2bobo$b2o"
  library.addRle "b2o2$2o"
  library.addRle "bo$bo$2o"
  library.addRle "o$o2$o$o"
  
  library.addRle "o"
  library.addRle "oo"
  
  console.log "Two velocities: #{v1}, #{v2}"
  [freeIndex, freeOrt] = opposingOrt v1, v2
  console.log "Free offset direction: #{freeOrt}, free index is #{freeIndex}"
  
  pv1 = removeComponent v1, freeIndex
  pv2 = removeComponent v2, freeIndex
  console.log "Projected to null-space of free ort:"
  console.log " PV1=#{pv1}, PV2=#{pv2}"
  
  s = area2d pv1, pv2
  console.log "Area of non-free section: #{s}"
  
  ecell = (restoreComponent(v,freeIndex) for v in elementaryCell(pv1, pv2))
  console.log "Elementary cell size: #{ecell.length}"
  for p, i in ecell
    console.log "  #{i}: " + JSON.stringify(p)
  
  #now we are ready to perform collisions
  # free index changes unboundedly, other variables change inside the elementary cell
  
  offsetRange = [-40, 30]
  
  for xFree in [offsetRange[0] .. offsetRange[1]] by 1
    for offset in ecell
      offset = offset[..]
      offset[freeIndex] = xFree
      if isValidOffset offset
        collision = doCollision rule, pattern1, v1, pattern2, v2, offset
        showCollision collision if collision.collision


runCollider()
