function SetCookie(name, value) {
	var argv = SetCookie.arguments;
	var argc = SetCookie.arguments.length;
	var expires = (argc > 2) ? argv[2] : null;
	var path = (argc > 3) ? argv[3] : null;
	var domain = (argc > 4) ? argv[4] : null;
	var secure = (argc > 5) ? argv[5] : false;
	document.cookie = name + "=" + escape (value) +
		((expires == null) ? "" : ("; expires=" + expires.toGMTString())) +
		((path == null) ? "" : ("; path=" + path)) +
		((domain == null) ? "" : ("; domain=" + domain)) +
		((secure == true) ? "; secure" : "");
}

function DeleteCookie(name) {
	var exp = new Date();
	exp.setTime (exp.getTime() - 1);
	var cval = GetCookie (name);
	document.cookie = name + "=" + cval + "; expires=" + exp.toGMTString();
}

function getExpires(expDays) {
	var expires = new Date();
	expires.setTime(expires.getTime() + (expDays*24*60*60*1000));
	return expires;
}

function getALToken(arg_length) {
	var strChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
	var retval = "";
	for (var i=0;i<arg_length;i++) {
		var rnum = Math.floor(Math.random() * strChars.length);
		retval += strChars.substr(rnum, 1);
	}
	return retval;
}

	
	
	


function getRegions(selectedCountryId) {
	var selRegions = document.getElementById("selRegions");
	while (selRegions.options.length > 0) {
		selRegions.remove(0);
	}
	if (selectedCountryId == 0) {
		selectedCountryId = document.getElementById("selCountries").value;
	}
	var showRegions = false;
	if (selectedCountryId > 0) {
		var myVars = new VarTable(selectedCountryId);
		myVars.add("countryid", selectedCountryId);
		var xmlDoc = loadXML("/_services/common/getCountryRegions", myVars, true);
		if (xmlDoc != null) {
			var retval = getNodeTextContent(xmlDoc.getElementsByTagName('returnvalue')[0]);
			if (retval == "true") {
				var regionsNode = xmlDoc.getElementsByTagName('regions')[0];
				addEmptyOption(selRegions);
				if (regionsNode.childNodes.length > 0) {
					showRegions = true;
					removeAllChildNodes(document.getElementById("lblRegion"));
					document.getElementById("lblRegion").appendChild(document.createTextNode(getNodeTextContent(regionsNode.attributes.getNamedItem("fieldtitle_division_name"))));
				}
				for (var i=0;i<regionsNode.childNodes.length;i++) {
					if (regionsNode.childNodes[i].nodeType == 1) {
						currentregionid = getNodeTextContent(regionsNode.childNodes[i].attributes.getNamedItem("id"));
						currentregionname = getNodeTextContent(regionsNode.childNodes[i].attributes.getNamedItem("name"));
						var objOption = document.createElement('option');
						objOption.value = currentregionid;
						if (parseInt(currentregionid) == parseInt(initVars.get("regionid"))) {
							objOption.selected = "true";
						}
						objOption.appendChild(document.createTextNode(currentregionname));
						selRegions.appendChild(objOption);
					}
				}
			} else if (retval == "false") {
				var errormessage = getNodeTextContent(xmlDoc.getElementsByTagName('errormessage')[0]);
				alert(errormessage);
			}
		} else {
			alert("There was a problem retrieving the XML data!");
		}
	} else {
		addEmptyOption(selRegions);
	}
	document.getElementById("li_region").style.display = showRegions?"block":"none";
}

function addEmptyOption(selRegions) {
	var objOptionEmpty = document.createElement('option');
	objOptionEmpty.value = "0";
	objOptionEmpty.appendChild(document.createTextNode("     "));
	selRegions.appendChild(objOptionEmpty);
}

function LoginHandler() {
	this.msgHandler = new XMLMessageHandler();
	this.msgHandler.add("username", "err_username");
	this.msgHandler.add("password", "err_password");
	
	this.getSubmitListener = function(loginHandler) {
		return function(e) {
			preventDefault(e);
			loginHandler.onsubmit();
		}
	}
	
	this.onsubmit = function() {
		this.msgHandler.clearMessages();
		var username = document.getElementById("username").value;
		var password = document.getElementById("password").value;
		var remember = document.getElementById("remember").checked;
		var url = document.getElementById("url").value;
		var response = getChallengeResponse(password);
		if (response.length > 0) {
			var res = this.doLogin(username, response, remember);
			if (res != null) {
				if (res.get("returnvalue")) {
					var goto_url = res.get("url");
					if (url.length > 0) {
						goto_url = url;
					}
					if (remember) {
						document.location.href = initVars.get("uri_/account/autologin/") + "?url=" + UTF8.urlEncodePathComponent(goto_url);
					} else {
						document.location.href = goto_url;
					}
				} else {
					document.getElementById("password").value = "";
					this.msgHandler.handleMessages(res);
				}
			}
		}
	}
	
	this.doLogin = function(username, response, remember) {
		var myVars = new VarTable();
		myVars.add("username", username);
		myVars.add("response", response);
		if (remember) {
			myVars.add("remember", "true");
		}
		var xmlDoc = loadXML("/_services/account/login", myVars, true);
		if (xmlDoc != null) {
			var xmlretval = getNodeTextContent(xmlDoc.getElementsByTagName('returnvalue')[0]);
			if (xmlretval == "true") {
				var retval = new VarTable();
				retval.add("returnvalue", true);
				retval.add("url", getNodeTextContent(xmlDoc.getElementsByTagName('url')[0]));
				return retval;
			} else if (xmlretval == "false") {
				return getFailedReturnValue(xmlDoc);
			} else {
				return null;
			}
		} else {
			return null;
		}
		
	}
	
	DeleteCookie("autologin");
	DeleteCookie("altoken");
	addEvent(document.getElementById("frmlogin"), "submit", this.getSubmitListener(this));
	document.getElementById("username").focus();
}









function getChallengeResponse(str) {
	var myVars = new VarTable();
	var xmlDoc = loadXML("/_services/account/getChallenge", myVars, true);
	if (xmlDoc != null) {
		var xmlretval = getNodeTextContent(xmlDoc.getElementsByTagName('returnvalue')[0]);
		if (xmlretval == "true") {
			var challenge = getNodeTextContent(xmlDoc.getElementsByTagName('challenge')[0]);
			return sha1(str + challenge);
		}
	}
	return "";
}








function sha1(msg) //adjusted for utf-8
{
    // constants [4.2.1]
    var K = [0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6];


    // PREPROCESSING 
 	ba_msg = UTF8.getByteArrayFromString(msg); //common.js
	ba_msg.push(0x80); // add trailing '1' bit to string [5.1.1]

    // convert string msg into 512-bit/16-integer blocks arrays of ints [5.2.1]
    var l = Math.ceil(ba_msg.length/4) + 2;  // long enough to contain msg plus 2-word length
    var N = Math.ceil(l/16);              // in N 16-int blocks
    var M = new Array(N);
    for (var i=0; i<N; i++) {
        M[i] = new Array(16);
        for (var j=0; j<16; j++) {  // encode 4 chars per integer, big-endian encoding
            M[i][j] = (ba_msg[i*64+j*4]<<24) | (ba_msg[i*64+j*4+1]<<16) | 
                      (ba_msg[i*64+j*4+2]<<8) | (ba_msg[i*64+j*4+3]);
        }
    }
    // add length (in bits) into final pair of 32-bit integers (big-endian) [5.1.1]
    // note: most significant word would be ((len-1)*8 >>> 32, but since JS converts
    // bitwise-op args to 32 bits, we need to simulate this by arithmetic operators
    M[N-1][14] = ((ba_msg.length-1)*8) / Math.pow(2, 32); M[N-1][14] = Math.floor(M[N-1][14])
    M[N-1][15] = ((ba_msg.length-1)*8) & 0xffffffff;

    // set initial hash value [5.3.1]
    var H0 = 0x67452301;
    var H1 = 0xefcdab89;
    var H2 = 0x98badcfe;
    var H3 = 0x10325476;
    var H4 = 0xc3d2e1f0;

    // HASH COMPUTATION [6.1.2]

    var W = new Array(80); var a, b, c, d, e;
    for (var i=0; i<N; i++) {

        // 1 - prepare message schedule 'W'
        for (var t=0;  t<16; t++) W[t] = M[i][t];
        for (var t=16; t<80; t++) W[t] = ROTL(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16], 1);

        // 2 - initialise five working variables a, b, c, d, e with previous hash value
        a = H0; b = H1; c = H2; d = H3; e = H4;

        // 3 - main loop
        for (var t=0; t<80; t++) {
            var s = Math.floor(t/20); // seq for blocks of 'f' functions and 'K' constants
            var T = (ROTL(a,5) + f(s,b,c,d) + e + K[s] + W[t]) & 0xffffffff;
            e = d;
            d = c;
            c = ROTL(b, 30);
            b = a;
            a = T;
        }

        // 4 - compute the new intermediate hash value
        H0 = (H0+a) & 0xffffffff;  // note 'addition modulo 2^32'
        H1 = (H1+b) & 0xffffffff; 
        H2 = (H2+c) & 0xffffffff; 
        H3 = (H3+d) & 0xffffffff; 
        H4 = (H4+e) & 0xffffffff;
    }

    return H0.toHexStr() + H1.toHexStr() + H2.toHexStr() + H3.toHexStr() + H4.toHexStr();
}

//
// function 'f' [4.1.1]
//
function f(s, x, y, z) 
{
    switch (s) {
    case 0: return (x & y) ^ (~x & z);           // Ch()
    case 1: return x ^ y ^ z;                    // Parity()
    case 2: return (x & y) ^ (x & z) ^ (y & z);  // Maj()
    case 3: return x ^ y ^ z;                    // Parity()
    }
}

//
// rotate left (circular left shift) value x by n positions [3.2.5]
//
function ROTL(x, n)
{
    return (x<<n) | (x>>>(32-n));
}

//
// extend Number class with a tailored hex-string method 
//   (note toString(16) is implementation-dependant, and 
//   in IE returns signed numbers when used on full words)
//
Number.prototype.toHexStr = function()
{
    var s="", v;
    for (var i=7; i>=0; i--) { v = (this>>>(i*4)) & 0xf; s += v.toString(16); }
    return s;
}
