// we use a javascript feature here called "inner functions"
// using these means the local variables retain their values after the outer function
// has returned. this is useful for thread safety, so
// reassigning the onreadystatechange function doesn't stomp over earlier requests.
// methodology invented/used from brockweaver on xml.com http://www.xml.com/cs/user/view/cs_msg/2815

function HttpRequest(url, callback, async) {
	// this function is a 'universal callback'
	// that allows us to store several requests
	// at once without losing callbacks
	function GetCallback()
	{
		 if (http_request.readyState == 4) {
	        if (http_request.status == 200) {
	            http_callback(http_request);
	        } else {
	            alert('There was a problem with the HTTP request. (HTTP Error ' + http_request.status + ' ' + http_request.statusText + ')');
	            return false;
	        }
	    }
	}
	
	// validate parameters
	if( typeof( async ) == 'undefined' ) {
		async = true;
	}
	
	if( typeof( callback ) != 'function' && async ) {
		alert( "No callback defined. A callback must be defined for async requests." );
		return false;
	}

	// these can have multiple copies over function calls
	// thus isolating them from event handler overwritings
    var http_request = false;
    var http_callback = callback;
	
	
	// create the httprequest object
    if (window.XMLHttpRequest) { // Mozilla, Safari,...
        http_request = new XMLHttpRequest();
        if (http_request.overrideMimeType) {
            http_request.overrideMimeType('text/xml');
        }
    } else if (window.ActiveXObject) { // IE
        try {
            http_request = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (e) {
            try {
                http_request = new ActiveXObject("Microsoft.XMLHTTP");
            } catch (e) {}
        }
    }

    if (!http_request) {
        alert('Your browser does not support HTTP requests.');
        return false;
    }
    
    if( async ) {
    	http_request.onreadystatechange = GetCallback;
    }
    http_request.open('GET', url, async);
    http_request.send(null);
    
    // for non-async requests, we just return the request object when we're done
    if( !async ) {
    	if (http_request.readyState == 4) {
	        if (http_request.status == 200) {
	            return http_request;
	        } else {
	            alert('There was a problem with the request. (HTTP Error ' + http_request.status + ' ' + http_request.statusText + ')');
	            return false;
	        }
   		}
    }
}