/**
*	@author Mike Chambers (mesh@adobe.com)
*	@customized Andrew Means (andrewembassy@gmail.com)
*/

/**
*	Constructor for the class.
*
*	@param {String} dataURL The path to the data that the class
*	will load (OPTIONAL)
*
*	@param {String} containerID The id of the div that accepts the content
*
*	@param {String} loadingID The id of the div that has the 'loading...' in it
*
*	@param {String} loadingMessage Text inside the 'loading...' div
*
*	@constructor
*/
function ajaxxer(dataURL,containerID,loadingID,loadingMessage) {
	if(dataURL != undefined) {
		this._dataURL = dataURL;
	}

	if(containerID != undefined) {
		this._containerID = containerID;
	}

	if(loadingID != undefined) {
		this._loadingID = loadingID;
	}

	if(loadingMessage != undefined) {
		this._loadingMessage = loadingMessage;
	}

	this._writeContainer();
	this._writeLoading();
}

//var to hold an instance of the XMLHTTPRequest object
ajaxxer.prototype._request = undefined;

/**************** Public APIs **********************/

/**
*	Tells the class to load its data and render the results.
*/
ajaxxer.prototype.load = function(pars)
{
	// show loading div
	document.getElementById(this._loadingID).style.display = "block";
	//get a new XMLHTTPRequest and store it in an instance var.
	this._request = this._getXMLHTTPRequest();

	//set the var so we can scope the callback
	var _this = this;

	//callback will be an anonymous function that calls back into our class
	//this allows the call back in which we handle the response (_onData())
	// to have the correct scope.
	this._request.onreadystatechange = function(){_this._onData()};
	this._request.open("GET", this._generateDataUrl(pars), true);
	this._request.send(null);
}

/***************Private Rendering APIs ********************/

//writes the top level div for the class / widget
ajaxxer.prototype._writeContainer = function()
{
	//styles should be in external CSS
	document.write("<div id='"+this._containerID+"'></div>");
}

//writes the top level div for the class / widget
ajaxxer.prototype._writeLoading = function()
{
	//styles should be in external CSS
	document.write("<div id='"+this._loadingID+"' class=\"loading\"><img src=\"images/loading.gif\" />" + this._loadingMessage + "</div>");
}

//renders the entire widget
ajaxxer.prototype._render = function(title) {
	var content = document.getElementById(this._containerID);
		content.innerHTML = title;

	//kill loading;
	document.getElementById(this._loadingID).style.display = "none";

}

/***************Private Data Loading Handlers*******************/

//return the URL from which the data will be loaded
ajaxxer.prototype._generateDataUrl = function(pars)
{
	return this._dataURL + '?' + pars;
}

//callback for when the data is loaded from the server
ajaxxer.prototype._onData = function()
{
	if(this._request.readyState == 4)
	{
		if(this._request.status == "200")
		{
			this._render(this._request.responseText);

			//if the onDraw callback has been defined
			//call it to let the listener know
			//that we are done creating the list
			if(this.onDraw != undefined)
			{
				this.onDraw();
			}
		}
		else
		{
			//check if an error callback handler has been defined
			if(this.onError != undefined)
			{
				//pass an object to the callback handler with info
				//about the error
				this.onError({status:this_request.status,
						statusText:this._request.statusText});
			}
		}

		//clean up
		delete this._request;
	}
}

/***************Private Data Util Functions ********************/

//returns an XMLHTTPRequest instance (based on browser)
ajaxxer.prototype._getXMLHTTPRequest = function()
{
	var xmlHttp;
	try
	{
		xmlHttp = new ActiveXObject("Msxml2.XMLHttp");
	}
	catch(e)
	{
		try
		{
			xmlHttp = new ActiveXObject("Microsoft.XMLHttp");
		}
		catch(e2)
		{
		}
	}

	if(xmlHttp == undefined && (typeof XMLHttpRequest != 'undefined'))
	{
		xmlHttp = new XMLHttpRequest();
	}

	return xmlHttp;
}
