
function XMLHTTP(server_url, readyStateFunction)
{
	this.server_url = server_url; 		// the SERVER page URL to connect to IE ajax_server.php
	this.async = true;					// whether we're in syncronous mode or async (default)
	this.debug=0;						// debug turned off by default, to see your request/response do ajaxObj.debug=1
	this.method = "POST";				// by default all requests are sent via POST to override just use ajaxObj.method="GET"; before your call
	this.req = null;					// the xmlhttprequest variable, starts off as null
	this.errors = new Array();			// array of errors generated
	this.headers = new Array();			// array of optional headers you may pass in
	this.callBack = '';					// the callback function, when the ajax request is sent, this is the function that will be called
	this.format = "JSON";				// by default JSON encoding is the expected format, to override: ajaxObj.format = "XML"; or ajaxObj.format="TEXT";
	this.readyStateFunction = (readyStateFunction) ? readyStateFunction : this.responseHandler;
}

/**
* Method to create an XMLHTTP object
*@access private
*/
XMLHTTP.prototype.getXMLHTTP = function()
{
	// moz XMLHTTPRequest object
	if (window.XMLHttpRequest) {
		this.req = new XMLHttpRequest();
	}
	// IE/Windows ActiveX version
	else if (window.ActiveXObject){
		this.req = new ActiveXObject("Microsoft.XMLHTTP");
	} else {
		if(this.debug == 1) {
			this.showDebug("<BR>FATAL ERROR: Could not create XMLHTTPRequest Object!<BR>");	
		}
	}
	return this.req;
}

/**
* Main API method to use for AJAX requests
* example: ajaxObj.call("id=1", myCallBackFunction, "GET"); // GET REQUEST
* example: ajaxObj.call(("id=1", myCallBackFunction); 		// POST REQUEST
*@access public
*@param string A url encoded string of data to send to the server
*@param string A callback function that the server will launch when the response is generated
*/
XMLHTTP.prototype.call = function(queryVars, userCallback)
{
	this.fullUrl = '';
	
	// get XMLHTTPRequest Object
	this.getXMLHTTP();
	
	this.callBack = userCallback;
	
	// set response handler, if none is set, use our default one
	this.req.onreadystatechange =  this.readyStateFunction;

	// check for JSON encoding
	if(this.format != 'JSON') {
		queryVars = queryVars+'&json=false';
	}
		
	// if get is used, append the query variables to the url string 
	this.full_url = (this.method == "POST") ? this.server_url : this.server_url + '?'+ queryVars;
	
	if(this.debug == 1) {
		this.showDebug("<BR>Current State:<BR>Server Page: "+this.server_url+"<BR>HTTP Method: "+this.method+"<BR>Encoding Format: "+this.format+"<BR>Query String: "+queryVars+"<BR>");
	}
	
	// open connection
	this.req.open(this.method, this.full_url, this.async);
	
	// set any optional headers
	if(this.headers)
	{
		for(var i in this.headers)
		{
			if(i != '') {
				this.req.setRequestHeader( i, this.headers[i]);
			}
		}
	}
    
	// send request
    if(this.method == 'POST') {
		this.req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
		this.request = queryVars;
		this.req.send(queryVars);
	} else {
		this.req.send(null);
	}
	
}

/**
* Default method for parsing the response from the server. It will try to eval the obj.method_to_call property and pass the native JS object
*/
XMLHTTP.prototype.responseHandler = function()
{
	// only if req shows "complete"
    if (ajaxObj.req.readyState == 4) {
        // only if "OK"
        if (ajaxObj.req.status == 200) {
			
			if(ajaxObj.req.responseText.indexOf('ajax_msg_failed') != -1) {
				ajaxObj.callBack(false);
				ajaxObj.showDebug("Fatal Error: mybic_server sent back ajax_msg_failed!<br/>");
			} else {
				if(ajaxObj.format == "JSON") {
				try {
	        	var myObject = eval( '(' + ajaxObj.req.responseText + ')' );
				
				// callback function we passed to the server to process the results
	        	ajaxObj.callBack(myObject);
				} catch(e) {
						ajaxObj.errors["An error occured while trying to post your request"];
						alert('an error occurred in your response function, not mybic related');
						ajaxObj.callBack(false);
				}
				} else if(ajaxObj.format == "XML") {
					// send the raw xml data to the callback function
					ajaxObj.callBack(ajaxObj.req.responseXML);	
				} else {
					
					ajaxObj.callBack(ajaxObj.req.responseText);
				}
			}

        }
		if(ajaxObj.debug == 1) {
				// STRIP HTML
				var str = ajaxObj.req.responseText.replace(/(\<)/gi, '&lt;');
				var str = str.replace(/(\>)/gi, '&gt;');
				ajaxObj.showDebug("<br/><b>HTTPResponse:</b><br/> "+str+"<br/>");
			}
		// reset the method, format, etc back to class defaults
		ajaxObj.restoreDefaults();
    }
}

/**
* Method called after callback function is called to return the class to a default state
*/
XMLHTTP.prototype.restoreDefaults = function()
{
	this.method = "POST";
	this.format = "JSON";	
	this.callback = "";
	
}

/**
* This method will allow you to get all your form fields in ONE magical step!
* right before your ajaxObj.call statement all you have to do is: var form_vars = ajaxObj.getForm('formid');
* that will loop through the form id you pass, and put all the form variables into your query string!
*@param string The ID of the form you wish to submit
*@return string An encoded query string, ready to send to the server
*/

XMLHTTP.prototype.getForm = function(formid)
{
	var mybic_q_string = '';
	var u_form = document.getElementById(formid);
	/*--- TEXT INPUTS ----*/
	
	var inputs = u_form.getElementsByTagName('input');
	var inp_len = inputs.length;
	for(var i=0; i<inp_len; i++) {
		
		if((inputs[i].type == 'checkbox' || inputs[i].type == 'radio') && inputs[i].checked) {
			mybic_q_string += '&'+encodeURIComponent(inputs[i].name)+'='+encodeURIComponent(inputs[i].value);
			
		}
		if(inputs[i].type == 'text' || inputs[i].type == 'hidden') {
			mybic_q_string += '&'+encodeURIComponent(inputs[i].name)+'='+encodeURIComponent(inputs[i].value);
		}
	}
	
	/*--- SELECT INPUTS ----*/
	
	var selects = u_form.getElementsByTagName('select');
	var selects_len = selects.length;
	for(var j=0; j<selects_len; j++) {
		if(selects[j].type == 'select-one') {
			mybic_q_string += '&'+encodeURIComponent(selects[j].name)+'='+encodeURIComponent(selects[j].options[selects[j].selectedIndex].value);
		}
		if(selects[j].type == 'select-multiple') {
			nod_len = selects[j].childNodes.length;
			for(var p=0; p<nod_len;p++) {
		
						if (selects[j].childNodes[p].selected) {
						
							var node = selects[j].childNodes[p];
							if(node.value == '') {
								var sel = node.text;
							} else {
								var sel = node.value;
							}
						
							mybic_q_string += '&'+encodeURIComponent(selects[j].name)+'='+encodeURIComponent(sel);
						} 
					}
			}
		}
		
		/*--- TEXT AREAS ----*/
		var textareas = u_form.getElementsByTagName('textarea');
		var tex_len  = textareas.length;
		for(var t=0; t<tex_len; t++) {
			if(textareas[t].type == 'textarea') {
				mybic_q_string += '&'+encodeURIComponent(textareas[t].name)+'='+encodeURIComponent(textareas[t].value);
			}
		}
		
		/*--- PASSWORDS ----*/
		var pass = u_form.getElementsByTagName('password');
		var pass_len  = pass.length;
		for(var k=0; k<pass_len; k++) {
			if(pass[t].type == 'password') {
				mybic_q_string += '&'+encodeURIComponent(pass[k].name)+'='+encodeURIComponent(pass[k].value);
			}
		}
		//document.getElementById('qstring').innerHTML += "<BR>name: "+selects[i].name+" value: "+selects[i].value;		
		return mybic_q_string;
}


/**
* This method will print debug information to a div with an id of "mybic"
* It will help you debug your ajax application
*/
XMLHTTP.prototype.showDebug = function(msg)
{
	if(document.getElementById('mybic_debug')) {
		document.getElementById('mybic_errs').innerHTML += msg;
	} else {
		// create element
		var deb = document.createElement('div');
		deb.id = 'mybic_debug';
		deb.style.border = "thin solid black";
		deb.style.backgroundColor = "#F9F0AE";
		deb.style.padding = "10px";
		deb.style.position='absolute';
		deb.style.top = 0;
		deb.style.left=0;
		deb.style.width="500px";
		
		deb.style.overflow="auto";
		deb.innerHTML += '<a href="#" onclick="document.getElementById(\'mybic_errs\').style.display = (document.getElementById(\'mybic_errs\').style.display==\'none\') ? \'\':\'none\';" >hide/show me!</a>';
		deb.innerHTML += '&nbsp;&nbsp;&nbsp;&nbsp;<a href="#" onclick="document.getElementById(\'mybic_errs\').innerHTML = \'\'; return false;">Clear</a>';
		deb.innerHTML += '&nbsp;&nbsp;&nbsp;&nbsp;<a href="#" onclick="document.getElementById(\'mybic_debug\').style.left = (parseInt(document.getElementById(\'mybic_debug\').style.left)+100)+\'px\';">Move Left</a>';
		deb.innerHTML += '&nbsp;&nbsp;&nbsp;&nbsp;<a href="#" onclick="document.getElementById(\'mybic_debug\').style.top = (parseInt(document.getElementById(\'mybic_debug\').style.top)+100)+\'px\';">Move Down</a>';
		
		var errs = document.createElement('div');
		errs.id = "mybic_errs";
		errs.innerHTML += msg;
		deb.appendChild(errs);
		if(document.body) {
			document.body.appendChild(deb);
		} else {
			document.lastChild.appendChild(deb);
		}
		
	}
}


