/*
 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();

// ----------------------
