// HttpRequest object & the desired callback
var g_XmlRequester, g_XmlRequestCallback, g_XmlRequestUrl, g_XmlRequestStatus, g_XmlRequestDefaultError;

// SOAP support
var g_soapEnvelopeNS = "http://schemas.xmlsoap.org/soap/envelope/";

/*
 *
 * Data downloading.
 *
 */

// Create the request object used to retrieve data from server
function	CreateRequester() {
	if( typeof(XMLHttpRequest) != 'undefined') {
		return new XMLHttpRequest();
	}
	for( var i = 4; i > 1; --i ) {
		try {
			return new ActiveXObject("Msxml" + i + ".XMLHTTP");
		}
		catch(e) {
		}
	}
	try {
		return new ActiveXObject("Microsoft.XMLHTTP");
	}
	catch(e) {
	}
	alert("This browser does not support a required JavaScript component, this page will not function correctly");
	return null;
}

// Callback for XMLHttpRequest. We don't use the supplied callback as the direct callback
// as we have other house keeping to do.
function	XmlRequestComplete() {
	// 4 == Request has finished loading
	g_XmlRequestStatus = false;

	if( g_XmlRequester.readyState == 4 )
		switch( g_XmlRequester.status ) {
		case 200:
			if( g_XmlRequestCallback )
				g_XmlRequestCallback();
			g_XmlRequestStatus = true;
		case 400:
			var str = g_XmlRequester.getResponseHeader("SessionInfo");

			if( str && str == "TimedOut" )
				//window.location = "TimedOut.aspx";
				alert("Session timeout");

			str = g_XmlRequester.getResponseHeader("DatabaseError");

			if( str && str == "true" )
				//window.location = "DatabaseError.aspx";
				alert("Database exception");

			break;
		default:
			if( g_XmlRequestDefaultError )
				alert("A data request to the WebApplication server failed:\nRequest Url: " + g_XmlRequestUrl
					+ "\nStatus Code: " + g_XmlRequester.status
					+ "\nResponse Text: " + g_XmlRequester.responseText);
			g_XmlRequestStatus = false;
		}
}

// Get data from the server.
function	StartDownload(url, callback) {
//	XmlRequester.
	if( !g_XmlRequester )
		g_XmlRequester = CreateRequester();

	g_XmlRequestDefaultError = true;

	// store the callback and the url for if things go wrong
	g_XmlRequestCallback = callback;
	g_XmlRequestUrl = url;

	g_XmlRequester.open("GET", url, true);
	g_XmlRequester.onreadystatechange = XmlRequestComplete;
	g_XmlRequester.send(null);
}

function	StartSynchronousDownload(url, callback, defaultError, body) {
	g_XmlRequestCallback = callback;
	g_XmlRequestUrl = url;
	g_XmlRequestDefaultError = defaultError;

	if( !body )
		g_XmlRequester.open("GET", url, false);
	else
		g_XmlRequester.open("POST", url, false);

	g_XmlRequester.onreadystatechange = XmlRequestComplete;
	g_XmlRequester.send(body);
	return g_XmlRequestStatus;
}

function getDoubleFromXml() {
   var   r = g_XmlRequester.responseXML.lastChild;

   if( r.nodeName == "double" ) {
		if( "textContent" in r )
         return parseFloat( r.textContent );
      return parseFloat( r.text );
   }
   return NaN;
}

// list of tld's from http://data.iana.org/TLD/tlds-alpha-by-domain.txt
var twoLetterTldsRx = /AC|AD|AE|AF|AG|AI|AL|AM|AN|AO|AQ|AR|AS|AT|AU|AW|AX|AZ|BA|BB|BD|BE|BF|BG|BH|BI|BJ|BM|BN|BO|BR|BS|BT|BV|BW|BY|BZ|CA|CC|CD|CF|CG|CH|CI|CK|CL|CM|CN|CO|CR|CU|CV|CX|CY|CZ|DE|DJ|DK|DM|DO|DZ|EC|EDU|EE|EG|ER|ES|ET|EU|FI|FJ|FK|FM|FO|FR|GA|GB|GD|GE|GF|GG|GH|GI|GL|GM|GN|GP|GQ|GR|GS|GT|GU|GW|GY|HK|HM|HN|HR|HT|HU|ID|IE|IL|IM|IN|IO|IQ|IR|IS|IT|JE|JM|JO|JP|KE|KG|KH|KI|KM|KN|KR|KW|KY|KZ|LA|LB|LC|LI|LK|LR|LS|LT|LU|LV|LY|MA|MC|MD|MG|MH|MK|ML|MM|MN|MO|MP|MQ|MR|MS|MT|MU|MV|MW|MX|MY|MZ|NA|NC|NE|NF|NG|NI|NL|NO|NP|NR|NU|NZ|OM|PA|PE|PF|PG|PH|PK|PL|PM|PN|PR|PS|PT|PW|PY|QA|RE|RO|RU|RW|SA|SB|SC|SD|SE|SG|SH|SI|SJ|SK|SL|SM|SN|SO|SR|ST|SU|SV|SY|SZ|TC|TD|TF|TG|TH|TJ|TK|TL|TM|TN|TO|TP|TR|TT|TV|TW|TZ|UA|UG|UK|UM|US|UY|UZ|VA|VC|VE|VG|VI|VN|VU|WF|WS|YE|YT|YU|ZA|ZM|ZW/i;
var longTldsRx = /ASIA|ARPA|AERO|BIZ|CAT|COM|COOP|GOV|INFO|INT|JOBS|MIL|MOBI|MUSEUM|NAME|NET|ORG|PRO|TEL|TRAVEL/i
var emailRx = /^(?!\.)(?:\w|[\.-])+@(?!\.)(?:\w|[\.-](?!\.))+[a-z]+/i;

// Check to see if an email address is valid
function ValidateEmail( str ) {
	var	arry;

	arry = emailRx.exec( str );

	if( !arry || arry[ 0 ] != str )
		return false;

	var tld = str.substr( str.lastIndexOf(".") + 1 );

	arry = longTldsRx.exec( tld );

	if( arry && arry[ 0 ] == tld )
		return true;

	arry = twoLetterTldsRx.exec( tld );

	if( arry && arry[ 0 ] == tld )
		return true;

	return false;
}

// XMLSerializer doesn't do a good job for reabablitiy
function layoutXmlDoc( string ) {
	var pos = 0, lastPos = 0;
	var splits = new Array();

	while( pos >= 0 )
	{
		pos = string.indexOf(">", pos);
		if( pos >= 0 )
		{
			++pos;
			if( string.charAt( pos ) != '\n' ) {
				splits.push( string.substring( lastPos, pos ) );
				lastPos = pos;
			}
		}
		else
		{
			splits.push( string.substr( lastPos ) );
		}
	}
	var newString = "";

	for( var i = 0; i < splits.length; ++i ) {
		var subStr = splits[ i ];
		newString += subStr + "\n";
	}
	return newString;
}

// Some times we need special magic for mozilla & fire fox
function IsMoz() {
	return	window.navigator.appName.lastIndexOf( "Netscape" ) != -1;
}

// but more often we need special magic for exploder
function IsIE() {
	return	window.navigator.appName.lastIndexOf( "Microsoft" ) != -1;
}

// retrieve event target from event descriptor object
function GetEventTarget( eventObject ) {
	if( eventObject.srcElement )
		return eventObject.srcElement;
	return eventObject.target;
}

// Add an event callback function to an element
function 	AddEventListener( element, eventName, callback ) {
   if( element.addEventListener )
      element.addEventListener( eventName, callback, false );
   else
      element.attachEvent( "on" + eventName, callback );
}
