function AjaxReq(fetchurl,recvobj) {
	this.clearParms();
	this.fetchUrl = fetchurl;
	this.state = 1;
	//1 = initializing, 2 = sending
	this.tryNumber = 0;
	this.recvObj = recvobj;
	this.retryTime = 3000;
	this.missingRetryTime = 30000;
	this.charset = "ISO-8859-1";
}

AjaxReq.prototype.clearParms = function() {
	this.getParms = new Object();
	this.postParms = new Object();
	return(0);
}

AjaxReq.prototype.addGet = function(key,val) {
	if(this.state != 1) return(1);
	this.getParms[key] = val;
	return(0);
}

AjaxReq.prototype.addPost = function(key,val) {
	if(this.state != 1) return(1);
	this.postParms[key] = escape(val.toString().replace(/\+/g,"%2b"));
	return(0);
}

AjaxReq.prototype.reqStr = function(parmHash) {
	var parmStr = new Array();
	for(p in parmHash) {
		parmStr[parmStr.length] = p+'='+parmHash[p];
	}//for
	return(parmStr.join("&"));
}

AjaxReq.prototype.send = function() {
	this.tryNumber++;
	this.prepareRequest();
    var postStr = this.reqStr(this.postParms);
    var getStr = "?" + this.reqStr(this.getParms);
    if(postStr.length) this.reqMethod = "POST";
    else this.reqMethod = "GET";
    this.httpReq.open(this.reqMethod,this.fetchUrl+getStr,true);
    if(postStr.length > 0) {
	    this.httpReq.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset="+this.charset);
	    this.httpReq.setRequestHeader("Accept-Charset",this.charset);
	    this.httpReq.setRequestHeader("Content-length",postStr.length);
    } else postStr = null;
    this.httpReq.onreadystatechange = this.httpReady.bind(this,this.tryNumber);
    this.httpReq.send(postStr);
    this.state = 2;
    return(0);
}

AjaxReq.prototype.retry = function() {
	return(this.send());
}

AjaxReq.prototype.abort = function() {
	this.state = 1;
	if(this.httpReq) {
		if(this.retryTimeoutId != undefined) {
			clearTimeout(this.retryTimeoutId);
			this.retryTimeoutId = null;
		}
		if(!isIE(6)) this.httpReq.abort();
		return(1);
	}
	return(0);
}

AjaxReq.prototype.prepareRequest = function() {
	if(!this.abort()) {
	    try {
	        this.httpReq = new XMLHttpRequest();
	        if(this.httpReq.overrideMimeType) {
		        this.httpReq.overrideMimeType('text/xml');
	        }
        } catch(e) {
	        this.httpReq = new ActiveXObject("MSXML2.XMLHTTP.3.0");
        }
	    return(0);
    }
    return(1);
}

AjaxReq.prototype.xml2hash = function(xml) {
    var hash = new Object();
    var empty = 1;
	if(xml.nodeType == 1) {
		for(var i = 0; i < xml.attributes.length; i++) {
			var node = xml.attributes[i].nodeName;
		    hash[node] = xml.getAttribute(node);
		    empty = 0;
		}
	    for(var i = 0; i < xml.childNodes.length; i++) if(xml.childNodes[i].tagName != undefined) {
	        cn = xml.childNodes[i];
		    hash[cn.tagName] = this.xml2hash(cn);
		    empty = 0;
	    }
	    if(empty && xml.childNodes[0] != undefined && xml.childNodes[0].data != undefined) {
		    hash = xml.childNodes[0].data;
	    }
    	return(hash);
    }
    return(undefined);
}

AjaxReq.prototype.httpReady = function(tryNumber) {
	if(this.tryNumber == tryNumber && this.state == 2 && this.httpReq.readyState == 4) {
		if(this.httpReq.responseXML && this.httpReq.status == 200) {
			if(this.recvObj.recvStart != undefined) this.recvObj.recvStart();
			var rootNodes = this.httpReq.responseXML.childNodes;
			for(var j = 0; j < rootNodes.length; j++) {
				if(rootNodes[j].nodeType == 1) {
					var mainNodes = rootNodes[j].childNodes;
					for(var i = 0; i < mainNodes.length; i++) {
						var mainNode = mainNodes[i];
						if(this.recvObj[mainNode.tagName] != undefined) this.recvObj[mainNode.tagName](this.xml2hash(mainNode),mainNode);
					}
			    }
			}
			this.state = 1;
			if(this.recvObj.recvEnd != undefined) this.recvObj.recvEnd();
		} else {
			var retryTime;
			if(this.httpReq.responseXML && this.httpReq.status == 404) retryTime = this.missingRetryTime;
			else retryTime = this.retryTime;
			this.retryTimeoutId = setTimeout(this.retry.bind(this),retryTime);
		}
	}
	return(0);
}
