/**
 * $Id: adtl.js,v 1.11 2006/09/18 07:58:13 coke Exp $
 * @author Simon Koster <simon@drecomm.nl>
 **/

/************************************
 * Ajax Data Tranfer Library [ADTL] *
 ************************************/

/**
 * Constructor
 **/
function ADTL(){
	var xmlhttp;
	/*@cc_on
	@if (@_jscript_version >= 5)
		try {
			xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
		} catch (e) {
			try {
				xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
			} 
			catch (E) {
				xmlhttp = false;
			}
		}
	@else
	xmlhttp = null;
	@end @*/
	if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
		try {
			xmlhttp = new XMLHttpRequest();
			//xmlhttp.overrideMimeType("text/xml"); 
		}
		catch (e) {
			xmlhttp = null;
		}
	}
	this.m_oXmlHttp = xmlhttp;
	this.m_aListeners = new Array();
	this.m_sUrl = null;
	this.m_bDebug = false;
}
/**
 * Error handler method
 *
 * Possible error codes:
 * CODE           MESSAGE
 * -------------------------------------------------------
 * noxml          ERROR: returned XML document is invalid.
 * 404            ERROR: url does not exist
 * error          Unknown error in sending request
 * busy           ERROR: already requesting data
 * unknowntarget  ERROR: Undefined URL
 * noxmlhttp      ERROR: XMLHTTP object is undefined
 **/
ADTL.prototype.errorHandler = function(p_sCode, p_sMsg){
	alert(p_sCode + ": " +  p_sMsg);
}

/**
 * Enable debug output method
 **/
ADTL.prototype.debug = function(p_bEnable){
	if(p_bEnable != null && p_bEnable == false){
		this.m_bDebug = false;
	}else{
		this.m_bDebug = true;
	}
}


/**
 * Add data listener
 **/
ADTL.prototype.addDataListener = function(p_sIdentifier, p_funListener){	
	/*if(this.m_aListeners[p_sIdentifier] != null){
		this.m_aListeners[p_sIdentifier][this.m_aListeners[p_sIdentifier].length] = p_funListener;
	}
	else*/
	{
		this.m_aListeners[p_sIdentifier] = new Array();
		this.m_aListeners[p_sIdentifier][0] = p_funListener;
	}
}

/**
 * Strip tags from a string
 * From http://prototype.conio.net/
 **/
String.prototype.stripTags = function() {
//	return this.replace(/<\/?[^>]+>/gi, '');
	var t = this.replace(/&lt;/gmi,"<");
	t = t.replace(/&gt;/gmi,">");
	t = t.replace(/&quot;/gmi,'"');

//	console.log("stripTags\t" + t);	
		
	return t;
}

/**
 * Convert html entities back
 * From http://prototype.conio.net/
 **/
String.prototype.unescapeHTML = function() {
	/*var div = document.createElement('div');
	div.innerHTML = this.stripTags();
	return div.childNodes[0] ? div.childNodes[0].nodeValue : '';*/
	return this.stripTags();	
}

/**
 * Transform XML Data Array to Array
 **/
ADTL.prototype.readOutXmlDataArray = function(p_oXmlData){
	var l_aReturnArray = new Array();
	for(var i=0;i<p_oXmlData.childNodes.length;i++){
		// Get data element
		var l_oDataElementNode = p_oXmlData.childNodes.item(i);
		if(l_oDataElementNode.nodeType == 1){
			// Get key of new array element
			var l_sKey = l_oDataElementNode.getAttribute("key");
			// Get content of new array element
			var l_bNestedArray = false;
			for(var j=0;j<l_oDataElementNode.childNodes.length;j++){
				if(l_oDataElementNode.childNodes.item(j).nodeName == "dataarray"){
					l_bNestedArray = true;
					var l_aValue = this.readOutXmlDataArray(l_oDataElementNode.childNodes.item(j));
				}
			}
			if(l_bNestedArray){
				l_aReturnArray[l_sKey] = l_aValue;
			}else{
				l_sStr = l_oDataElementNode.firstChild.nodeValue;
				l_aReturnArray[l_sKey] = l_sStr.unescapeHTML();
			}
		}
	}
	return l_aReturnArray;
}
/**
 * Fetch data from server
 **/
ADTL.prototype.fetchData = function(p_aVars, p_sUrl, p_aRef){
	// Define target URL
	var l_sTargetUrl = new String();
	if(p_sUrl != null){
		l_sTargetUrl = p_sUrl;
	}else{
		l_sTargetUrl = this.m_sUrl;
	}

	// Prepare and encode the vars that need to be posted with the HTTP request
	var l_sUrlEncodedVars = this.encodeDataToUrl(p_aVars);

	// Check if XmlHttp exists
	if(this.m_oXmlHttp != null){
		// Only Proceed when target URL is defined
		if(l_sTargetUrl != null){
			// Only proceed when XMLHTTP is not in the process of loading a document already
			if(this.m_oXmlHttp.readyState == 0 || this.m_oXmlHttp.readyState == 4 || this.m_oXmlHttp.readyState == null){
				try {
					this.m_oXmlHttp.open("POST", l_sTargetUrl, true);
					this.m_oXmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");
					/**
					 * This sets the onreadystatechange function. NOTE: Within this method it is not 
					 * possible to use the THIS reference to get the ADTL instance.
					 **/
					var l_oSelf = this;
					this.m_oXmlHttp.onreadystatechange = function(){

						// readState 4 means the document has been fully loaded
						if (l_oSelf.m_oXmlHttp.readyState == 4) {
							if(l_oSelf.m_oXmlHttp.status != 404){
								if(l_oSelf.m_bDebug){
									alert(l_oSelf.m_oXmlHttp.responseText);
								}
								var l_oXmlDoc = l_oSelf.m_oXmlHttp.responseXML;

								var l_oDataTranferNode;
								if(l_oXmlDoc != null){
									// Get datatransfer node
	
									for(var i=0;i<l_oXmlDoc.childNodes.length;i++){
										if(l_oXmlDoc.childNodes.item(i).nodeName == "datatransfer"){
											var l_oDataTranferNode = l_oXmlDoc.childNodes.item(i);
											// Loop through dataarrays
											for(var j=0;j<l_oDataTranferNode.childNodes.length;j++){
												if(l_oDataTranferNode.childNodes.item(j).nodeName == "dataarray" &&
												   l_oDataTranferNode.childNodes.item(j).getAttribute("identifier") != null){
													var l_sIdentifier = l_oDataTranferNode.childNodes.item(j).getAttribute("identifier");
													var l_oDataArrayNode = l_oDataTranferNode.childNodes.item(j);
													var l_aDataArray = l_oSelf.readOutXmlDataArray(l_oDataArrayNode);
													if(l_oSelf.m_aListeners[l_sIdentifier] != null){
														for(var l_iKey in l_oSelf.m_aListeners[l_sIdentifier]){
															l_oSelf.m_aListeners[l_sIdentifier][l_iKey](l_aDataArray, p_aRef);
														}
													}
												}
											}
										}
									}
								}else{
									l_oSelf.errorHandler('noxml','ERROR: Returned XML document is invalid.');
								}
							}else{
								// Error in loading document
								l_oSelf.errorHandler('404','ERROR: URL does not exist');
							}
						}
					}
					this.m_oXmlHttp.send(l_sUrlEncodedVars);
//					window.open(l_sTargetUrl+'?'+l_sUrlEncodedVars);
				}
				catch(e){
					// Error in loading document
					if(e.message == undefined){
						this.errorHandler('error', e);
					}else{
						this.errorHandler('error', e.message);
					}
				}
			}else{
				// XMLHTTP object is already loading in XML document
				this.errorHandler('busy', 'ERROR: Already requesting data');
			}
		}else{
			// No url provided
			this.errorHandler('unknowntarget', 'ERROR: Invalid URL');
		}
	}else{
		// XMLHTTP object is undefined
		this.errorHandler('noxmlhttp', 'ERROR: XMLHTTP object is undefined');
	}
}
/**
 * Encode data from array to be used in URL
 **/
ADTL.prototype.encodeDataToUrl = function(p_aVars){
	var l_sUrlEncodedVars = "";
	for(l_sKey in p_aVars){
		// Escape special characters in key and then unescape the brackets to allow for nested arrays in strings
		var l_sEscapedKey = escape(l_sKey);
		l_sEscapedKey = l_sEscapedKey.replace(/%5B/g, "[");
		l_sEscapedKey = l_sEscapedKey.replace(/%5D/g, "]");

		if(typeof p_aVars[l_sKey] == "object" || typeof p_aVars[l_sKey] == "array"){
			l_sUrlEncodedVars += this.encodeDataToUrlWalkArray(p_aVars[l_sKey], l_sEscapedKey);
		}else{
			l_sUrlEncodedVars += l_sEscapedKey + '=' + escape(p_aVars[l_sKey]) + '&';
		}
	}
	return l_sUrlEncodedVars;
}

/**
 * Walk the array recursively to encode the data capture inside
 **/
ADTL.prototype.encodeDataToUrlWalkArray = function(p_aVars, p_sArrayPrefix){
	var l_sUrlEncodedVars = "";
	for(l_sKey in p_aVars){
		// Escape special characters in key and then unescape the brackets to allow for nested arrays in strings
		var l_sEscapedKey = escape(l_sKey);
		l_sEscapedKey = l_sEscapedKey.replace(/%5B/g, "[");
		l_sEscapedKey = l_sEscapedKey.replace(/%5D/g, "]");

		// Check if p_aVars[l_sKey] is an array
		if(typeof p_aVars[l_sKey] == "object" || typeof p_aVars[l_sKey] == "array"){
			l_sUrlEncodedVars += this.encodeDataToUrlWalkArray(p_aVars[l_sKey], p_sArrayPrefix + "[" +l_sEscapedKey + "]");
		}else{
			l_sUrlEncodedVars += p_sArrayPrefix + "[" + l_sEscapedKey + "]" + '=' + escape(p_aVars[l_sKey]) + '&';
		}
	}
	return l_sUrlEncodedVars;
}

function inc(filename)
{
	var head = document.getElementsByTagName('head').item(0);
	script = document.createElement('script');
	script.src = filename;
	script.type = 'text/javascript';
	head.appendChild(script);
}
