//Constants for HTTP Method
var HTTP_GET = 1;
var HTTP_POST = 2;

// object constructor
function AjaxRequest(statusElementId)
{
	this.toString = function() { return "AjaxRequest"; }
	
	// define object's private properties
	var statusElementId = statusElementId;
	var statusElement = false;
	
	// define object's properties
	this.readyStateMsg0 = "uninitialized...";
	this.readyStateMsg1 = "loading...";
	this.readyStateMsg2 = "loaded...";
	this.readyStateMsg3 = "interactive...";
	this.readyStateMsg4 = "complete";
	
	this.request = getNewRequestObject();
	if (this.request == false) {
		return null;
	}
	this.theURL = false;
	this.callbackMethod = false;
		
	// attach object's API methods
	this.get = function (url, callback) {
		this.process(HTTP_GET, url, callback)
	};
	this.post = function (url, submitData, callback) {
		this.process(HTTP_POST, url, callback, submitData)
	}

	// attach object's support methods
	
	//http://www.onlamp.com/lpt/a/5841
	this.process = function (httpMethod, strURL, callback, submitData) {
		var oThis = this;
		this.theURL = strURL;
		this.callbackMethod = callback;
		var httpMethodStr
		if(this.request) {
			//if (httpMethod == HTTP_GET) httpMethodStr = "GET" else httpMethodStr = "POST"
			httpMethodStr = (httpMethod == HTTP_GET) ? "GET" : "POST";
			this.request.open(httpMethodStr, strURL, true);	//Always asychronous
			//this.request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
			//this.request.setRequestHeader("Content-Type", "text/xml");
			this.request.onreadystatechange = function() {
				switch (oThis.request.readyState) {
					case 0:
						oThis.displayStatus(oThis.readyStateMsg0);
						break;
					case 1:
						oThis.displayStatus(oThis.readyStateMsg1);
						break;
					case 2:
						oThis.displayStatus(oThis.readyStateMsg2);
						break;
					case 3:
						oThis.displayStatus(oThis.readyStateMsg3);
						break;
					case 4:
						oThis.displayStatus(oThis.readyStateMsg4);
						var strResponse = oThis.request.responseText;
						//alert("DEBUG: headers: " + oThis.request.getAllResponseHeaders());
						//alert("DEBUG: strResponse: "+ strResponse );
						switch (oThis.request.status) {
						  case 0:	// for local gets, Note: undefined in Safari.
						  case 200: //"OK"
							//alert("DEBUG: responseXML: "+ oThis.request.responseXML);
							//alert("DEBUG: Parse Error?: " + oThis.request.responseXML.parseError);
							// Call the desired result function
							eval(oThis.callbackMethod + "(oThis.request.responseXML, strResponse);");
							oThis.displayStatus("");
							break;
						  case 404: // Page-not-found error
							oThis.displayStatus('404 Error: Not Found. The requested URL ' + 
								   oThis.theURL + ' could not be found.');
							break;
						  case 500:
							// Display results in a full window for server-side errors
							handleErrFullPage(strResponse);
							break;
						  default:
							// Call JS alert for custom error or debug messages
							if (strResponse.indexOf('Error:') > -1 || 
								   strResponse.indexOf('Debug:') > -1) {
								   oThis.displayStatus(strResponse);
							} else {
							  oThis.displayStatus("There was a problem with the request:\n" +
									oThis.request.status + ": " + oThis.request.statusText);
							}
							break;
						} //end status switch
						break;
				} //end readyState switch
			}; //end function
	
			if (httpMethod = HTTP_GET) {
				this.request.send(null);
			} else {
				this.request.send(submitData);
			}
		}
	};

	this.displayStatus = function(msg) {
		if (statusElement == false && statusElementId) {
			statusElement = document.getElementById( statusElementId );
		}
		statusElement.innerHTML = msg;
	};

}

// internal methods
//http://developer.apple.com/internet/webcontent/xmlhttpreq.html
function getNewRequestObject() {
  var xmlHttpReq = false;
  // branch for native XMLHttpRequest object
  // Mozilla/Safari
  if(window.XMLHttpRequest) {
	//alert("DEBUG: getNewRequestObject using window.XMLHttpRequest");
    try {
      xmlHttpReq = new XMLHttpRequest();
      //xmlHttpReq.overrideMimeType("text/xml");   // boolean parameter??? //Does not work in IE7
    } catch(e) {
		//alert("DEBUG: getNewRequestObject could not instantiate XMLHttpRequest: "+ e);
	    xmlHttpReq = false;
    }
  // branch for IE/Windows ActiveX version
  } else if(window.ActiveXObject) {
	//alert("DEBUG: getNewRequestObject using window.ActiveXObject");
    try {
      xmlHttpReq = new ActiveXObject("Msxml2.XMLHTTP");
    } catch(e) {
      try {
        xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
      } catch(e) {
        xmlHttpReq = false;
      }
    }
  }
  return xmlHttpReq;
}

function handleErrFullPage(errDoc) {
  var errorWin;
  // Create new window and display error
  try {
    errorWin = window.open('', 'errorWin');
    errorWin.document.body.innerHTML = errDoc;
  }
  catch(e) {
    // If pop-up gets blocked, inform user
    alert('An error occurred, but the error message cannot be' +
            ' displayed because of your browser\'s pop-up blocker.\n' +
            'Please allow pop-ups from this Web site.');
  }
}

