var xmlhttp_enableDebug = false;

function xmlhttp2_createBoundedWrapper(object, method) {
  return function() {
    return method.apply(object, arguments);
  };
}


/**
 *	Luo uuden requestin
 *
 *	@param	href				osoite mihin lähetetään (ainoa pakollinen parametri)
 *	@param	postData		post/get -data objectina. esim. {'action':'testi', 'testi-action':'uufoof', ..}
 *	@param	method			requestin method, joko post tai get, default post
 *	@param	callback		funktio, jota kutsutaan sen jälkeen kun request on valmis ja vastaus on tullut tai null jos ei haluta callbackiä
 *	@param	requireJSON	true/false tuleeko response JSON-muodossa. jos tulee, ja response ei evaluoidu, lätkästään ruudulle virhe (?). default=true
 *
 *	@return	request			palauttaa objectin jossa on edelliset parametrit, seka lisäksi:
 *	                    httprequest:	httprequest-objekti
 *	                    postData: data urlencoodattuna
 *	                    send:	send-metodi, joka lähettää requestin palvelimelle
 *
 *	                    voi myös palauttaa null, jos httprequest-objektin luonti epäonnistui
 *
 *	kun olet siis ensin luonut requestin, lähetä se send-metodilla:
 *	request.send();
 *
 *	send()-metodille voi antaa parametrina postDatan objektina.
 *
 *	kun request on lähetetty, ja siihen tullee vastaus joskus:
 *
 *	callback-funktio saa parametrina request-objectin, missä:
 *		request.xmlhttprequest = itse httprequest {readyState, responseText, responseXML, status, ..}
 *		ja jos requireJSON on päälle, tulee myös seuraava:
 *		request.response = palvelimelta tullut JSON muotoinen vastaus tulkattuna takaisin objektiksi
 *
 *	seuraavat tapahtuvat siis vain jos requireJSON on päällä:
 *
 *	request.response voi sisältää hashin request.response.html, jolloin se käsitellään automaattisesti. alla esimerkki:
 *		request.response.html['hinta_kpl'] = {'code':'<span>12.50 &euro;</span>'}
 *		request.response.html['hinta_kg'] = {'code':'<span>50.00 &euro;</span>'}
 *		request.response.html['koodiblokki3'] = {'base64':1, 'code':'635JH7GJH5G67J3H56G7JKH35677HJ365G'}
 *		request.response.html['koodiblokki4'] = {'base64':1, 'code':'YJ36Y2Ö4L6JY2ÖL4KJ6Y24224LJ5YTL4635JH7GJH5G67J3H56G7JKH35677HJ365G'}
 *		request.response.html['title'] = {'element':'tuotenimi', 'code':'Jääkaappi'}
 *
 *		eli:
 *		jos yhdessä itemissä on vain code, ei sille tehdä mitään, ja jatkokäsittely jää callbackin vastuulle.
 *		jos base64 on asetettu, decoodataan code automaattisesti base64 decodella.
 *		jos element on asetettu, laitetaan code (decoodattuna) suoraan kyseisellä id:llä löytyvän elementin innerHTML:ksi
 *
 *		näin palvelin voi siis kontrolloida responsella suoraan mitä muutetaan sivulla, eikä callback-funktiota välttämättä tarvita,
 *		jos kyseessä on vain simppeleja sisältövaihdoksia tiettyihin elementteihin
 */
function xmlhttp_request() {
	if(arguments.length < 1) {
		debugPrint("xmlhttp_request() - no arguments", "xmlhttp");
		return null;
	}

	var request = {'method':'POST', 'postData':null, 'method':'post', 'callback':null, 'requireJSON':true};
	request.href = arguments[0];
	if(arguments[1]) request.postData = arguments[1];
	if(arguments[2]) request.method = arguments[2];
	if(arguments[3]) request.callback = arguments[3];
	if(arguments[4] != undefined) request.requireJSON = arguments[4];
	request.method = request.method.toUpperCase()

	debugPrint("xmlhttp_request("+request.href+","+request.method+")", "xmlhttp");

	request.send = function() {
		if(arguments[0]) request.postData = arguments[0];
		var urlEncoded = "";
		if(request.postData) for(var i in request.postData) urlEncoded += "&" + encodeURIComponent(i)+"="+encodeURIComponent(request.postData[i]);
		urlEncoded = urlEncoded.replace(/^&/,"");
		request.xmlhttprequest = null;	// we simply overwrite the old xmlhttprequest
		request.xmlhttprequest = xmlhttp_create();
		if(request.xmlhttprequest) {
			request.xmlhttprequest.open(request.method, request.href, true);
			request.xmlhttprequest.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT");
			request.xmlhttprequest.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
			request.xmlhttprequest.onreadystatechange = xmlhttp2_createBoundedWrapper(request, xmlhttp_readyStateChange);
			request.xmlhttprequest.send(urlEncoded);
		} else {
			debugPrint("Failed to create xmlhttprequest", "xmlhttp");
		}
	}

	return request;
}

function xmlhttp_readyStateChange() {
	var rep = "";
	rep = "readyState="+this.xmlhttprequest.readyState;
	if(this.xmlhttprequest.readyState==4) {
		if(this.xmlhttprequest.status) {
			rep += " status="+this.xmlhttprequest.status;
			if(this.xmlhttprequest.status == 200) {
				if(this.xmlhttprequest.responseText) {
					this.responseText = this.xmlhttprequest.responseText;	// makes life easier
					if(this.requireJSON) {
						try {
							eval("this.response = " + this.xmlhttprequest.responseText);
						} catch(err) {
							showProps(err);
						}
						if(this.response) {
							if(this.response.errors) {
								var errorReport = "";
								for(var i in this.response.errors) {
									errorReport += this.response.errors[i]+"\n\n";
								}
								alert(errorReport);
							}
							if(this.response.messages) {
								var messageReport = "";
								for(var i in this.response.messages) {
									messageReport += this.response.messages[i]+"\n\n";
								}
								alert(messageReport);
							}
							if(this.response.html) {
								for(var i in this.response.html) {
									if(this.response.html[i].base64) this.response.html[i].code = Base64.decode(this.response.html[i].code);
									if(this.response.html[i].element) {
										var el = document.getElementById(this.response.html[i].element);
										if(el) el.innerHTML = this.response.html[i].code;
									}
								}
							}
						}
					}
				} else {
					rep += " no responseText";
				}
				this.callback(this);
			}
		}
	}
	debugPrint("xmlhttp_readyStateChange: "+rep, "xmlhttp");
}


/**
 * Luo uuden XMLHttpRequest-objektin. (Ensisijaisesti käyttää native objektia, muuten IE:n ActiveX versiota)
 *
 * @return Palauttaa objektin tai null jos epäonnistui.
 */
function xmlhttp_create() {
	var xmlHttp = null;
	if (window.XMLHttpRequest) {
		// If IE7, Mozilla, Safari, and so on: Use native object
		xmlHttp = new XMLHttpRequest();
	} else {
		if (window.ActiveXObject) {
			// ...otherwise, use the ActiveX control for IE5.x and IE6
			try {
				xmlHttp = new ActiveXObject('MSXML2.XMLHTTP.3.0');
			} catch (E) {
				xmlHttp = null;
			}
		}
	}
	return xmlHttp;
}
