/*
	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 = function (fm)
		{
		    if (!$ts.exists(fm)) fm = "rediger";
		    this.srcFrm = $elm(fm);
		    if (!$ts.exists(this.srcFrm))
		    {
		        this.srcFrm = $elm('form[name="' + fm + '"]');
		        if ($ts.exists(this.srcFrm)) fm = this.srcFrm;
		    }
		    this.postData = $ts.collectFormValues(fm);
		}
		
	}

	this.storage = [];      					    // Named array to hold namedInstances of asyncronous calls (TAjaxStorage)

	/* 
	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
	*/
	this.innerHTML = function (url, myName, instanceName, destObj, statusObj, callback, nocache)
	{
	    var async = $ts.exists(myName);
	    if (!$ts.exists(nocache)) url += "&nocache=true";
	    else
	    {
	        url += nocache ? "&nocache=true" : "&nocache=false";
	    }
	    if ($ts.exists(instanceName) && instanceName == "") instanceName = "default";
	    else 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 (!$ts.exists(thisInstance.ajaxObj)) thisInstance.ajaxObj = getHTTPObject(); // Create the xmlhttprequest object, if not allready defined
	    if ($ts.exists(callback)) thisInstance.callback = callback;  // If a callback event is provided, then use that one instead of our own
	    if ($ts.exists(thisInstance.ajaxObj))
	    {
	        try { thisInstance.ajaxObj.open(thisInstance.method, url, async); }
	        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
	        thisInstance.statusElement = $elm(statusObj);
	        thisInstance.resultElement = $elm(destObj);

	        if ($ts.exists(thisInstance.statusElement)) thisInstance.statusElement.innerHTML = thisInstance.statusText_Get; // If a valid html object is specified to hold status info, the set the "get" status text
	        if ($ts.exists(thisInstance.ajaxObj))
	        {
	            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")
	            {
	                $ts.addEvent(thisInstance.IF, "load", 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
	            {
	                $ts.addEvent(thisInstance.IF, "load", 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 ($ts.exists(thisInstance.ajaxObj))
	            {
	                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")
	                {
	                    $ts.addEvent(thisInstance.IF, "load", 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
	    }
	}

	// Programmatic interface to create a namedInstance of the TAjaxStorage, usefull to specify a custom callback function and to redifine statustext
	// Creates an instance of TAjaxStorage and assignes it to the storage array, if it allready exists it returns the old instance
	this.createInstance = 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];
	}

	this.getModalDIV = function (id)
	{
	    if (!$ts.exists(id)) id = "modal";
	    var modal = document.getElementById(id);
	    if (modal === null)
	    {
	        modal = document.createElement("DIV");
	        modal.style.position = "absolute";
	        modal.style.left = 0;
	        modal.style.top = 0;
	        modal.className = "statusdialog";
	        modal.style.visibility = "visible";
	        modal.id = id;
	        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;
	        $ts.addEvent(modal, "click", 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 _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 
        {
			var RT = this.IF.innerHTML;
			if (this.statusElement!=null) this.statusElement.innerHTML = this.statusText_Done;
			if (this.resultElement!=null) this.resultElement.innerHTML = RT;
		}
	}					
	
	
	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();
