/* Constructor */
var gHTTPTransactions = new Object;
var gTransID = 0;

function HTTPTransaction() {
	this.transID = gTransID++;
	this.httpRequest = null;
	this.nTrials = 0;
	this.bGetHack = false;
}

function ICQHTTPRequest(oOwner, sMethod) {
	this.owner = oOwner;
	if (undefined == sMethod)
		sMethod = "onHTTPDataReady";
	this.callback = sMethod;
}

ICQHTTPRequest.prototype.addTransaction = function(transID, transaction) {
	gHTTPTransactions[transID] = transaction;
}

ICQHTTPRequest.prototype.findTransactionByID = function(transID) {
	return gHTTPTransactions[transID];
}

ICQHTTPRequest.prototype.removeTransaction = function(transID) {
 	delete gHTTPTransactions[transID];
}


ICQHTTPRequest.prototype.send = function(sURL, sData, sCookie, sMethod, bAsync) {
	XtrazDebug.assert(sURL.length > 0, "httprequest send: bad url");
	if (arguments.length < 5)
		bAsync = true;
	if (arguments.length < 4)
		sMethod = "POST";
	if (arguments.length < 2)
		sData = "";
	XtrazDebug.alert("icqhttprequest accessing", sURL, "with data", XMLEncoder.encode(sData), "method", sMethod);
	
	var transaction = new HTTPTransaction();
	transaction.cookie = sCookie;
	transaction.sMethod = sMethod;
	transaction.sURL = sURL;
	transaction.bAsync = bAsync;
	transaction.sData = sData;
	
	var req = makeXMLRequest();
	XtrazDebug.assert(req, "could not create http request")
	transaction.httpRequest = req;
	var f = function() {
		arguments.callee.owner.onRequestData(arguments.callee.transID);
	}
	f.owner = this;
	f.transID = transaction.transID;
	req.onreadystatechange = f;
	
	
	this.addTransaction(transaction.transID, transaction);
	this.sendTransaction(transaction);
}

ICQHTTPRequest.prototype.sendTransaction = function(transaction) {
	var req = transaction.httpRequest;
	transaction.nTrials++;
	var bError = false;
	try {
		XtrazDebug.alert("icqhttprequest: trying to open", transaction.sURL, "method", transaction.sMethod);
		req.open(transaction.sMethod, transaction.sURL, transaction.bAsync);
	}
	catch (e) {
		bError = true;
		XtrazDebug.alert("icqhttprequest: error opening", e);
	}
	if (! bError) {
		try {
			req.send(transaction.sData);
		}
		catch (e) {
			bError = true;
			XtrazDebug.alert("icqhttprequest: error sending", e);
		}
	}
	if (bError) {
		this.owner[this.callback]('', null, -1, transaction.cookie);
	}
}

ICQHTTPRequest.prototype.onRequestData = function(transID) {
	var transaction = this.findTransactionByID(transID);
	XtrazDebug.assert(transaction, "on request data: no transaction", transID);
//	if (! transaction)
//		 return;
 
	var request = transaction.httpRequest;
	
	var state = request.readyState;
	XtrazDebug.alert("onRequestData found transaction for transID ", transID, "state", state);
//	var str = "onLoginRequestData, transaction " + transID + ", state is " + state;
	
	if (state == 4) {
		 request.onreadystatechange = ICQHTTPRequest.dummy;
		var bCallback = true;
		if (request.status != 200) {
			if (transaction.nTrials == 1 && transaction.sMethod == "POST") {
				XtrazDebug.alert("http request trying get hack");
				transaction.sMethod = "GET";
				transaction.bGetHack = true;				
				this.sendTransaction(transaction);
			}
//			XtrazDebug.alert("http request statustext", request.statusText); 
		}
		else { // request was successful
			if (transaction.bGetHack) { // the get call was just a hack
				transaction.sMethod = "POST";
				transaction.bGetHack = false; // rest to normal
				this.sendTransaction(transaction);
			}
			else {
				this.removeTransaction(transID);
				XtrazDebug.trace("calling callback", this.callback, typeof(this.owner), typeof(this.owner[this.callback]));
				this.owner[this.callback](request.responseText, request.responseXML, request.status, transaction.cookie);
			}
		}
	}
}

ICQHTTPRequest.dummy = function(){}
/*static */
function makeXMLRequest() {
	var xmlhttp;
	try {
//		XtrazDebug.alert("trying msxml");
		xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
	} catch (e) {
		XtrazDebug.alert("caught error in Msxml2.XMLHTTP");
	}
	if (! xmlhttp) {
		XtrazDebug.alert("trying microsoft");
		try {
			xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
		} catch ( e ) {
			XtrazDebug.alert("caught error in Microsoft.XMLHTTP");
		}
	}
	if (! xmlhttp) {
		XtrazDebug.alert("trying xmlhttp");
		try {
		  xmlhttp = new XMLHttpRequest();
		}
		catch (e) {
			XtrazDebug.alert("caught error in XMLHttpRequest");
		}
	}
//	XtrazDebug.alert("returning " + typeof(xmlhttp));
	return xmlhttp;
}
