/*  new AjaxManager();  */

AjaxManager = function() {
    this.processUrl = "";
    this.method     = "GET";
    this.response   = null;
    this.version    = "1.0";
    this.responseHandler = null;
    this.timeoutHandler = null;
    this.timeoutWait = 10000; //10 sec.

   var AjaxResponse = function() {
        this.text      = null;
        this.xml       = null;
        this.success   = false;
        this.completed = false;
    };
    
    var thisRef = this;

    /*public void */ 
    this.request = function() {
        if (arguments.length >= 1) {
            this.processUrl = arguments[0];
        }
        if (arguments.length >= 2) {
            this.responseHandler = arguments[1];
        }
                
        getNativeObj();
        validateRequest();
        this.response = new AjaxResponse();
        nativeObj.onreadystatechange = handleAsynchronous;  //set the handler
                
        isLoading = true;
        if (this.method == "GET") { 
            sendGetRequest();
        }
    }
        
    /*public obj  */ 
    this.requestSynchronous = function() {
        this.processUrl = arguments.length >= 1 ? arguments[0] : false;
        getNativeObj();
        validateRequest(true);
        this.response = new AjaxResponse();
                    
        if (this.method == "GET") {
            sendGetRequest(true);
        }
                
        handleSynchronous();
        return this.response;
    }
     
    /*private*/ var nativeObj = null;
    /*private*/ var isLoading = false; 
    
    /*PRIVATE METHODS:*/
    function sendGetRequest(blnsynchronous) {
        nativeObj.open("GET", thisRef.processUrl, !blnsynchronous);
        nativeObj.send(null);
        if(thisRef.timeoutHandler) {
			setTimeout(timeoutCheck, thisRef.timeoutWait);
        }
    }
      
    //ensures extensibility
    function handleSynchronous() {
        thisRef.response.completed = true;
        if (nativeObj.status==200 || nativeObj.status==0) {   
            processSuccessfulResponse();
        }
            
    }
    
    function handleAsynchronous() {
        if (nativeObj.readyState == 4) {   // if request of file complete
            isLoading = false;
            thisRef.response.completed = true;
            if (nativeObj.status == 200 || nativeObj.status == 0) {   
                processSuccessfulResponse();
            }
            thisRef.responseHandler(thisRef.response);
        }
    }
    
    function processSuccessfulResponse() {
        thisRef.response.success = true;
        thisRef.response.text = nativeObj.responseText;
        
        try {
            var xmldom = nativeObj.responseXML;
            if (xmldom.documentElement == null) {
                xmldom = getXMLDom();
                if (xmldom) { 
                    xmldom.loadXML(nativeObj.responseText);
                }
            }
            thisRef.response.xml = xmldom;
        } catch(e) { /*implement logging*/ }
    }
    
    function getXMLDom() {
        if (window.ActiveXObject) {
            try { return new ActiveXObject('MSXML3.DomDocument');    } catch(e) { /*implement logging*/ }
            try { return new ActiveXObject('MSXML2.DomDocument');    } catch(e) { /*implement logging*/ }
            try { return new ActiveXObject('MSXML.DomDocument');     } catch(e) { /*implement logging*/ }
            try { return new ActiveXObject('Microsoft.DomDocument'); } catch(e) { /*implement logging*/ }
        }
        return null;
    }
    
    function getNativeObj() { 
        if (window.XMLHttpRequest) {        // branch for native XMLHttpRequest object
            try { return nativeObj = new XMLHttpRequest(); } catch(e) { /*implement logging*/ }
        } else if (window.ActiveXObject) {   // branch for IE/Windows ActiveX version
            try { return nativeObj = new ActiveXObject("Msxml2.XMLHTTP.3.0"); } catch(e) { /*implement logging*/ }
            try { return nativeObj = new ActiveXObject("Msxml2.XMLHTTP");     } catch(e) { /*implement logging*/ }
            try { return nativeObj = new ActiveXObject("Microsoft.XMLHTTP");  } catch(e) { /*implement logging*/ }
        }
        return nativeObj = false;
    }
    
    function validateRequest() {
        var blnsynchronous = arguments.length >= 1 ? arguments[0] : false;
                
        if(thisRef.method != "GET") {
            throw("The specified request method is not supported");
        }
        if (thisRef.processUrl == "") {
            throw("Invalid URL");
        }
        if (isLoading) {
            throw("Previous request is still loading");
        }
        if (!nativeObj) {
            throw("Native Request Object cannot be built");
        }
        if (!thisRef.responseHandler && !blnsynchronous) {
            throw("Response Handler Not Set");
        }
    }

	function timeoutCheck() {
		if(!thisRef.response.completed) {
			nativeObj.abort();
			thisRef.timeoutHandler();
		}
	}
    /*END PRIVATE METHODS*/
    
}
