// The Ajax.Spinner object adds an 'hourglass' animation that follows
// the mouse cursor around, like the activity indicator in operating
// systems. It appears whenever there is a running Ajax request that
// has not completed, to indicate to the user that something is happening.

Ajax.Spinner = {
  
  requests: 0,
  
  initialize: function() {
    if (this.addSpinnerImage()) { this.registerMouseFollower(); };
    this.monitorAjaxCalls();
  },
  
  addSpinnerImage: function() {
    if (this.spinnerImage) { return false; }
    var insert = new Insertion.Bottom(document.body, '<img src="/images/ajax_spinner/spinner.gif" id="ajaxSpinnerImage" />');
    this.spinnerImage = $('ajaxSpinnerImage');
    this.spinnerImage.setStyle({
      position: 'absolute'
    });
    this.spinnerImage.hide();
    return true;
  },
  
  registerMouseFollower: function() {
    if (!this.spinnerImage) { return false; }
    Event.observe(document.body, 'mousemove', function(e) {
      this.spinnerImage.setStyle({
        left: (Event.pointerX(e) + 14) + 'px',
        top: (Event.pointerY(e) + 6) + 'px'
      });
    }.bind(this) );
  },
  
  monitorAjaxCalls: function() {
    Utils.intercept(Ajax.Request.prototype, 'initialize', 'spinner', function() {
      Ajax.Spinner.addRequest();
      this.initialize_without_spinner.apply(this, arguments);
    });
    
    Utils.intercept(Ajax.Request.prototype, 'respondToReadyState', 'spinner', function() {
      var complete = this._complete;
      this.respondToReadyState_without_spinner.apply(this, arguments);
      if (!complete && this._complete) { Ajax.Spinner.stopRequest(); }
    });
  },
  
  addRequest: function() {
    if (!this.spinnerImage) { return false; }
    this.requests++;
    this.setImageVisibility();
  },
  
  stopRequest: function() {
    if (!this.spinnerImage) { return false; }
    if (this.requests > 0) { this.requests--; }
    this.setImageVisibility();
  },
  
  setImageVisibility: function() {
    this.spinnerImage[this.requests > 0 ? 'show' : 'hide']();
  }
};

Event.onDOMReady(Ajax.Spinner.initialize.bind(Ajax.Spinner));
