//
//   --------------------====[  _timinc.js rev 7  ]====------------------------
//
//_____________________________________________________________________________
//                                                                        A P I
//
// ltrim(str)
//		Remove leading spaces from string
// rtrim(str)
//		Remove trailing spaces from string
// trim(str)
//		Remove leading and trailing spaces from string
// pause(milliseconds)
//		Pauses execution for so many milliseconds
// MAX(a, b)
//		Returns the greater
// MIN(a, b)
//		Returns the lesser
// setCookie(name, value, lifetime, path, domain)
//		Set a cookie on the client machine. lifetime is in seconds.
// getCookie(name)
//		Retrieve a cookie on the chlient machine.
// gotoPage(url)
//		Goes to the specified url. Note if you are using the <BASE HREF=""> tag
//		then specifying a relative url wont work under internet explorer...
// URLMangle(text)
//		Returns a mangled "url-friendly" version of text.
// drawEmailAddress(scrambled, text)
//		draws a mailto link with rot13 of scrambled string. If text != null, it
//		is used as the link text.
// getPosX(obj)
//		Get the x-position of an html object.
// getPosY(obj)
//		Get the y-position of an html object.
// detectFlashVersion()
//		Try to determine if flash is installed, and what version.
// checkChars(str, cvalid, cinvalid)
//		Returns a list of invalid characters in str, or "" if it's ok. cvalid is
//		a string of all valid characters. If it is empty, cinvalid is instead
//		used as a string of all invalid characters.
//
// pageInit()
//		Call from page onload.
// pageCleanup()
//		Call from page onunload
// openWindow(w, h, url)
//		Open a popup window.
// openImagePreview(imgurl, w, h)
//		Open a window and previews the specified image in it.
// registerWindowToClose(win)
//		Adds the window to a list of windows to try and close when the page is
//		changed (unloaded).
// closeRegisteredWindows()
//		Call from onunload in <body> (or manually) to close registered windows
//
// selectCtrlClear(ctrl)
//		Clears all options in a <select> control.
// selectCtrlAppend(ctrl, value, [option])
//		Appends an option to a <select> control. If value is unspecified, the
//		option string is used for the value also.
// selectCtrlSelect(ctrl, value)
//		Selects the given <option> in a <select> control.
// selectCtrlExists(ctrl, value)
//		Returns true if the given <option> in a <select> control exists.
// selectCtrlBuildList(ctrl)
//		Returns a string list of the comma separated values of all <option>s in
//		a <select> control.
//
// validateRequired(ctrl, [desc])
//		Success when control contains some data. desc is a description of the
//		field for the error message (eg, "your name").
// validateNumber(ctrl, [flags], [llimit, ulimit], [desc])
//		Success when control contains a number valid according to the flags. The
//		flags string may contain:
//			i	to ensure number is an integer (not float)
//			p	to ensure number is positive
//			z	to ensure number is greater than zero.
//		llimit and ulimit are the allowable lower and upper numerical limits.
//		desc is a description of the field for the error message (eg, "a Year").
// validateYear(ctrl)
//		Success when control contains a valid year.
// validateDate(ctrld, ctrlm, ctrly)
//		Success when d/m/y controls contain a valid date.
// validateEmail(ctrl)
//		Success when control contains a valid email address.
// validateSelected(ctrl, [desc])
//		Success when <select> control is at index > 0 or there is only one
//		<option> to be selected. For multiple-selection <select> controls, index
//		must just be greater than -1 (no selection). desc is a description of
//		the field for the error message (eg, "your gender").
// validatePasswords(ctrl1, ctrl2)
//		Seccuess when both password controls contain the same value.
// validatePasswordDiffers(pwctrl, otherctrl, desc)
//		Success when the password is not the same as any word in the other
//		control. Case is irrelevant. desc is a description of the field for the
//		error message (eg, "your gender").
//
// popupTable(anchorobj, name)
//		call to make a <div> block (called 'div'+name) visible. It must contain
//		a <table> called 'tbl'+name. It is positioned centrally over anchorobj's
// 		co-ordinates (note anchorobj's style *must* have "position: relative;"
//		specified!).
// popupSelector(anchorobj, name, formobj)
//		call to make a <div> block (called 'div'+name) visible. It must contain
//		a <table> called 'tbl'+name, and within that, a <select> called 'sel'+name.
//		It is positioned centrally over anchorobj's co-ordinates (note anchorobj's
//		style *must* have "position: relative;" specified!). 'formobj' is the name
//		of the object that will recieve the <select>'s value as it changes.
// popupHide()
//		Call to hide the current <div> block immediately.
// popupOnChange()
//		Copys the changed value to the form object
// popupOnClick()
//		Ends the popup, refocusing the another object.
// popupOnBlur()
//		Hide the popup immediately
//
//_____________________________________________________________________________
//                                                                      I N I T

// detected flash version
var flashVersion = 0;

// Popup's object pointers
var popupDivObj = 0;
var popupFormObj = 0;
var popupSelectObj = 0;
var popupOffsetX = 0;				// this is reset to 0 after each popupXXX()
var popupOffsetY = 0;				// this is reset to 0 after each popupXXX()

// IE Fudge - setup getElementById()
if(document.all) {
	document.getElementById = function(id) {
		return document.all[id];
	}
}

// Registerd open window list
var openWindowsList = new Array();

//_____________________________________________________________________________
//                                                                      C O D E


// ltrim(str)
//		Remove leading spaces from string
function ltrim(str)
{
   var whitespace = new String(" \t\n\r");
   var s = new String(str);
   if (whitespace.indexOf(s.charAt(0)) != -1) {
	  var j=0, i = s.length;
	  while (j < i && whitespace.indexOf(s.charAt(j)) != -1)
		 j++;
	  s = s.substring(j, i);
   }
   return s;
}

// rtrim(str)
//		Remove trailing spaces from string
function rtrim(str)
{
   var whitespace = new String(" \t\n\r");
   var s = new String(str);
   if (whitespace.indexOf(s.charAt(s.length-1)) != -1) {
	  var i = s.length - 1;
	  while (i >= 0 && whitespace.indexOf(s.charAt(i)) != -1)
		 i--;
	  s = s.substring(0, i+1);
   }

   return s;
}

// trim(str)
//		Remove leading and trailing spaces from string
function trim(str)
{
   return rtrim(ltrim(str));
}

// pause(milliseconds)
//		Pauses execution for so many milliseconds
function pause(milliseconds)
{
	var now = new Date();
	var exitTime = now.getTime() + milliseconds;
	while(true) {
		var now = new Date();
		if(now.getTime() >= exitTime) break;
	}
}

// MAX(a, b)
//		Returns the greater
function MAX(a, b)
{
	return a > b? a : b;
}

// MIN(a, b)
//		Returns the lesser
function MIN(a, b)
{
	return a < b? a : b;
}

// setCookie(name, value, lifetime, path, domain)
//		Set a cookie on the client machine. lifetime is in seconds.
function setCookie(name, value, lifetime, path, domain)
{
	document.cookie = escape(name) + "=" + escape(value) +
		(lifetime? ";expires=" + (new Date((new Date()).getTime() + (1000 * lifeTime))).toGMTString() : "" ) +
		(path? ";path=" + path : "") +
		(domain? ";domain=" + domain : "");
}

// getCookie(name)
//		Retrieve a cookie on the chlient machine.
function getCookie(name)
{
	if(document.cookie.indexOf(name + "=") > -1) {
		cookies = document.cookie.split("; ");
		for(i = 0; i < cookies.length; i++) {
			pair = coockies[i].split("=");
			if(pair[0] == name) return unescape(pair[1]);
		}
	}
	return null;
}

// gotoPage(url)
//		Goes to the specified url. Note if you are using the <BASE HREF=""> tag
//		then specifying a relative url wont work under internet explorer...
function gotoPage(url)
{
	// WARNING!!! This doesn't work in internet explorer when the <BASE HREF="">
	// tag is used and you specify a relative url... I need a work around!!!
	location.href = url;
}

// URLMangle(text)
//		Returns a mangled "url-friendly" version of text.
function URLMangle(text)
{
	// characters to allow
	chars = "abcdefghijklmnopqrstuvwxyz0123456789_-";
	// characters to convert into a "_"
	convert = " ";

	title = trim((""+text).toLowerCase());
	urlname = "";
	for(a = 0; a < title.length; a++) {
		found = false;
		for(b = 0; b < chars.length; b++)
			if(chars.charAt(b) == title.charAt(a)) {
				urlname += title.charAt(a);
				found = true;
				break;
			}
		if(!found) {
			for(b = 0; b < convert.length; b++)
				if(convert.charAt(b) == title.charAt(a))
					urlname += "_";
		}
	}
	return urlname;
}

// drawEmailAddress(scrambled, text)
//		draws a mailto link with rot13 of scrambled string. If text != null, it
//		is used as the link text.
function drawEmailAddress(scrambled, text)
{
	chars = "abcdefghijklmnopqrstuvwxyz";
	realaddr = "";
	for(a = 0; a < scrambled.length; a++)
		if((loc = chars.indexOf(scrambled.charAt(a))) >= 0)
			realaddr += chars.charAt((loc + 13) % 26);
		else
			realaddr += scrambled.charAt(a);
	document.write("<a href=\"mailto:" + realaddr + "\">" + (text == null? realaddr : text) + "</a>");
}

// getPosX(obj)
//		Get the x-position of an html object.
function getPosX(obj)
{
	var curleft = 0;
	if (obj.offsetParent) {
		while (obj.offsetParent) {
			curleft += obj.offsetLeft
			obj = obj.offsetParent;
		}
	}
	else if (obj.x)
		curleft += obj.x;
	return curleft;
}

// getPosY(obj)
//		Get the y-position of an html object.
function getPosY(obj)
{
	var curtop = 0;
	if (obj.offsetParent) {
		while (obj.offsetParent) {
			curtop += obj.offsetTop
			obj = obj.offsetParent;
		}
	}
	else if (obj.y)
		curtop += obj.y;
	return curtop;
}

// detectFlashVersion();
//		Try to determine if flash is installed, and what version.
function detectFlashVersion()
{
	var a, agent = navigator.userAgent.toLowerCase();

	// NS3+ and Opera3+: Check plugin array
	if (navigator.plugins != null && navigator.plugins.length > 0) {
		var flashPlugin = navigator.plugins['Shockwave Flash'];
		if (typeof flashPlugin == 'object') {
			if (flashPlugin.description.indexOf('7.') != -1) flashVersion = 7;
			else if (flashPlugin.description.indexOf('6.') != -1) flashVersion = 6;
			else if (flashPlugin.description.indexOf('5.') != -1) flashVersion = 5;
			else if (flashPlugin.description.indexOf('4.') != -1) flashVersion = 4;
			else if (flashPlugin.description.indexOf('3.') != -1) flashVersion = 3;
		}
	}

	// IE4+ on Win32:  Try and create ActiveX object using VBScript
	else if (agent.indexOf("msie") != -1 && parseInt(navigator.appVersion) >= 4 && agent.indexOf("win") != -1 && agent.indexOf("16bit") == -1) {
		a =  '<scr' + 'ipt language="VBScript"\> \n';
		a += 'on error resume next \n';
		a += 'dim obFlash \n';
		a += 'set obFlash = CreateObject("ShockwaveFlash.ShockwaveFlash.7") \n';
		a += 'if IsObject(obFlash) then \n';
		a += 'flashVersion = 7 \n';
		a += 'else set obFlash = CreateObject("ShockwaveFlash.ShockwaveFlash.6") end if \n';
		a += 'if IsObject(obFlash) then \n';
		a += 'flashVersion = 6 \n';
		a += 'else set obFlash = CreateObject("ShockwaveFlash.ShockwaveFlash.5") end if \n';
		a += 'if flashVersion < 6 and IsObject(obFlash) then \n';
		a += 'flashVersion = 5 \n';
		a += 'else set obFlash = CreateObject("ShockwaveFlash.ShockwaveFlash.4") end if \n';
		a += 'if flashVersion < 5 and IsObject(obFlash) then \n';
		a += 'flashVersion = 4 \n';
		a += 'else set obFlash = CreateObject("ShockwaveFlash.ShockwaveFlash.3") end if \n';
		a += 'if flashVersion < 4 and IsObject(obFlash) then \n';
		a += 'flashVersion = 3 \n';
		a += 'end if';
		a += '</scr' + 'ipt\> \n';
		document.write(a);
	}

	// WebTV 2.5 supports flash 3
	else if (agent.indexOf("webtv/2.5") != -1) flashVersion = 3;

	// older WebTV supports flash 2
	else if (agent.indexOf("webtv") != -1) flashVersion = 2;
}

// checkChars(str, cvalid, cinvalid)
//		Returns a list of invalid characters in str, or "" if it's ok. cvalid is
//		a string of all valid characters. If it is empty, cinvalid is instead
//		used as a string of all invalid characters.
function checkChars(str, cvalid, cinvalid)
{
	ret = "";
	if(str == null || cvalid == null || (cvalid == "" && cinvalid == null)) {
		alert("JavaScript Error: validateChars(): Bad argument!");
		return "";
	}
	if(cvalid != "") {
		for(a = 0; a < str.length; a++)
			if(cvalid.indexOf(str.charAt(a)) < 0)
				ret += str.charAt(a);
	}
	else {
		for(a = 0; a < cinvalid.length; a++)
			if(str.indexOf(cinvalid.charAt(a)) >= 0)
				ret += cinvalid.charAt(a);
	}
	return ret;
}

// pageInit()
//		Call from page onload.
function pageInit()
{
	if(document.onloadfunc)
	  document.onloadfunc();
}

// pageCleanup()
//		Call from page onunload
function pageCleanup()
{
	closeRegisteredWindows();
}

// openWindow(w, h, url)
//		Open a popup window.
function openWindow(w, h, url, name)
{
	win = window.open(url, name, 'width='+w+',height='+h+',status=no,location=no,menubar=no,toolbar=no,resizable=yes,scrollbars=yes');
	win.focus();
	if(!win.opener) win.opener = self;
	return win;
}

// openImagePreview(imgurl, w, h)
//		Open a window and previews the specified image in it.
function openImagePreview(imgurl, w, h)
{
	win = window.open('about:blank', name, 'width='+(w + 20)+',height='+(h + 20)+',status=no,location=no,menubar=no,toolbar=no,resizable=no,scrollbars=auto');
	win.focus();
	registerWindowToClose(win);
	html = 	'<body leftmargin=0 topmargin=0 marginwidth=0 marginheight=0>' +
			'<table width=100% height=100% cellpadding=0 cellspacing=0 border=0>' +
			'<tr><td align=center valign=middle><a href="javascript:window.close();">' +
			'<img src="'+imgurl+'" width='+w+' height='+h+' border=0></a></td></tr></table></body>';
	win.document.write(html);
}

// registerWindowToClose(win)
//		Adds the window to a list of windows to try and close when the page is
//		changed (unloaded).
function registerWindowToClose(win)
{
	for(var a = 0; a < openWindowsList.lengh; a++)
		if(openWindowsList[a] == win) return;
	openWindowsList[openWindowsList.length] = win;
}

// closeRegisteredWindows()
//		Call from onunload in <body> (or manually) to close registered windows
function closeRegisteredWindows()
{
	for(var a = 0; a < openWindowsList.length; a++)
		if(openWindowsList[a]) openWindowsList[a].close();
}

// selectCtrlClear(ctrl)
//		Clears all options in a <select> control.
function selectCtrlClear(ctrl)
{
	while(ctrl.options.length) ctrl.options[0] = null;
}

// selectCtrlAppend(ctrl, value, [option])
//		Appends an option to a <select> control. If value is unspecified, the
//		option string is used for the value also.
function selectCtrlAppend(ctrl, value, option)
{
	ctrl.options[ctrl.options.length] = new Option(option == null? value : option, value);
}

// selectCtrlSelect(ctrl, value)
//		Selects the given <option> in a <select> control.
function selectCtrlSelect(ctrl, value)
{
	for(a = 0; a < ctrl.options.length; a++)
		if(ctrl.options[a].value == value) {
			ctrl.selectedIndex = a;
			break;
		}
}

// selectCtrlExists(ctrl, value)
//		Returns true if the given <option> in a <select> control exists.
function selectCtrlExists(ctrl, value)
{
	for(a = 0; a < ctrl.options.length; a++)
		if(ctrl.options[a].value == value)
			return true;
	return false;
}

// selectCtrlBuildList(ctrl)
//		Returns a string list of the comma separated values of all <option>s in
//		a <select> control.
function selectCtrlBuildList(ctrl)
{
	ret = ""; sep = "";
	for(a = 0; a < ctrl.options.length; a++) {
		ret += sep + ctrl.options[a].value;
		sep = ", ";
	}
	return ret;
}

// validateRequired(ctrl, [desc])
//		Success when control contains some data. desc is a description of the
//		field for the error message (eg, "your name").
function validateRequired(ctrl, desc)
{
	if(ctrl == null) {
		alert("JavaScript Error: validateRequired(): Null control!");
		return true;
	}
	if(trim(ctrl.value) == "") {
		if(desc)	alert("Please enter "+desc+"!");
		else		alert("This is a required field, please enter a value!");
		ctrl.focus();
		return false;
	}
	return true;
}

// validateNumber(ctrl, [flags], [llimit, ulimit], [desc])
//		Success when control contains a number valid according to the flags.
//		The flags string may contain:
//			i	to ensure number is an integer (not float)
//			p	to ensure number is positive
//			z	to ensure number is greater than zero.
//		llimit and ulimit are the allowable lower and upper numerical limits.
//		desc is a description of the field for the error message (eg, "a year").
function validateNumber(ctrl, flags, llimit, ulimit, desc)
{
	allowzero = allownegative = allowfloat = true;
	valid = true;
	msg = "This value is not valid!";

	if(ctrl == null) {
		alert("JavaScript Error: validateNumber(): Null control!");
		return true;
	}

	ctrl.value = origstr = str = trim(ctrl.value);

	// Work out flags
	if(flags != null)
		for(a = 0; a < flags.length; a++)
			switch(flags.charAt(a)) {
			case 'i': allowfloat = false; break;
			case 'p': allownegative = false; break;
			case 'z': allowzero = false; break;
			default:
				alert("JavaScript Error: validateNumber(): Bad flags!");
				return true;	// validation passes
			}

	// Ignore empty
	if(str == "") return true;

	// Test for bad characters
	chars = "0123456789"; canseedot = allowfloat;
	if(str.charAt(0) == "-")
		str = str.substr(1);
	for(a = 0; a < str.length; a++)
		if(chars.indexOf(str.charAt(a)) == -1) {
			if(canseedot && str.charAt(a) == ".")
				canseedot = false;		// allow only one
			else
				valid = false;
		}

	// Test number
	if(valid) {
		res = allowfloat? parseFloat(origstr) : parseInt(origstr);
		if(isNaN(res)) valid = false;
		if(valid && !allowzero && res == 0) {
			valid = false;
			msg = "The value cannot be zero!";
		}
		if(valid && !allownegative && res < 0) {
			valid = false;
			msg = "The value cannot be negative!";
		}
		if(valid && llimit != null && ulimit != null) {
			if((allowfloat? parseFloat(llimit) : parseInt(llimit)) > res) {
				valid = false;
				msg = "The value cannot be less than "+llimit+"!";
			}
			if((allowfloat? parseFloat(ulimit) : parseInt(ulimit)) < res) {
				valid = false;
				msg = "The value cannot be more than "+ulimit+"!";
			}
		}
	}

	// Valid?
	if(!valid) {
		alert("Please re-enter "+(desc? desc : "this number")+"!\n"+msg);
		ctrl.focus();
	}
	return valid;
}

// validateYear(ctrl)
//		Success when control contains a valid year.
function validateYear(ctrl)
{
	chars = "0123456789"; valid = true;

	if(ctrl == null) {
		alert("JavaScript Error: validateYear(): Null control!");
		return true;
	}
	ctrl.value = trim(ctrl.value);
	for(a = 0; a < ctrl.value.length; a++)
		if(chars.indexOf(ctrl.value.charAt(a)) == -1)
			valid = false;
	y = ctrl.value;
	if(y.length == 2) {
		if(0 + y < 20)	y = "20" + y;
		else			y = "19" + y;
	}
	if(y.length != 4 && y.length != 0) valid = false;
	if(!valid) {
		alert("Please enter a valid year!");
		ctrl.focus();
		return false;
	}
	ctrl.value = y;
	return true;
}

// isLeapYear(year)
//		Returns the number of days in february for a given year. This is usually
//		29. It is only 28 when the year is divisible by 4, UNLESS it is also
//		divisible by 100, BUT NOT where it is also divisible by 400. Follow?
function isLeapYear(year)
{
	return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
}

// validateDate(ctrld, ctrlm, ctrly)
//		Success when d/m/y controls contain a valid date.
function validateDate(ctrld, ctrlm, ctrly)
{

	var days_in_month = new Array(31, 99, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
	if(ctrl == null) {
		alert("JavaScript Error: validateDate(): Null control!");
		return true;
	}
	if(trim(ctrld.value) == "" && trim(ctrlm.value) == "" && trim(ctrly.value) == "")
		return true;
	if(!validateYear(ctrly))
		return false;
	day = ctrld.value - 0; month = ctrlm.value - 0; year = ctrly.value - 0;
	if(month < 1 || month > 12) {
		alert("Please enter a valid month!")
		ctrlm.focus();
		return false;
	}
	if(day < 1 || (month == 2 && day > (isLeapYear(year)? 29 : 28)) || day > days_in_month[month - 1]) {
		alert("Please enter a valid day!")
		ctrld.focus();
		return false
	}
	return true
}

// validateEmail(ctrl)
//		Success when control contains a valid email address.
function validateEmail(ctrl)
{
	if(ctrl == null) {
		alert("JavaScript Error: validateEmail(): Null control!");
		return true;
	}
	str = trim(ctrl.value).toLowerCase();
	if(ctrl.value != str)
		ctrl.value = str;
	if(str != "") {
		valid = true;
		a = ctrl.value.indexOf('@')
		if(a < 0 || ctrl.value.indexOf('.', a) < 0 ) {
			alert("Please enter a valid email address!");
			ctrl.focus();
			return false;
		}
		res = checkChars(ctrl.value.substr(0, a), "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!#$%&'*+-/=?^_`(|)~.");
		if(res != "") {
			alert("The following characters are not allowed in the first part of an email address: "+res);
			ctrl.focus();
			return false;
		}
		res = checkChars(ctrl.value.substr(a + 1), "abcdefghijklmnopqrstuvwxyz0123456789-.");
		if(res != "") {
			alert("The following characters are not allowed in the domain part of an email address: "+res);
			ctrl.focus();
			return false;
		}
	}
	return true;
}

// validateSelected(ctrl, [desc])
//		Success when <select> control is at index > 0 or there is only one
//		<option> to be selected. For multiple-selection <select> controls, index
//		must just be greater than -1 (no selection). desc is a description of
//		the field for the error message (eg, "your gender").
function validateSelected(ctrl, desc)
{
	valid = true;
	if(ctrl == null) {
		alert("JavaScript Error: validateSelected(): Null control!");
		return true;
	}
	if(ctrl.multiple && ctrl.selectedIndex < 0) valid = false;
	if(!ctrl.multiple && ctrl.selectedIndex < 1 && ctrl.options.length > 1) valid = false;
	if(!valid) {
		if(desc)	alert("Please select "+desc+"!");
		else		alert("Please make a selection!");
		ctrl.focus();
		return false;
	}
	return true;
}

// validatePasswords(ctrl1, ctrl2)
//		Seccuess when both password controls contain the same value.
function validatePasswords(ctrl1, ctrl2)
{
	if(ctrl1 == null || ctrl2 == null) {
		alert("JavaScript Error: validatePasswords(): Null control!");
		return true;
	}
	if(ctrl1.value != ctrl2.value) {
		alert("The two passwords you have entered are different!");
		ctrl2.focus();
		return false;
	}
	return true;
}

// validatePasswordDiffers(pwctrl, otherctrl, desc)
//		Success when the password is not the same as any word in the other
//		control. Case is irrelevant. desc is a description of the field for the
//		error message (eg, "your gender").
function validatePasswordDiffers(pwctrl, otherctrl, desc)
{
	if(pwctrl == null || otherctrl == null) {
		alert("JavaScript Error: validatePasswordDiffers(): Null control!");
		return true;
	}
	passwd = trim(pwctrl.value).toLowerCase();
	words = otherctrl.value.split(" ");
	if(passwd != "")
		for(a = 0; a < words.length; a++)
			if(words[a] != "" && passwd == words[a].toLowerCase()) {
				if(desc)	alert("The password is too similar to "+desc+"!\n\nPlease choose another.");
				else		alert("The password is too similar to other information!\n\nPlease choose another.");
				pwctrl.focus();
				return false;
			}
	return true;
}

// popupTable(anchorobj, name)
//		call to make a <div> block (called 'div'+name) visible. It must contain
//		a <table> called 'tbl'+name. It is positioned centrally over anchorobj's
//		co-ordinates (note anchorobj's style *must* have "position: relative;"
//		specified!).
function popupTable(anchorobj, name)
{
	popupHide();
	tobj = document.getElementById('tbl' + name)
	popupDivObj = document.getElementById('div' + name)
	popupFormObj = popupSelectObj = 0;
	if(!tobj || !popupDivObj) {
		popupOffsetX = popupOffsetY = 0;	// Reset offset
		alert("JavaScript Error: popupTable(): Couldn't find object!");
		return false;
	}

	// Popup
	if(popupOffsetX == -1)		desiredx = MAX(0, document.body.clientWidth - tobj.offsetWidth) / 2;
	else if(popupOffsetX == -2)	desiredx = MAX(0, getPosX(anchorobj) + (anchorobj.offsetWidth - tobj.offsetWidth) / 2);
	else						desiredx = getPosX(anchorobj) + popupOffsetX;
	if(popupOffsetY == -2)		desiredy = MAX(0, getPosY(anchorobj) + (anchorobj.offsetHeight - tobj.offsetHeight) / 2);
	else						desiredy = getPosY(anchorobj) + popupOffsetY;
	popupDivObj.style.left = MAX(desiredx, 0);
	popupDivObj.style.top = MAX(MIN(desiredy, MAX(document.body.scrollHeight, document.body.clientHeight) - tobj.offsetHeight), 0)
	popupDivObj.style.visibility = "visible";
	popupOffsetX = popupOffsetY = 0;	// Reset offset
	return false;
}

// popupSelector(anchorobj, name, formobj)
//		call to make a <div> block (called 'div'+name) visible. It must contain
//		a <table> called 'tbl'+name, and within that, a <select> called 'sel'+name.
//		It is positioned centrally over anchorobj's co-ordinates (note anchorobj's
//		style *must* have "position: relative;" specified!). 'formobj' is the name
//		of the object that will recieve the <select>'s value as it changes.
function popupSelector(anchorobj, name, formobj)
{
	popupHide();
	tobj = document.getElementById('tbl' + name);
	popupDivObj = document.getElementById('div' + name);
	popupSelectObj = document.getElementById('sel' + name);
	popupFormObj = formobj;
	if(!tobj || !popupDivObj || !popupSelectObj) {
		popupOffsetX = popupOffsetY = 0;	// Reset offset
		alert("JavaScript Error: popupSelector(): Couldn't find object!");
		return false;
	}
	popupSelectObj.selectedIndex = -1;	// Deselect before popping up
	desiredx = getPosX(anchorobj) - tobj.offsetWidth + 20 + popupOffsetX;
	desiredy = getPosY(anchorobj) + anchorobj.offsetHeight + popupOffsetY;
	popupDivObj.style.left = MAX(desiredx, 0);
	popupDivObj.style.top = MAX(desiredy, 0)
	popupDivObj.style.visibility = "visible";
	// Select *after* popping up to get IE to make selection visible.
	if(popupFormObj)
		for(a = 0; a < popupSelectObj.options.length; a++)
			if(popupSelectObj.options[a].text.toLowerCase() == popupFormObj.value.toLowerCase()) {
//				popupSelectObj.selectedIndex = a;
				setTimeout("popupSelectObj.selectedIndex = " + a, 10);
				break;
			}
	popupSelectObj.focus();
	popupOffsetX = popupOffsetY = 0;	// Reset offset
	return false;
}

// popupHide()
//		Call to hide the current <div> block immediately.
function popupHide()
{
	if(popupDivObj) {
		popupDivObj.style.visibility = "hidden";
		popupDivObj.style.left = 0;	// Move back to (0, 0) so browsers dont include
		popupDivObj.style.top = 0;	// hidden <div> in scrollbar page size calculations.
		popupDivObj = 0;
	}
}

// popupOnChange()
//		Copys the changed value to the form object
function popupOnChange()
{
	if(popupFormObj) popupFormObj.value = popupSelectObj.value;
}

// popupOnClick()
//		Ends the popup, refocusing the another object.
function popupOnClick()
{
	popupHide();
	if(popupFormObj) popupFormObj.focus();
	popupOnClickSetFocus = true;
}

// popupOnBlur()
//		Hide the popup immediately
function popupOnBlur()
{
	popupHide();
	if(popupFormObj) popupFormObj.focus();
}
