function remote(){
	this.READY_STATE_UNINITIALIZED	= 0;
	this.READY_STATE_LOADING	= 1;
	this.READY_STATE_LOADED	= 2;
	this.READY_STATE_INTERACTIVE = 3;
	this.READY_STATE_COMPLETE	= 4;
	this.xmlHttp;
	
	/**
	 * createConnector
	 * create the agent for contacting the server, 
	 * in this case Instantiation of xmlhttp object
	 */
	this.createConnector	= _createConnector;
	function _createConnector(){
		if (window.ActiveXObject){
	    this.xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
	  }
	  else if (window.XMLHttpRequest){
	    this.xmlHttp = new XMLHttpRequest();
	  }
	}
	
	/**
	 * sendRequest
	 * Main method for sending request to the server synchronously or asynchronously
	 * @param string method
	 * @param string strUrl
	 * @param boolean asynch (true for asynchronous)
	 * @param string param --> in the format of (name1=value1&...&namen=valuen)
	 * @param mixed stateChangeHandler --> for handling state change
	 */
	this.sendRequest	= _sendRequest;
	function _sendRequest(method, strUrl, asynch, param, stateChangeHandler){
		this.createConnector();
	  if (stateChangeHandler){
	    this.xmlHttp.onreadystatechange  = typeof stateChangeHandler == 'string' ?
	    	eval(stateChangeHandler) : stateChangeHandler;
	  }
	  else
	    this.xmlHttp.onreadystatechange  = handleStateChange;
	  
	  this.xmlHttp.open(method, strUrl, asynch);
	  
	  if (method.toLowerCase() == 'post'){
	  	this.xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-url-encoded");
	  	this.xmlHttp.setRequestHeader("Content-length", param.length);
	  	this.xmlHttp.setRequestHeader("Connection", "close");
	  }
	  
	  this.xmlHttp.send(param);
	}
	
	/**
	 * cancel
	 * abort the current running request
	 */
	this.cancel	= _cancel;
	function _cancel(){
		this.xmlHttp.abort();
	}
	
	/**
	 * createQueryString
	 * create string that holds value of name1=value1&..&namen=valuen
	 * @param object param
	 * @return string queryString
	 * @ex: 
	 * 	var qs	= {'name' : 'abdul', 'age' : 17}; alert (createQueryString(qs));
	 * 	will prompt the result name=abdul&age=17
	 */
	this.createQueryString	= _createQueryString;
	function _createQueryString(param){
		var queryString	= '';
		
		var counter	= 0;
		
		var length	= associativeArrayLength(param);
		
		for (var key in param){
			if (counter > 0 && counter != length)
				queryString	+= '&';
			
			queryString	+= key + '=' + param[key];
			
			counter++;
		}
		
		return queryString;
	}
}

/**
 * associativeArrayLength
 * count the length of Object Literal (Object Notation)
 * @param object param
 * @return string counter
 */
function associativeArrayLength(param){
	var counter	= 0;
	
	for (var key in param) 
		counter++;
		
	return counter;
}
