       @animationIndices = @indices.slice()
       @redraw()
 
+  ###
+  # Placeholders to fill in with data/stats.
+  # They don't change, calculate them once.
+  ###
   domStats:
     swaps: $("#js-swaps")
     inserts: $("#js-inserts")

        slideRange = [step.i..step.j]
      else
        slideRange = [step.j..step.i]
      @redraw()
      @ctx.fillStyle = @colors.slide
      for x in slideRange
        @drawIndex(x)
      @ctx.fillStyle = @colors.insert
      @drawIndex(step.i)
      setTimeout =>

  scale: (value) =>
    @height / @maxIndex * value

  ###
  # Draw the line at the specified index.
  # @param {number} index the index to draw
  # @param {boolean} markForRedraw false if it doesn't need a redraw next time.
  ###
  drawIndex: (index, markForRedraw = true) =>
    @markedForRedraw.push index if markForRedraw
    @ctx.fillRect(2 * index * @barWidth, @height - @scale(@animationIndices[index]), @barWidth, @scale(@animationIndices[index]))

  ###
  # Redraw a part of the canvas.
  # @param {array[number]} range array of the indices to redraw. It must
  #   represent a range.
  ###
  redrawParts: (range) ->
    @ctx.clearRect(2 * _.first(range) * @barWidth, 0, 2 * range.length * @barWidth, @height)
    @ctx.fillStyle = @colors.normal
    for index in range
      @drawIndex(index, false)

  ###
  # Redraw the persistent highlight.
  ###
  redrawPersistentHighlight: ->
    @ctx.fillStyle = @colors.persistHighlight
    for index in @currentHighlight
      @drawIndex(index, false)

  ###
  # Redraw the parts of the canvas which were recently colorized.
  ###
  redrawIfNeeded: ->
    if @markedForRedraw.length
      for range in @markedForRedraw
        if !$.isArray range
          range = [range]
        @redrawParts range
    @redrawPersistentHighlight()
    @markedForRedraw = []

  ###
  # Redraw all of the canvas.
  ###
  redraw: =>
    @redrawParts [0...@length]
    @redrawPersistentHighlight()

  shuffle: =>
    # Fisher-Yates shuffle
