function SeqQueue(size, maxWaiting) {
  this.lo = 0
  this.size = size
  this.maxWaiting = maxWaiting
  this.waiting = 0
  this.list = new Array(size)
  this.locked = true
}

SeqQueue.prototype.start = function(seq) {
  this.locked = false
  // The loop in maybeConsume() will make sure that the value wraps correctly
  // if necessary.
  this.lo = seq + 1
  this.maybeConsume()
}

SeqQueue.prototype.stop = function() {
  this.locked = true
  this.maybeConsume()
}

SeqQueue.prototype.push = function(seq, handler) {
  if (seq >= this.size) {
    return
  }

  this.list[seq] = handler
  this.waiting += 1
  this.maybeConsume()
}

SeqQueue.prototype.maybeConsume = function() {
  if (this.locked) {
    return
  }

  while (this.waiting) {
    // Did we reach the end of the loop? If so, start from the beginning.
    if (this.lo >= this.size) {
      this.lo = 0
    }

    var handler = this.list[this.lo]
    // Have we received it yet?
    if (handler) {
      this.list[this.lo] = void 0
      handler()
      this.lo += 1
      this.waiting -= 1
    }
    // Are we too much behind? If so, just move on.
    else if (this.waiting >= this.maxWaiting) {
      this.lo += 1
      this.waiting -= 1
    }
    // We don't have it yet, stop.
    else {
      break
    }
  }
}

module.exports = SeqQueue
