
/* Throbber is a singleton class that implements 
 * a reference counting mechanism for displaying
 * a throbber. Use Throbber.retain() whenever an 
 * operation starts, and Throbber.release() 
 * when the operation finishes.
 * A good place to do this would be callRemote (which we're doing).
 *
 * This way, we can have several operations running
 * simultaneously and the throbber will be shown until
 * all of them are finished.
 */

var Throbber = new function() {
	/* This creates exactly one instance of our class (the singleton). 
	 * Wow! I wasn't aware that Javascript had anynomous Classes. Really nice!
	 */
	
	this.div_template = 
	'<div id="main_throbber">' +
	'<img src="/media/img/ajax-loader.gif" alt="Working..." />' +
	'</div>';
	
	this.retain_count = 0;
	this.visible = false;
	this.element = null;
	this.throbberbox = null;
	this.showTimer = null;
	this.showTimeout = 1000; /* in milliseconds */
	this.hideTimer = null;
	this.hideTimeout = 5000; /* if something takes longer than 5 seconds, we're screwed anyways */
	
	this.retain = function() {
        // write('increasing throbber ' + this.retain_count);
		this.retain_count++;
		this.updateUI();
	};
	
	this.release = function() {
		if(this.retain_count == 0) {
		    /* can happen because the menu list is in an iframe and that can cause a race condition */
			return;
		}
        // write('releasing throbber ' + this.retain_count);
		this.retain_count--;
		this.updateUI();
	};
	
	this.updateUI = function() {
		if(this.retain_count > 0) {			
			this.showDelayed();
		} else {
			this.hide();
		}
	};
	
	this.showDelayed = function() {
		if(!this.showTimer) {
			this.showTimer = setTimeout(this.show.bind(this), this.showTimeout);			
		}
	};
	
	this.hideDelayed = function() {
	    if(!this.hideTimer) {
			this.hideTimer = setTimeout(this.hide.bind(this), this.hideTimeout);			
		}
	};
	
	this.show = function() {
		if(this.visible)
			return;
		this.element = new Element('div');
		this.element.innerHTML = this.div_template; 
		this.throbberbox = new Lightbox(this.element);
		this.throbberbox.show(true, 'throbbox');
		this.visible = true;
		this.hideDelayed();
	};
	
	this.hide = function() {
		clearTimeout(this.showTimer); this.showTimer = null;
		clearTimeout(this.hideTimer); this.hideTimer = null;
		if(!this.visible)
			return;
		this.throbberbox.hide();
		this.visible = false;
		this.retain_count = 0;
	};
};
