/**
 * @author Henry
 */

/**
 * Create an xml http request.
 */
function createXMLHttpRequest() {
	var xmlHttp = null;
	
	if (window.XMLHttpRequest) { // in mozilla / firefox / IE7.0
		xmlHttp = new XMLHttpRequest();
	} else if (window.ActiveXObject) { // in IE
		try {
			xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
		} catch (e) {
			try {
				xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
			} catch (e) {
				try {
					xmlHttp = new ActiveXObject("Msxml2.XMLHTTP.3.0"); //3.0或4.0, 5.0
				} catch (e) {
				//do nothing
				}
			}
		}
	}
	
	return xmlHttp;
}

function createXMLHttpRequest1() {
    var xmlHttp = null;
	
    var progIDs = ["Msxml2.XMLHTTP", "Microsoft.XMLHTTP"];
    for (var i = 0; i < progIDs.length; i++) {
        try {
			// in IE
            xmlHttp = new ActiveXObject(progIDs[i]); 
			break;
        }
        catch (e) {
			//do nothing
		}
    }
	
    if (typeof(XMLHttpRequest) != 'undefined') {
        try {
			// in mozilla & firefox
            xmlHttp = new XMLHttpRequest(); 
        }
        catch (e){
			//do nothing
		}
    }
	
    return xmlHttp;
}

/**
 * Do an synchronous http request.
 * @param {Object} url
 * @param {Object} data
 * @return response text.
 */
function doSyncHttpRequest(url, data) {
	return doHttpRequest(url, data, null, false);;
}

/**
 * Do an synchronous http request and receive and xml response.
 * @param {Object} url
 * @param {Object} data
 * @return response xml.
 */
function doSyncHttpXMLRequest(url, data) {
	return doHttpRequest(url, data, null, true);;
}

/**
 * Do an asynchronous http request.
 * @param {Object} url
 * @param {Object} data
 * @param {Object} callback a function to invoke after do request. e.g: function callback(result)
 * @return response text.
 */
function doAsyncHttpRequest(url, data, callback) {
	return doHttpRequest(url, data, callback, false);
}

/**
 * Do an synchronous http request and receive and xml response.
 * @param {Object} url
 * @param {Object} data
 * @param {Object} callback a function to invoke after do request. e.g: function callback(result)
 * @return response xml.
 */
function doAsyncHttpXMLRequest(url, data, callback) {
	return doHttpRequest(url, data, callback, true);
}

/**
 * Do an http request. The request can be synchronous or asynchronous according to
 * the callback parameter.
 * @param {Object} url url of the server.
 * @param {Object} data data to send to the server.
 * @param {Object} callback a function to invoke after do request. e.g: function callback(result)
 * @param {Object} isXMLResponse if true, will receive the response as xml.
 * @return in sychronous mode, return the response. in asynchronous mode, return true of false.
 */
function doHttpRequest(url, data, callback, isXMLResponse) {
	
    var xmlHttp = new createXMLHttpRequest();
	
    //var async = typeof(callback) == "function";
	var async = callback != null;
    if (async)
    {
        xmlHttp.onreadystatechange = doCallback;
    }
	
    xmlHttp.open("POST", url, async);
	
	//if (xmlHttp.overrideMimeType) {
	//	// set response header to avoid encoding problem
	//	xmlHttp.overrideMimeType('text/xml');
	//	xmlhttp.overrideMimeType("text/html;charset=gb2312");
	//}
	
	// must do send data even data is null
    xmlHttp.send(data);

    if (!async)
		return getResponse();
	else
	  return true;
	
	// ----- Sub function
	function getResponse() {
        if (xmlHttp.status != 200) {
            return null;
        }
		
		if (isXMLResponse) 
	        return xmlHttp.responseXML;
		else
	        return xmlHttp.responseText;
	}

    function doCallback() {
        if (xmlHttp.readyState == 4) {
	        try {
	            // Invoke the javascript callback method
		    	callback(getResponse());
	        } catch (e) {
				// do nothing
			} finally {
		        // Release the XMLHttpRequest object here to avoid memory leak
		        xmlHttp = null;
			}
		}
    }
	// ----- end
}