/**
*
* This class is used for displaying "loading" widgets in moviedollars, such
*	as when the contents of a dropdown are updated dynamically.
*
* Example:
*
* element.loadingWidget("Categories")
* // category loading code...
* element.loadingWidget()
*
* The above code will display "loading" next to the element in question, and
*	append the string "Loading: Categories" next to the title of the page.
*
* loadingWidget() can be called multiple times safely.  If multiple elemenst
*	are in the process of being loaded, this widget will do the right thing
*	and display the messages as a comma delimited message.
*
* After an item is completely loaded, just call loadingWidget() again with
*	no parameters and the loading dialogue will be removed, as will the item
*	from the title list.
*/


/**
* A global variable here for holding widget data between invocations.
* I am unclear on how to do static variables in jQuery plugins, so this
*	will have to suffice for now.
*/
var loadingWidgetData = {};
loadingWidgetData["ids"] = {};
loadingWidgetData["timeout"] = "";
loadingWidgetData["interval"] = 100;
loadingWidgetData["interval_original"] = loadingWidgetData["interval"];

/**
*/
jQuery.fn.loadingWidget = function(message) {

	//
	// Sabitize our argument.
	//
	if (typeof(message) == "undefined") {
		message = "";
	}

	/**
	* Return the ID attribute from an element.  Throw an exception if 
	*	that attribute does not exist.
	*/
	function getId(element) {

		retval = element.attr("id");

		if (typeof(retval) == "undefined") {
			var error = "An ID attribute is required on this element.";
			throw(error);
		}

		return(retval);

	} // End of getId()


	/**
	* "store" the message in the array of widget data.  If message is
	*	empty, then we are deleting that record.
	*/
	function storeMessage(id, message) {

		if (message != "") {
			loadingWidgetData["ids"][id] = message;

		} else {
			delete loadingWidgetData["ids"][id];

		}

	} // End of storeMessage()


	/**
	* Update our element so that it cause a "loading" widget displayed after
	*	it, or removed if the message is empty.
	*/
	function updateElement(element, message) {

		if (message != "") {
			var loading = "<span class=\"loadingWidget\" >Loading...</span>";
			element.parent().append(loading);

		} else {
			element.parent().find(".loadingWidget").remove();

		}

	} // End of updateElement()


	/**
	* Go through our widget data and create a string to display with the 
	*	general loading status.
	*/
	function getSummaryMessage() {

		var retval = "";

		for (k in loadingWidgetData["ids"]) {
			if (retval) {
				retval += ", ";
			}

			retval += loadingWidgetData["ids"][k];

		}

		if (retval) {
			retval = "Loading: " + retval;
		}

		return(retval);

	} // End of getSummaryMessage()


	/**
	* Add some progress to our progress meter.
	*/ 
	function addProgress() {
		jQuery(".loadingWidgetSummary").append(".");
		scheduleProgressMeter();
	}


	/**
	* Return our progress interval in milliseconds, increasing it
	* until a specified peak.
	*/
	function getProgressInterval() {

		var retval = loadingWidgetData["interval"];

		loadingWidgetData["interval"] += 100;
		if (loadingWidgetData["interval"] > 1000) {
			loadingWidgetData["interval"] = 1000;
		}

		//jQuery("h3").append(retval); // Debugging

		return(retval);
	}


	/**
	* Set our progress interval back to its original value.
	*/
	function resetProgressInterval() {
		loadingWidgetData["interval"] = 
			loadingWidgetData["interval_original"];
		//jQuery("h3").append("DONE"); // Debugging
	}


	/**
	* Schedule the next iteration of the progress meter.
	*/
	function scheduleProgressMeter() {
		var interval = getProgressInterval();
		loadingWidgetData["timeout"] = setTimeout(addProgress, interval);
	}


	/**
	* Stop the progress meter, we're done.
	*/
	function stopProgressMeter() {
		clearTimeout(loadingWidgetData["timeout"]);
		loadingWidgetData["timeout"] = "";
		resetProgressInterval();
	}


	/**
	* Set the summary message.
	*/
	function setSummaryMessage(message) {

		//
		// Remove the existing sumamry mesage.
		//
		$(".loadingWidgetSummary").remove();

		if (message) {
			var summary = $("<span/>");
			summary.text(message);
			summary.addClass("loadingWidgetSummary");
	
			jQuery("h3").append(summary);

			//
			// Stop any progress meters we have currently scheduled,
			// and start a new one.
			//
			stopProgressMeter();
			if (!loadingWidgetData["timeout"]) {
				scheduleProgressMeter();
			}

		} else {
			//
			// We have nothing loading and therestop nothing to print.
			// Stop the progress meter.
			//
			stopProgressMeter();

		}

	} // End of setSummaryMessage()


	//
	// Main program.  This loops through each element in the chain.
	//
	return(this.each(function() {

		var element = jQuery(this);
		var id = getId(element);

		updateElement(element, message);
		storeMessage(id, message);

		var display_message = getSummaryMessage();
		setSummaryMessage(display_message);

		}));

} // End of loadingWidget()



