/*
		File:		AjaxHelper class
		Version:	0.9
		Desc:		This class builds and returns XMLHttpRequests.
		Requires:	/pages/v4/script/dhtml_lib.js

		Use:		---USE DIRECTIONS HERE---

		Author:		John Resig (www.jquery.com) from the jquery library
				Adapted and modified by Eric Shepherd
		Date:		December 2006
		Methods:	The following methods are in this class.
		
				---METHOD DESCRIPTIONS GO HERE---
									
		Version History:
			0.9		EBS		There are issues with this script that prevent it from being fully functional, however, it will return html via an xmlhttprequest and place into an element
*/



	/* ------------------------------
			WRAPPER FOR IE
	------------------------------*/

if (!window.XMLHttpRequest) {
	XMLHttpRequest = function() {
		return new ActiveXObject('Microsoft.XMLHTTP');	
	}
}



// AjaxHelper Object
var AjaxHelper = {
	
	/* ------------------------------
			LOAD METHODS
			(Shortcut if you only need to place HTML content into a page element)
	------------------------------*/
	
	loadIfModified : function(el, url, params, callback) {
		this.load(el, url, params, callback, 1);
	},
	
	load : function(el, url, params, callback, ifModified) {
				// WE DON'T SUPPORT PASSING IN FUNCTIONS YET
		if (url.constructor == Function) {
			return; 
		}
				// proceed with normal load operation
		callback = callback || function() { };
				// default to a GET request
		var type = 'GET';
				// if the third parameter was provided
		if (params) {
					// if it's a function
			if (params.constructor == Function) {
						// we assume it's the callback
				callback = params;
				params = null;
			} else {
						// otherwise, build a param string
				params = this.param(params);
				type = "POST";
			}
		}
		var thisReference = this;
				// request the remote document
		this.ajax(type, url, params, function(res, status) {
			if (status == 'success' || !ifModified && status == 'notmodified') {
						// inject the html into all the matched elements
						// then evaluate scripts and execute callbacks
				el.innerHTML = res.responseText;
				thisReference.evalScripts(el);
				// need to do callbacks still
				//.evalScripts().each(callback, [res.responseText, status]);
				callback.apply(thisReference, [res.responseText, status]);
			} else {
				callback.apply(thisReference, [res.responseText, status]);
			}
			}, ifModified);
		return;
	},
	
	/* ------------------------------
			SERIALIZE
	------------------------------*/
	
	serialize : function() {
		return this.param(this);
	},
	
	/* ------------------------------
			EVALUATE SCRIPTS
	------------------------------*/
	
	evalScripts : function(el) {
		var scripts = el.getElementsByTagName('script');
		for (i=0; i<scripts.length; i++) {
			if (scripts[i].src) {
				this.getScript(scripts[i].src, function() {  });
			} else {
				eval.call(window, scripts[i].text || scripts[i].textContent || scripts[i].innerHTML || '');
			}
		}
	},
	
	/* ------------------------------
			GET METHODS
	------------------------------*/
	
	get : function(url, data, callback, type, ifModified) {
		if (data && data.constructor == Function) {
			type = callback;
			callback = data;
			data = null;
		}
		if (data) {
					// append ? + data or & + data in case there are already parameters
			url += ((url.indexOf('?') > -1) ? '&' : '?') + this.param(data);	
		}
				// build and start the http request
		var thisReference = this;
		this.ajax('GET', url, null, function(r,status) {
			if (callback) {
				callback(thisReference.httpData(r,type), status);	
			}
		}, ifModified);	
	},
	
	getIfModified : function(url, data, callback, type) {
		this.get(url, data, callback, type, 1);	
	},
	
	getScript : function(url, callback) {
		if (callback) {
			this.get(url,	 null, callback, 'script');
		} else {
			this.get(url, null, null, 'script');	
		}
	},
	
	getJSON : function(url, data, callback) {
		if (callback) {
			this.get(url, data, callback, 'json');
		} else {
			this.get(url, data, 'json');
		}
	},
	
	/* ------------------------------
			POST METHODS
	------------------------------*/
	
	post : function(url, data, callback, type) {
				// build and start the http request
		this.ajax('POST', url, this.param(data), function(r, status) {
			if (callback) {
				callback(this.httpData(r,type), staus);
			}
		});
	},
	
	/* ------------------------------
			TIMEOUT
	------------------------------*/
	
	timeout : 0,
	
	ajaxTimeout : function(timeout) {
		this.timeout = timeout;
	},
	
	/* ------------------------------
			Last Modified header cache for next request
	------------------------------*/
	
	lastModified : {},
	
	/* ------------------------------
			AJAX
	------------------------------*/
	
			// type can be 'get' or 'post', or it can be a closure containing type as a property, along with other properties defining callback functions like success and error
	ajax : function(type, url, data, ret, ifModified) {
				// if only single argument, assume that it is an object of name/value pairs
		var global = true;
		var timeout = this.timeout;
		if (!url) {
			ret = type.complete;
			var success = type.success;
			var error = type.error;
			var dataType = type.dataType;
			var global = typeof type.global == 'boolean' ? type.global : true;
			var timeout = typeof type.timeout == 'number' ? type.timeout : this.timeout;
			ifModified = type.ifModified || false;
			data = type.data;
			url = type.url;
			type = type.type;
		}
		if (global && ! this.active++) { // we do get in here on a normal load call
			//this.event.trigger('ajaxStart'); ////////////////////////////?????????????????????????
			//alert('ajax started');
		}
		var requestDone = false;
				// create the new request object
		
		var xml = new XMLHttpRequest();
		//alert(xml.status);
				// open the socket
				//alert('status: ' + xml.status);
		xml.open(type || 'GET', url, true);

		try { 
			//alert('status: ' + xml.status); 
		} catch(e) { 
			//alert('error: ' + e); 
		}
				// set the correct header if data is being sent
		if (data) {
			xml.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
		}
				//set the if-modified-since header, if ifModified mode
		if (ifModified) {
			xml.setRequestHeader('If-Modified-Since', this.lastModified[url] || 'Thu, 01 Jan 1970 00:00:00 GMT'); ////////////////////????????????????????????????
		}
				// set header so that the called script knows that it's an XMLHttpRequest
		xml.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
				// make sure the browser sends the right content length
		if (xml.overrideMimeType) {
			xml.setRequestHeader('Connection', 'close');
		}
		var thisReference = this;
		var onreadystatechange = function(istimeout) {
			//alert(istimeout + '|' + xml.readyState);
			
			if (xml && (xml.readyState == 4 || istimeout == 'timeout')) {
				requestDone = true;
				//alert(xml);
				var status = thisReference.httpSuccess(xml) && istimeout != 'timeout' ? ifModified && thisReference.httpNotModified(xml, url) ? 'notmodified' : 'success' : 'error';
				//alert(status);
						// make sure the request was successful or notmodified
				if (status != 'error') {
							// cache last-modified header, if ifModified mode
					var modRes;
					try {
						modRes = xml.getResponseHeader('Last-Modified');
					} catch(e) {
						// swallow exception thrown by Firefox if header not available
					}
					if (ifModified && modRes) {
						thisReference.lastModified[url] = modRes;
					}
							// if a local callback was specified, fire it now
					if (success) {
						success(thisReference.httpData(xml, dataType), status);
					}
							// fire the global callback
					if (global) {
						//thisReference.event.trigger('ajaxSuccess'); /////////////////////////////////?????????????????????????
						//alert('ajax successful');
					}
				} else {
							// the request was not successful
					if (error) {
								// if a local callback was specified, fire it now
						error(xml, status);
					}
							// fire the global callback
					if (global) {
						//thisReference.event.trigger('ajaxError');
						//alert('Ajax Error');
						// we get an error/completed series with the award link, success/completed with view larger
					}
				}
						// the request was completed
				if (global) {
					//thisReference.event.trigger('ajaxComplete'); ////////////////////////////////////////////////////
					//alert('ajax completed');
				}
						// handle the global ajax counter
				if (global && ! --this.active) {
					//alert('ajax stopped');
					//thisReference.event.trigger('ajaxStop'); /////////////////////////////////////////////////
				}
						// process result
				if (ret) ret(xml, status);
						// stop memory leaks
				xml.onreadystatechange = function() {};
				xml = null;
			}
		};
		xml.onreadystatechange = onreadystatechange;
				// timeout checker
		if (timeout > 0) {
			setTimeout(function(){
						// is the request still happening?
				if (xml) {
							// cancel the request
					xml.abort();
					if (!requestDone) {
						onreadystatechange('timeout');
					}
							// clear from memory
					xml = null;
				}
			}, timeout);
		}
				// send the data
		xml.send(data);
	},
	
	/* ------------------------------
			Number of active queries
	------------------------------*/
	
	active : 0,
	
	/* ------------------------------
			Successful?
	------------------------------*/
	
	httpSuccess : function(r) {
		try {
			//alert('try error');
			for (var i in r) {
				try {
					//alert(i+"|"+r[i]);
				} catch (e) {
					//alert(i+"|"+e);	
				}
			}
			return !r.status && location.protocol == 'file:' || (r.status >= 200 && r.status < 300) || r.status == 304 || SupportTest.isSafari && r.status == undefined;
		} catch(e) {	
			//alert('catch error: ' + e);
		}
		return false;
	},
	
	
	/* ------------------------------
			Not modified returned?
	------------------------------*/
	
	httpNotModified : function(xml, url) {
		try {
			var xmlRes = xml.getResponseHeader('Last-Modified');
					// firefox always returns 200 - check last modified date
			return xml.status == 304 || xmlRes == this.lastModified[url] || SupportTest.isSafari && xml.status == undefined; ////////////////////////////////////////////
		} catch(e) {
		}
		return false;
	},
	
	/* ------------------------------
			GET THE DATA
	------------------------------*/
	
			// get the data out of an XMLHttpRequest
			// return parsed xml if content-type is xml and type is xml or omitted
			// otherwise return plain text
			// (String) data = the type of data you're expecting to be returned ('xml', 'html', 'script')
	httpData : function(r,type) {
		//alert('entered httpData function');
		var ctype = r.getResponseHeader('content-type');
		var data = !type && ctype && ctype.indexOf('xml') >= 0;
		data = type == 'xml' || data ? r.responseXML : r.responseText;
				// if the type is script ,eval it
		if (type == 'script') {
			eval.call(window, data);
		}
				// get the javascript object, if json is used
		if (type == 'json') {
			eval('data = ' + data);
		}
				// evaluate scripts within html
		if (type == 'html') $('<div>').html(data).evalScripts(); /////////////////////////////////////////////////////////////////////////////
		
		return data;
	},
	
	/* ------------------------------
			Serialize form elements or key values into query string
	------------------------------*/
	
	param : function(a) {
		var s = [];
				// if array passed in, it could be an array of form elements
		if (a.constructor == Array) { ////////////////////////////////////////////////// compare - also an || a.jquery
			for (var i=0; i<a.length; i++) {
				s.push(a[i].name + '=' + encodeURIComponent(a[i].value));
			}
				// else assume it's name/value pairs
		} else {
			for (var j in a) {
				s.push(j + '=' + encodeURIComponent(a[j]));
			}
		}
	}
};





// add functions for common ajax tasks

new function() {
	var e = 'ajaxStart, ajaxStop,ajaxComplete,ajaxError,ajaxSuccess'.split(',');
			// loop and create functions as part of AjaxHelper object
	for (var i = 0; i<e.length; i++) new function() {
		var o = e[i];
		AjaxHelper[o] = function(f) {
			////////////////////////////////////////////////???????????????????????????
		}
	};
};




