/**All calls should be made to this static factory.
 a single factory is needed since the browser cannot handle calls in parallel.
 The factory will queue up the calls and make the calls in order.
*/
var httpRequestFactory = new MbHttpRequestFactory();

function handleReadyStateChange()
{
    httpRequestFactory.handleRequest();
}

/**
use createRequest to get a request object given a name.

*/
function MbHttpRequestFactory()
{
    this.outstandingRequests = new Array();

    this.currentlyRequesting;

    this.handleRequest = function()
    {
        var request = this.currentlyRequesting;
        var message = "";
        var complete = false;
        //if any are found to be ready, but not called then put them here.
        if(request != null)
        {
            var readyState = request.httpRequest.readyState;
            switch(readyState)
            {
                case 0:
                    message = "Requesting " + request.requestName;
                    break;
                case 1:
                    message = "Loading " + request.requestName;
                    break;
                case 2:
                case 3:
                    message = "Processing " + request.requestName;
                    break;
                case 4:
                    message = request.requestName + "  loaded";
                    complete = false;
                    request.complete();
                    this.sendAnother();
                    request.getStatusMessage().hideMessage(3000);
                    break;
                default:
                    alert('unhandled status ' + request.httpRequest.readyState);
            }
	        request.getStatusMessage().showMessage(message);
        }
        else
        {
            this.sendAnother();
        }
    }    

	/**Make another request when freed up */
    this.sendAnother = function()
    {
        this.currentlyRequesting = this.outstandingRequests.pop();
        if(this.currentlyRequesting != null)
        {
            this.currentlyRequesting.makeRequest();
        }
    }



	/**the factory method to get a request and register it to the queue for processing*/
    this.createRequest = function(requestName)
    {
        var request = new MbHttpRequest(requestName);
        request.setFactoryHandlerMethod(handleReadyStateChange);
         this.outstandingRequests.push(request);
        return request;
    }
}

var POST_METHOD ="POST";
var GET_METHOD = "GET";

/**
An encapsulation of a request object.
setUrl is a good function  to start with.
setAsynch to true (usually the case)
set a listener that will be called once the request is complete
the call makeRequest();
*/
function MbHttpRequest(requestName)
{
	this.method = GET_METHOD;
	this.data = null;
    this.requestName = requestName;
    this.
    Errors=false;

    /**use the default status message unless otherwise assigned with setStatusMessage*/
	this.statusMessage = statusMessage;
    this.readyToSend = false;

    this.asynch = false;
    this.setAsynch = function (asynch) { this.asynch = asynch;}

    this.url;
    this.setUrl = function(url) {this.url = url;}

    this.factoryHandlerMethod;
    this.setFactoryHandlerMethod  = function(factoryHandlerMethod) { this.factoryHandlerMethod = factoryHandlerMethod; }

    this.listener;
    
    this.send = function()
    {
        this.readyToSend = true;
        httpRequestFactory.handleRequest();
    }

	this.changeStatusMessage = function(statusMessageElement)
	{
		this.statusMessage = new StatusMessage(statusMessageElement);
	}
	
	this.getStatusMessage = function() { return this.statusMessage; }
	
	this.setMethodToPost = function() { this.method = POST_METHOD;}
	
	this.setData = function(data) { this.data = data;}
	/**the method used to send a request to the server.
	*/
    this.makeRequest = function()
    {
        this.httpRequest;
        // branch for native XMLHttpRequest object
        if (window.XMLHttpRequest) 
        {
            this.httpRequest = new XMLHttpRequest();
            this.httpRequest.onreadystatechange = this.factoryHandlerMethod;
            this.httpRequest.open(this.method, this.url, this.asynch);
            if (this.method == POST_METHOD && this.data) {
	            this.httpRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
	        }
            this.httpRequest.send(this.data);
        // branch for IE/Windows ActiveX version
        } 
        else if (window.ActiveXObject) 
        {
            this.httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
            if (this.httpRequest) 
            {
                this.httpRequest.onreadystatechange = this.factoryHandlerMethod;
                this.httpRequest.open(this.method, this.url, this.asynch);
	            if (this.method == POST_METHOD && this.data) {
		            this.httpRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
		        }
                this.httpRequest.send(this.data);
            }
        }
    }

    /**a listener is required and the object must have a method named requestCompleted that accepts an MbHttpRequest object as a parameter*/
    this.registerListener =  function(listener)
    {
        this.listener = listener;
    }

    /**called by the factory when the status for this object is complete */
    this.complete = function()
    {
        this.status = this.httpRequest.status;
        if(this.status == 200)
        {
        	this.text = this.httpRequest.responseText;
            this.xml = this.httpRequest.responseXML;
            if(this.listener == null)
            {
            	alert('no listener assigned');
            }
            this.listener.requestCompleted(this);
        }
        else
        {
			if(!this.disableErrors){
				alert("Error reading data for " + this.requestName + " : " + this.status);
            }
        }
    }

    this.getXml = function() { return this.xml; }
    this.getText = function() { return this.text; }
}

/**the default status message*/
var statusMessage = new StatusMessage(document.getElementById('statusMessage'));
/**An easy way to display messages for each request.*/
function StatusMessage(messageElement)
{
	this.messageElement = messageElement;
    this.backgroundColor = 'rgb(195,47,47)';

    this.showMessage = function(message)
    {
	    //load every time since new elements may be created.
	     var messageElement = this.getMessageElement();
	
	    messageElement.style.display = "block";
	    messageElement.innerHTML = message;
    }

    this.hideMessage = function(delay)
    {
        if(delay != null)
        {
           var statusMessageId = this.getMessageElement().getAttribute('id');
           if(statusMessageId == null)
           {
               alert('status message needs an id attribute in order to hide');
           }
           
            //delay doesn't work with individual messages
            window.setTimeout("document.getElementById('" + statusMessageId + "').style.display='none'", delay);
        }
        else
        {
            var messageElement = this.getMessageElement();
            messageElement.style.display="none";
        }
    }

    this.getMessageElement = function()
    {
        return this.messageElement;
    }
    
}

//======================= OLD SCHOOL STATIC METHODS =====================

      function appendDocumentTo(sourceDoc, targetElement)
      {
          alert(sourceDoc);
      }
          
      function appendElementTo(sourceElement, targetElement)
      {
          targetElement.appendChild(sourceElement);
      }
      function transformIntoElement(xml,xsl,targetElement)
      {
             var resultOfTransformation;
             
            if (window.ActiveXObject) 
            {
                   resultOfTransformation = new ActiveXObject("Microsoft.XMLDOM");
                   resultOfTransformation.async = false;
                   if (xml && xsl && targetElement)
	                   targetElement.innerHTML =  xml.transformNode(xsl);
           }      
            else
            {
        		var processor = new XSLTProcessor();
        		 processor.importStylesheet(xsl);
        		 resultOfTransformation = processor.transformToDocument(xml);
        		 targetElement.removeChild(targetElement.firstChild);
        		 targetElement.appendChild(resultOfTransformation.documentElement);
            }
		 
      }
      


function loadXml(url)
{
    return loadXmlDoc(url).responseXML;
}



function loadXmlDoc(url,asynch,onReadyMethod,targetObject) 
{

    if(asynch == null)
    {
        asynch = false;
    }
    if(onReadyMethod == null)
    {
        onReadyMethod = processReqChange;
    }
    else
    {
      //  alert(onReadyMethod);
    }

    var req;
    // branch for native XMLHttpRequest object
    if (window.XMLHttpRequest) 
    {
        req = new XMLHttpRequest();
if(targetObject != null)
{
    GEvent.bind(req, "onreadystatechange",  targetObject, onReadyMethod);
//alert('binding object');
}
else
{
        req.onreadystatechange = onReadyMethod;
//alert(onReadyMethod);
}

        req.open("GET", url, asynch);
        req.send(null);
    // branch for IE/Windows ActiveX version
    } 
    else if (window.ActiveXObject) 
    {
        req = new ActiveXObject("Microsoft.XMLHTTP");
        if (req) 
        {
            req.onreadystatechange = onReadyMethod;
//alert("IE " + aysynch);
            req.open("GET", url, asynch);
            req.send();
        }
    }
    
    if (req.readyState == 4) {
        // only if "OK"
        if (req.status == 200) {
            // ...processing statements go here...
        
        } else {
            alert("There was a problem retrieving the XML data:\n" +
               req.status + ": " + req.statusText);
        }
    }
    return req;
}


function processReqChange() {

    // only if req shows "loaded"
    /*
    if (req.readyState == 4) {
        // only if "OK"
        if (req.status == 200) {
            // ...processing statements go here...
        } else {
            alert("There was a problem retrieving the XML data:\n" +
                req.statusText);
        }
    }
    */
}
