     [canvas.width, canvas.height] = @oldSize
     @oldSize = null
     canvasSizeUpdateBlocked = false
-
-  beginWork: ->
+    redraw()
+
+  _beginWork: ->
+    @busy = true
     @_setCanvasSize()
     console.log "Started animation"
     
-  endWork: ->
+  _endWork: ->
     @_restoreCanvasSize()
     console.log "End animation"
+    @busy = false
         
   cancelWork: ->
-    return unless @uploadWorker
-    clearInterval @uploadWorker
+    return unless @busy
+    clearTimeout @uploadWorker is @uploadWorker
     @uploadWorker = null
-    @endWork()
+    @_endWork()
     
   animate: (observer, stepsPerGen, generations, callback)->
     return unless @startChain? and @endChain?

  constructor: ->
    @oldSize = null
    @uploadWorker = null
    @reset()

  assertNotBusy: ->
    if @uploadWorker isnt null
      throw new Error "Animator is busy"
      
  reset: ->
    if @uploadWorker isnt null
      @cancelWork()
    @startChain = null
    @startOffset = null
    @endChain = null

    framesBeforeGeneration = stepsPerGen

    imageNameTemplate = E('upload-name').value
    @_beginWork()
    uploadStep = =>
      @uploadWorker = null
      observer.navigateTo @startChain, @startOffset
      p = index / totalSteps
      observer.modifyView M.hyperbolicInv Tinterp(p)
      drawEverything()
      
      imageName = formatString imageNameTemplate, [pad(index,4)]
      uploadToServer imageName, (ajax)=>
        if ajax.readyState is XMLHttpRequest.DONE and ajax.status is 200
          console.log "Upload success"
          index +=1
          framesBeforeGeneration -= 1
          if framesBeforeGeneration is 0
            doStep()
            framesBeforeGeneration = stepsPerGen

          if index <= totalSteps
            console.log "request next frame"
            @uploadWorker = flipSetTimeout 1, uploadStep
          else
            @_endWork()
        else
          console.log "Upload failure, cancel"
          console.log ajax.responseText
          @_endWork()
          
    uploadStep()
    
flipSetTimeout = (t, cb) -> setTimeout cb, t

serverSupportsUpload = -> ((""+window.location).match /:8000\//) and true
# ============================================  app code ===============
