//Define sub-objects in the Webclient object.
var WebClient={
	AsyncHTTP:Object,
	DOM:Object,
	GenFunc:Object
}

// Global configurationvariables.
var gsClassName = "WebPage.WebClient";
var gsErrors = "";
var gsBrowserType;

//Determine browsertype and store in global variable.
if (navigator.userAgent.indexOf("MSIE")>=0) {
	gsBrowserType = 'IE';
}
else if(navigator.userAgent.indexOf("Gecko")>=0) {
	gsBrowserType = 'MOZILLA';
}
else if(navigator.userAgent.indexOf("Opera")>=0) {
	gsBrowserType = 'OPERA';
}
else {
	gsBrowserType = 'MOZILLA';
}

// Functions to manage asynchronous http-requests.
WebClient.AsyncHTTP = function(asCalledFrom) {
	//ClassHeader
	var lsClassName = "AsyncHTTP";
	var lsCalledFrom;
	if(asCalledFrom != null) {lsCalledFrom = asCalledFrom;}else{lsCalledFrom = gsClassName;}
	var lsClassPath = lsCalledFrom + '.' + lsClassName;
	var loDOM = new WebClient.DOM(lsClassPath);
	var loGenFunc = new WebClient.GenFunc(lsClassPath);
	//End ClassHeader
	
	var aoHTTPXML;
		
	this.httpRequest = function(asURL, aoCallbackHandler) { // Performs a HttpGet-request on asURL and returns HTTPXML-object.
		if (gsBrowserType == 'IE') {
			try {
				aoHTTPXML = new ActiveXObject("Msxml2.XMLHTTP");
			} catch (e) {
				try {
					aoHTTPXML = new ActiveXObject("Microsoft.XMLHTTP");
				} catch (e) {}
			}
		}
		else {
			try {
				aoHTTPXML = new XMLHttpRequest();
			} catch (e) {}
		}
		if (!aoHTTPXML) {
			loGenFunc.handleError(lsClassPath,'httpRequest()','error','Cannot create XMLHTTP instance.');
		}
		aoHTTPXML.onreadystatechange = function() {
			if (aoHTTPXML.readyState == 4||aoHTTPXML.readyState=="complete") {
				if (aoHTTPXML.status != 200) {
					loGenFunc.handleError(lsClassPath,'httpRequest()','error',aoHTTPXML.status + ' http-status returned by URL: ' + asURL + '.');
			}
				aoCallbackHandler(aoHTTPXML);
		}
		}
		aoHTTPXML.open('GET', asURL, true);
		aoHTTPXML.send(null);
	}
}

// Functions to transform the client-document using the Document  Object Model.
WebClient.DOM = function(asCalledFrom) {
	//ClassHeader
	var lsClassName = "DOM";
	var lsCalledFrom;
	if(asCalledFrom != null) {lsCalledFrom = asCalledFrom;}else{lsCalledFrom = gsClassName;}
	var lsClassPath = lsCalledFrom + '.' + lsClassName;
	var loGenFunc = new WebClient.GenFunc(lsClassPath);
	//End ClassHeader
		
	this.detectBrowser = gsBrowserType;
	
	this.setFocus = function(asObjectID) { //Sets focus to asObjectID
		try {
			document.getElementById(asObjectID).focus();
		} catch (e) {
			loGenFunc.handleError(lsClassPath,'setFocus()','warning',e.description + ' (ElementID: ' + asObjectID + ')');
		}
	}
	
	this.hideElement = function(asObjectID) { //Hides an element
		try {
			document.getElementById(asObjectID).style.display="none";
		} catch (e) {
			loGenFunc.handleError(lsClassPath,'hideElement()','warning',e.description + ' (ElementID: ' + asObjectID + ')');
		}
	}
	
	this.unHideElement = function(asObjectID, asType) { //Unhides element
		var lsType = asType;
		if (!lsType) {lsType="block"}
		try {
			document.getElementById(asObjectID).style.display=lsType;
		} catch (e) {
			loGenFunc.handleError(lsClassPath,'unHideElement()','error',e.description + ' (ElementID: ' + asObjectID + ', Type: ' + lsType + ')');
		}
	}
	
	this.setInnerHTML = function(asObjectID, asNewHTML) { // Sets value asNewHTML as HTML-content in element asObjectID.
		try {
			var loElement = document.getElementById(asObjectID);
			loElement.innerHTML = asNewHTML;
		} catch (e) {
			loGenFunc.handleError(lsClassPath,'setInnerHTML()','error',e.description + ' (ElementID: ' + asObjectID + ', NewHTML: ' + asNewHTML + ')');
		}
		return false;
	}
	
	this.setInnerHTMLMulti = function(aarrObjectID, aoNewHTML) { // Sets value(s) asNewHTML as HTML-content in array aarrObjectID.
		var i,loElement,lsValue;
		var lbIsArray = loGenFunc.isArray(aoNewHTML);
		for (i=0;i<aarrObjectID.length;i++) {
			if (lbIsArray == true) {
				lsValue = aoNewHTML[i];
			}
			else {
				lsValue = aoNewHTML;
			}
			try {
				loElement = document.getElementById(aarrObjectID[i]);
				loElement.innerHTML = lsValue;
			} catch (e) {
				loGenFunc.handleError(lsClassPath,'setInnerHTMLMulti()','error',e.description + ' (ElementID: ' + aarrObjectID[i] + ', NewHTML: ' + lsValue + ')');
			}
		}
		return false;
	}
	
	this.setInnerText = function(asObjectID, asNewText) { // Sets value asNewText as TextContent in element asObjectID.
		try {
			var loElement = document.getElementById(asObjectID);
			if (gsBrowserType == 'IE') {
				loElement.innerText = asNewText;
			}
			else {
				loElement.textContent = asNewText;
			}
		} catch (e) {
			loGenFunc.handleError(lsClassPath,'setInnerText()','error',e.description + ' (ElementID: ' + asObjectID + ', NewText: ' + asNewText + ')');
		}
		return false;
	}
	
	this.setInnerTextMulti = function(aarrObjectID, aoNewText) { // Sets value(s) aoNewText as TextContent in array aarrObjectID.
		var i,loElement,lsValue;
		var lbIsArray = loGenFunc.isArray(aoNewHTML);
		for (i=0;i<aarrObjectID.length;i++) {
			if (lbIsArray == true) {
				lsValue = aoNewHTML[i];
			}
			else {
				lsValue = aoNewHTML;
			}
			try {
				loElement = document.getElementById(aarrObjectID[i]);
				if (gsBrowserType == 'IE') {
					loElement.innerText = lsValue;
				}
				else {
					loElement.textContent = lsValue;
				}
			} catch (e) {
				loGenFunc.handleError(lsClassPath,'setInnerTextMulti()','error',e.description + ' (ElementID: ' + aarrObjectID[i] + ', NewHTML: ' + lsValue + ')');
			}
		}
		return false;
	}
	
	this.setInnerTextfromXML = function(aoHTTPXML, asElementID, asValue) { // Parses the responseXML in aoHTTPXML: searches for elementnames asElementID in document, and sets innertext asValue.
		var loTagList = aoHTTPXML.responseXML.getElementsByTagName(asElementID);
		var loValueList = aoHTTPXML.responseXML.getElementsByTagName(asValue);

		if (loTagList.length > 0 && loValueList.length > 0) {
			for (var i=0; i<loTagList.length; i++) {
				if (gsBrowserType == 'IE') {
					try {
						document.getElementById(loTagList[i].text).innerText = loValueList[i].text;
					} catch (e) {
						loGenFunc.handleError(lsClassPath,'setInnerTextFromXML','error',e.description + ' (Unable to place data in element: ' + loTagList[i].text + '. Value: ' + loValueList[i].text + '.)');
					}
				}
				else {
					try {
						document.getElementById(loTagList[i].childNodes[0].nodeValue).textContent = loValueList[i].childNodes[0].nodeValue;
					} catch (e) {
						loGenFunc.handleError(lsClassPath,'setInnerTextFromXML','error',e.description + ' (Unable to place data in element: ' + loTagList[i].childNodes[0].nodeValue + '. Value: ' + loValueList[i].childNodes[0].nodeValue + '.)');
					}
				}
			}
		}
		else {
			loGenFunc.handleError(lsClassPath,'setInnerTextFromXML','error', 'Unable to find elements and/or values: \'' + asElementID + '\' / \'' + asValue + '\' in responseXML. Page will not be filled with data.)');
		}
	}
}

// General Functions, including ErrorHandling.
WebClient.GenFunc = function(asCalledFrom) {
	//ClassHeader
	var lsClassName = "GenFunc";
	var lsCalledFrom;
	if(asCalledFrom != null) {lsCalledFrom = asCalledFrom;}else{lsCalledFrom = gsClassName;}
	var lsClassPath = lsCalledFrom + '.' + lsClassName;
	//End ClassHeader

	this.Errors = gsErrors;
	this.handleError = function(asClass, asFunction, asType, asErrorMessage) { // Creates errormessage and sends it to the server by placing a pixel-tag.
		var lsError = '[' + asClass + '.' + asFunction + '] ' + asErrorMessage;
		gsErrors = gsErrors + lsError;
		try {
			//var loElement = document.getElementById("Errors");
			//var loValue = '<img src="/webservices/errorhandling/eventtolog.aspx?app=' + this.urlEncode(asClass + '.' + asFunction) + '&type=' + asType + '&msg=' + this.urlEncode(this.Left(asErrorMessage,500)) + '&page=' + window.location + '" id="errorImg" width="0" />';
			//loElement.innerHTML = loValue;
		} catch (e) {}
	}
	
	this.urlEncode = function(asInput) { // To urlencode asInput.
		var lsSafeChars = "0123456789" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "-_.!~*'()";
		var lsHex = "0123456789ABCDEF";		
		var lsEncoded = "";
		var lbLastCharIs13or10;
		for (var i = 0; i < asInput.length; i++ ) {
			var lsChr = asInput.charAt(i);
			if (lsChr == " ") {
				lsEncoded += "+";
				lbLastCharIs13or10 = false;
			}
			else if (lsSafeChars.indexOf(lsChr) != -1) {
				lsEncoded += lsChr;
				lbLastCharIs13or10 = false;
			}
			else {
				var liChr = lsChr.charCodeAt(0);
				if (liChr > 255) { //unicode, simply do not encode...
					lsEncoded += "+";
					var lbLastCharIs13or10 = false;
				}
				else if (liChr == 13) {
					if (lbLastCharIs13or10 == false) {
						lsEncoded += "%0D%0A";
						lbLastCharIs13or10 = true;
					}
				}
				else if (liChr == 10) {
					if (lbLastCharIs13or10 == false) {
						lsEncoded += "%0D%0A";
						lbLastCharIs13or10 = true;
					}
				}
				else {
					lsEncoded += "%";
					lsEncoded += lsHex.charAt((liChr >> 4) & 0xF);
					lsEncoded += lsHex.charAt(liChr & 0xF);
					var lbLastCharIs13or10 = false;
				}
			}
		}
		return lsEncoded;
	}
	
	this.isArray = function(aoInput){
		var lbArray = false;
		if (aoInput) {
			if (typeof aoInput == 'object' || typeof aoInput == 'function') {
				if (aoInput.constructor == Array) {
					lbArray = true;
				}
			}
		}
		return lbArray;
	}
	
	this.makePostString = function(aarrFields) {
		var i,loElement;
		var lsOutput = "";
		for (i=0;i<aarrFields.length;i++) {
			try {
				loElement = document.getElementById(aarrFields[i]);
				lsOutput += aarrFields[i]+'='+this.urlEncode(loElement.value)+'&';
			} catch (e) {
				lsOutput += aarrFields[i]+'=notfound&';
			}
		}
		return lsOutput + Math.random();
	}
	
	this.Left = function(asInput, aiLen) {
		if (aiLen <= 0) {
			return "";
		}
		else if (aiLen > String(asInput).length) {
			return asInput;
		}
		else {
			return String(asInput).substring(0,aiLen);
		}
	}
}