/**
   * Specialized wrapper around array which provides a toggle() method for viewing the contents of the
   * array in a manner that is asynchronously filled in over a short time period. This prevents long
   * pauses in the UI for ngRepeat's when the array is significant in size.
   */
angular.module('quay').factory('AngularViewArray', ['$interval', function($interval) {
  var ADDTIONAL_COUNT = 20;

  function _ViewArray() {
    this.isVisible = false;
    this.visibleEntries = null;
    this.hasEntries = false;
    this.entries = [];

    this.timerRef_ = null;
    this.currentIndex_ = 0;
  }

  _ViewArray.prototype.length = function() {
    return this.entries.length;
  };

  _ViewArray.prototype.get = function(index) {
    return this.entries[index];
  };

  _ViewArray.prototype.push = function(elem) {
    this.entries.push(elem);
    this.hasEntries = true;

    if (this.isVisible) {
      this.setVisible(true);
    }
  };

  _ViewArray.prototype.toggle = function() {
    this.setVisible(!this.isVisible);
  };

  _ViewArray.prototype.setVisible = function(newState) {
    this.isVisible = newState;

    this.visibleEntries = [];
    this.currentIndex_ = 0;

    if (newState) {
      this.showAdditionalEntries_();
      this.startTimer_();
    } else {
      this.stopTimer_();
    }
  };

  _ViewArray.prototype.showAdditionalEntries_ = function() {
    var i = 0;
    for (i = this.currentIndex_; i < (this.currentIndex_ + ADDTIONAL_COUNT) && i < this.entries.length; ++i) {
      this.visibleEntries.push(this.entries[i]);
    }

    this.currentIndex_ = i;
    if (this.currentIndex_ >= this.entries.length) {
      this.stopTimer_();
    }
  };

  _ViewArray.prototype.startTimer_ = function() {
    var that = this;
    this.timerRef_ = $interval(function() {
      that.showAdditionalEntries_();
    }, 10);
  };

  _ViewArray.prototype.stopTimer_ = function() {
    if (this.timerRef_) {
      $interval.cancel(this.timerRef_);
      this.timerRef_ = null;
    }
  };

  var service = {
    'create': function() {
      return new _ViewArray();
    }
  };

  return service;
}]);