/*
	This library contains the primary ajax functionality provided by the Tangora Framework.
	The published public object is called ts_ajax
*/

// function prototype to allow innerHTML to be used as both a metod and a property
TAjax.prototype.innerHTML = "";	
	

// Class factory for retrieving "ajax" data. Use innerHTML to get data.
function TAjax () {	

	// class container used to hold values for the "TAjax" ClassFactory
	function TAjaxStorage () {
		this.ajaxObj = null;						// instance of a xmlhttprequest (type) object
		this.callback = _AsyncCallback;				// callback function to handle the onreadystatechange event on ajaxObj		
		this.statusElement = null;					// A html element to display status info in
		this.resultElement = null;					// A html element to display the recived data
		this.statusText_Get = "Henter...";			// status text, while fetching
		this.statusText_Done = "Færdig...";			// status text, when done
		this.method = "get";						// The method to use when fetching data - default value = get
		this.postData = "";							// Used to hold postdata
		this.srcFrm = null;							// Used to hold a reference to the form
		this.IF = null;								// Used to hold a IFRAME reference
		this.getPostData = _getPostData;			// Fetches element data form a form				
		
		function _getPostData(fm) {
			var form = null;
			if (typeof (fm)!="undefined") {
				if (typeof (fm)=="string") {
					form = eval ("document."+fm);	// Resolve the formname
				} else {
					form = fm;
				}
			} else {
				form=eval ("document.rediger");		// Resolve the formname, default to rediger
			}	
			this.srcFrm = form;
			var i,item;								// Declare vars
			var poststring = "";
			var supressAmpersand = false;
			for (i=0;i<form.elements.length;i++) {	// Iterate all form elements
				item=form.elements[i];
				if (i>0 && !supressAmpersand) {
					poststring=poststring+'&';
				}
				if ((item.type=='checkbox' || item.type=='radio') && !item.checked) {}
				else {
					if (item.type=='button' || item.type=='submit') {
						supressAmpersand=true;
					} else {					
						poststring=poststring+item.name+'='+encodeURIComponent(item.value);
						supressAmpersand=false;
					}
				}
			}
			this.postData = poststring;
		}
		
	}

	this.storage = new Array;					// Named array to hold namedInstances of asyncronous calls (TAjaxStorage)
		
	this.innerHTML = _ajaxInnerHTML;			// The main data recieve function
	this.createInstance = _createInstance;		// Programmatic interface to create a namedInstance of the TAjaxStorage, usefull to specify a custom callback function and to redifine statustext
	this.getModalDIV = _getModalDIV;


	// Creates an instance of TAjaxStorage and assignes it to the storage array, if it allready exists it returns the old instance
	function _createInstance(instanceName) {
		if (this.storage[instanceName]==null) {
			this.storage[instanceName] = new TAjaxStorage();		
			this.storage[instanceName].ajaxObj = getHTTPObject(); // Create xmlhttprequest object (in case of custom headers)
		}
		return this.storage[instanceName];
	}

	/* 
	The infamous innerHTML method, used either syncronously or asyncronously

	AS	: string url = the url to call
	A   : string myName = instanceName of the classFactory (TAjax), NB! this instance ' Importent only for async calls
	A   : string instanceName = the instanceName of the current async call container, needs only to be unique while the request is not completed
	A	: string/object destObj = element to hold result values: if the type is string then it is interpreted as an element id, otherwise as the element itself - can be null
	A	: string/object statusObj = element to hold status values: if the type is string then it is interpreted as an element id, otherwise as the element itself - can be null	
	A	: function callback = custom callback function to override default behaviour, can be null
	A	: boolean nocache = determines wether or not caching is allowed. true (default) = nocahe
	*/
	function _ajaxInnerHTML (url, myName, instanceName, destObj, statusObj, callback, nocache) {	
		var async = true;
		if (typeof(nocache)=="undefined") 
		{
			url+="&nocache=true";
		}
		else
		{
			if (nocache) 
			{
				url+="&nocache=true";
			}
			else 
			{
				url+="&nocache=false"
			}
		}
		if (!myName) {async=false}
		
		if (instanceName=="") {instanceName="default"}	 // If no instanceName is given use a default one - named "default" 	
		this.createInstance(instanceName); // Create a storage, if not allready done
		
		var thisInstance = this.storage[instanceName];	 // Create a "local" instance of the storage (to avoid code bloat)		
		if (thisInstance.ajaxObj==null) {thisInstance.ajaxObj = getHTTPObject()} // Create the xmlhttprequest object, if not allready defined
		if (typeof (callback)!="undefined") {thisInstance.callback = callback;}	 // If a callback event is provided, then use that one instead of our own
		if (thisInstance.ajaxObj!=null) {
			try {
				thisInstance.ajaxObj.open (thisInstance.method,url,async);					 // Open the ajax request
			} catch(e) {
				thisInstance.ajaxObj = getHTTPObject();								 // Mozill Firefox hack to trap the evil "NS_ERROR_FAILIURE" bug, If the error occured, then recreate the xmlhttprequest object
				thisInstance.ajaxObj.open (thisInstance.method,url,async);					 // And open (again) 
			}
		}
		if (async) {
			// Async handler
			if (typeof (statusObj)=="string") {thisInstance.statusElement=document.getElementById(statusObj)} // If the statusObj is a string, it is expected to be an id... fetch the element
			if (typeof (statusObj)=="object") {thisInstance.statusElement = statusObj;}						  // If the statusObj is an object, then ... just set it
			
			if (typeof (destObj)=="string") {thisInstance.resultElement = document.getElementById(destObj);}  // If the destObj is a string, it is expected to be an id... fetch the element
			if (typeof (destObj)=="object") {thisInstance.resultElement = destObj;}							  // If the destObj is an object, then ... just set it
			
			if (thisInstance.statusElement!=null) {thisInstance.statusElement.innerHTML = thisInstance.statusText_Get;}	 // If a valid html object is specified to hold status info, the set the "get" status text
			if (thisInstance.ajaxObj != null) {
				thisInstance.ajaxObj.onreadystatechange=function() { eval(myName+".storage[instanceName].callback()")};		 // Resolve the "onreadystatechange" function callback handler				
				if (thisInstance.method=="get") {
					thisInstance.ajaxObj.send("");	// Send and exit
				} else {
					thisInstance.ajaxObj.setRequestHeader('Content-Type','application/x-www-form-urlencoded; charset=UTF-8');
					thisInstance.ajaxObj.send(thisInstance.postData);	// Send and exit
				}
				return;
			} else {					
				thisInstance.IF = getIF();
				if (thisInstance.method=="post") {						
					tsCompat.addEvent(thisInstance.IF,"onload",function () {eval(myName+".storage[instanceName].callback()")});
					document.body.insertBefore(thisInstance.IF, null);
					if (thisInstance.srcFrm.id=="") {thisInstance.srcFrm.id=thisInstance.srcFrm.name}
					thisInstance.IF.contentWindow.document.write ("<body>" + thisInstance.srcFrm.outerHTML + "</body>");
					var tmp = thisInstance.IF.contentWindow.document.getElementById(thisInstance.srcFrm.name);
					tmp.submit();
				} else {
					tsCompat.addEvent(thisInstance.IF,"onload",function() { eval(myName+".storage[instanceName].callback()")});
					document.body.insertBefore(thisInstance.IF, null);
					thisInstance.IF.src = url;
				}
				return;
			}
			
		} else {
			if (thisInstance.method=="get") {
				thisInstance.ajaxObj.send("");	// Send and wait
			} else {
				if (thisInstance.ajaxObj!=null) {
					thisInstance.ajaxObj.setRequestHeader('Content-Type','application/x-www-form-urlencoded; charset=UTF-8');
					thisInstance.ajaxObj.send(thisInstance.postData);	// Send postdata and wait
				} else {					
					var modal = getModalDIV();
					thisInstance.IF = getIF();
					if (thisInstance.method=="post") {						
						tsCompat.addEvent(thisInstance.IF,"onload",doWait);
						document.body.insertBefore(thisInstance.IF, null);
						if (thisInstance.srcFrm.id=="") {thisInstance.srcFrm.id=thisInstance.srcFrm.name}
						thisInstance.IF.contentWindow.document.write ("<body>" + thisInstance.srcFrm.outerHTML + "</body>");
						var tmp = thisInstance.IF.contentWindow.document.getElementById(thisInstance.srcFrm.name);
						tmp.submit();
					}
					return;
				}
			}
			return (thisInstance.ajaxObj.responseText);	// return the fetched data
		}	
	}	

	function _AsyncCallback() {
		if (this.ajaxObj!=null) {
			if (this.ajaxObj.readyState==4) {
				var RT = this.ajaxObj.responseText;
				if (this.statusElement!=null) {this.statusElement.innerHTML = this.statusText_Done;}
				if (this.resultElement!=null) {this.resultElement.innerHTML = RT}
			} else {
				
			}			
		} else {
			var RT = this.IF.innerHTML;
			if (this.statusElement!=null) {this.statusElement.innerHTML = this.statusText_Done;}
			if (this.resultElement!=null) {this.resultElement.innerHTML = RT}
		}
	}					
	
	function _getModalDIV(id) {
		if (typeof (id)=="undefined") {id="modal"}
		var modal = document.getElementById(id);
		if (modal==null) {
			modal = document.createElement("DIV");
			modal.style.position="absolute";
			//modal.style.height = "100%";
			//modal.style.width = "100%";
			modal.style.left = 0;
			modal.style.top = 0;
			modal.className="statusdialog";
			modal.style.visibility = "visible";
			modal.id=id;
			//modal.innerHTML = "<center><table width=10% height=100%><tr><td style='font-size:50pt;' align=center valign=middle><div style='background-color:gray;border:1px inset black;padding:8px;'>GEMMER</div></td></tr></table></center>";
			modal.innerHTML = "<table cellspacing=0 cellpadding=0 border=0><tbody><tr align=middle><td class=statusdialogcontents id=tssavestatuscontents valign=center><b>"+admlib1021+"...</b></td></tr></tbody></table>";
			modal.style.cursor="hand";
			modal.style.zIndex=100;					
			tsCompat.addEvent (modal, "onclick", negatory);												
			document.body.insertBefore(modal, null);
			
			var body = document.body;
			var x = body.scrollLeft + (body.clientWidth - modal.offsetWidth) / 2;
			var y = body.scrollTop + (body.clientHeight - modal.offsetHeight) / 2;
			modal.style.top = y;
			modal.style.left = x;
			
			modal.style.display = "block";				
		} else {
			modal.style.display = "block";
		}
		return modal;
	}
	
	function getIF() {
		var IF = document.getElementById("XYZ");
		if (IF!=null) {
			IF.parentNode.removeChild(IF);
		}
		IF = document.createElement("IFRAME");
		IF.src = "about:blank";
		IF.name = "XYZ";
		IF.id = "XYZ";
		IF.style.position="absolute";
		IF.style.visibility="hidden";
		IF.style.zIndex=99;
		IF.style.top=0;
		IF.style.left=0;
		return IF;
	}
		
	function doWait() {	
		document.getElementById("modal").style.display="none";
	}

	function negatory() {
		return false;
	}
	
}

// ----------------------

tsAjax = new TAjax();

// ----------------------
