function doDirtyPage(obj){
	obj.className = "ChangedEntry";
	if(typeof(blnIsPageDirty) == "undefined")
		alert("You must define a variable called 'blnIsPageDirty'");
	else
		blnIsPageDirty = true;
}

function doConfirmPageDirty(){
	if(blnIsPageDirty)
		return confirm("You have unsaved changes. Press OK to discard those changes. Press cancel to return to the page.");
	else{
		// confirms that the window should be close, hence the value true		
		return true;
	}
}

function isDialogWindow(){
	if(typeof(window.opener) != "undefined")
		return false;
	else if(typeof(window.dialogHeight) == "undefined")
		return false;
	else
		return true;
}
function doViewImages(){
	szPage = "view_images_frame.php";
	if(typeof(window.showModalDialog) == "undefined"){
		window.open(szPage, "ViewImages", "height=630,width=780,left=100,top=100,resizable=no,scrollbars=no,toolbar=no,status=no");
	} else {
		var intResponse = window.showModalDialog(szPage,"ClientOrder","dialogHeight: 630px; dialogWidth: 800px; edge: Raised; center: Yes; help: Yes; resizable: no; status: yes;");
		if(intResponse > 0)
			doReload();
	}
}

function doResizeFrame(szFrameID, intMinSize) {
	var oFrame = parent.frames[szFrameID];
	if (typeof oFrame == 'undefined') 
		oFrame = document.frames[szFrameID];

	if (typeof oFrame != 'undefined') {
		intHeight =  document.body && document.body.scrollHeight? oFrame.document.body.scrollHeight : oFrame.document.height? oFrame.document.height : null;
		if (intHeight) {
			if(intMinSize && intHeight < intMinSize)
				intHeight = intMinSize;
			oFrame.resizeTo(parent.document.getElementById(szFrameID).offsetWidth, intHeight); 
		} else {
			setTimeout("doResizeFrame('" + szFrameID + "', " + intMinSize + ")", 1000);
		}
	} 
}

function doClientSearch(blnIndividualOnly, szSearch){
	szParams = "blnIndividualOnly=" + blnIndividualOnly;
	if(typeof(szSearch) != "undefined"){
		szParams += "&szSearch=" + szSearch;
	}
	szPage = "../search/client_search_frame.php?" + szParams;
	if(typeof(window.showModalDialog) == "undefined"){
		window.open(szPage, "ProjectSearch", "height=540,width=850,left=100,top=100,resizable=no,scrollbars=no,toolbar=no,status=no");
	} else {
		var szResponse = window.showModalDialog(szPage, "","dialogHeight: 540px; dialogWidth: 850px; edge: Raised; center: Yes; help: Yes; resizable: yes; status: yes;");
		doSearchClientCallback(szResponse);
	}
}

function doProjectSearch(szSearch){
	szParams = '';
	if(typeof(szSearch) != "undefined"){
		szParams = "&szSearch=" + szSearch;
	}

	szPage ="../search/project_search_frame.php?" + szParams;
	if(typeof(window.showModalDialog) == "undefined"){
		window.open(szPage, "ProjectSearch", "height=600,width=850,left=100,top=100,resizable=no,scrollbars=no,toolbar=no,status=no");
	} else {
		var szResponse = window.showModalDialog(szPage, "","dialogHeight: 600px; dialogWidth: 850px; edge: Raised; center: Yes; help: Yes; resizable: yes; status: yes;");
		doSearchProjectCallback(szResponse);
	}
}

// Cancel the popup help screen
document.onhelp = function () {
    showHotKeys();
	return false;
}

function showHotKeys(){
	window.showModalDialog("../admin/hot_keys.php", "Shortcut keys", "dialogHeight: 350px; dialogWidth: 550px; edge: Raised; center: Yes; help: Yes; resizable: no; status: no;");
}

function doHotKeys() {
	blnFound = false;

	if(top)
		oMain = window.top;
	else
		oMain = window.top;

	switch(event.keyCode){
		case 13:
			blnFound = true;
			if(document.location.href.indexOf('client_update') > -1)
				doValidate(true);
			break;
		case 27: 
			blnFound = true;
			if(typeof(doCancel) == 'function')
				doCancel();
			break;
		case 112: 
			blnFound = true;
			break;
		case 115:
			oMain.src = '../html/client_detail.php';
			blnFound = true;
			break;
		case 117:
			blnFound = true;
			if(document.location.href.indexOf('client_update') > -1)
				doAction('INSERTDONATION');
			break;
		case 118:
		case 119:
			if(document.location.href.indexOf('client_update') > -1)
				doAction('INSERTORDER');
			break;
	}
	if(blnFound){
		event.keyCode = 0;
		event.returnValue = false;
		event.cancelBubble = true;
		return false;
	}
}

function doMouseOverSelect(oRow){
	if(oOver)
		oOver.className = 'SelectRow';
	oOver = oRow;
	oRow.className = 'SelectRowMouseOver';
}

function doMouseOutSelect(oRow){
	if(oOver){
		if(oOver == oSelected)
			oOver.className = "SelectedRow"
		else
			oOver.className = 'SelectRow';
	}	
	oOver = null;
}

function getSelected(oList){
	szAddIDs = '';
	szNameList = '';
	if(oList.tagName == "SELECT"){
		for(i=0; i < oList.options.length;i++){
			if(oList.options[i].selected){
				if(szAddIDs.length > 0){
					szAddIDs += ',';
					szNameList += ', ';
				}
				szAddIDs += oList.options[i].value;
				szNameList += oList.options[i].text;
			}
		}
	} else {
		// Process a text entry field
		szNameList = oList.value;
	}
	return szAddIDs;
}

function LTrim(str){
	var whitespace = new String(" \t\n\r");
	var s = new String(str);
	if (whitespace.indexOf(s.charAt(0)) != -1 || s.charCodeAt(0) == 160) {
		var j=0, i = s.length;
		while (j < i && whitespace.indexOf(s.charAt(j)) != -1 || s.charCodeAt(j) == 160)
			j++;
		s = s.substring(j, i);
	}
	return s;
}

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;
}


function Trim(str){
		return RTrim(LTrim(str));
}

function subAwithBinC(a,b,c){

	var i = c.indexOf(a);
	var l = b.length;

	while (i != -1)	{
		c = c.substring(0,i) + b + c.substring(i + a.length,c.length);
		i += l;
		i = c.indexOf(a,i);
	}
	return c;

}

function szFormatMoney(szIn, blnShowDollarSign){

	if(typeof(blnShowDollarSign) =='undefined')
		blnShowDollarSign = true;
	szSign = '';

	if(blnShowDollarSign)
		szSign = '$';

	szMeniscus = '.00';
	szChar = ',';	
	blnIsNegative = false;
	szOutput = '';

	// rounds the number first
	szIn = Math.round(szIn * 100)/100;

	// parses a number and inserts the separation character in the appropriate places.
	szIn = new String(szIn)	
	if(szIn == 'undefined' || szIn == 'null')
		szIn = '0.00';
	if(szIn.substr(0,1) == '-'){
		szIn = szIn.substr(1);
		blnIsNegative = true;
	}
	if(szIn.indexOf('.') > 0){
		szMeniscus = szIn.substr(szIn.indexOf('.'), 3);
		szIn = szIn.substr(0, szIn.indexOf('.'));
	}
	while(szIn.length > 3){
		szOutput =  szChar + szIn.substr(szIn.length - 3) + szOutput;
		szIn = szIn.substr(0, szIn.length - 3);
	}
	szOutput = szIn + szOutput;
	
	if(blnIsNegative)
		return '(' + szSign + szOutput + szMeniscus + ')';
	else
		return szSign + szOutput + szMeniscus;
}


function doUpdateCustomHTML(intActionID, intContentID, intReferenceID){
	szFeatures = 'width=800,height=620,left=100,top=60,screenX=100,screenY=60,status=no,menubar=no,resizable=no,toolbar=no,scrollbars=no';
	myWindow = window.open('custom_page.asp?szCommand=SHOWUPDATE&intContentID=' + intContentID + '&intReferenceID=' + intReferenceID, 'winHTMLUpdate', szFeatures);
	myWindow.focus();
}


function getDOMObject(szName){
	return eval('document.all.' +szName);
	if (oObject != null){
	   if (oObject.length > 0){
		 return oObject(0);
	   } else 
		  return oObject;
	} 
	return null
}

function doListMove(lstSource, lstDest){
	// ===============================
	// * Moves 0 or more items from the source list to a sorted position in the dest list. 
	// * Returns a comma seperated string of the IDs of the items that were moved.
	// * 
    // * lstSource: The object reference to the source list 
	// * lstDest: The object reference to the dest list
	// ===============================
	delArray = new Array;
	x=0;
	for(i=0; i < lstSource.options.length; i++){
		if(lstSource.options[i].selected){
			blnIsSelection = true;
			var optNew = new Option(lstSource.options[i].text, lstSource.options[i].value, false, false);
			delArray[x++] = lstSource.options[i].value;

			//Sort the list.
			j = lstDest.options.length - 1;
			while(j > -1 && optNew.text <= lstDest.options[j].text ){
				var optSwap = new Option(lstDest.options[j].text, lstDest.options[j].value, false, false);
				lstDest.options[j+1] = optSwap;
				j--;
			}
			lstDest.options[j+1] = optNew;
		}
	}

	for(i=0; i<delArray.length;i++){
		for(j=0; j < lstSource.options.length; j++){
			if(lstSource.options[j].value == delArray[i])
				lstSource.options[j] = null;
		}
	}
	return delArray.toString();
}


function resizeImage(szImg, intSize){
	oImg = document.getElementById(szImg);
	if(intSize == null)	
		intSize = '';
	if(!oImg)
		return false;

	h = parseInt(oImg.height);
	w = parseInt(oImg.width);
	if(h == 0 || w == 0){
		setTimeout('resizeImage("' + szImg + '", ' + intSize + ')', 1000)
		return false;
	}

	if(h > w && h > intSize){
		intProportion = w/h;
		oImg.height = intSize;
		oImg.width = parseInt(intSize * intProportion);
	} else if(w > intSize) {
		intProportion = h/w;
		oImg.width = intSize;
		oImg.height = parseInt(intSize * intProportion);
	}
}

function szMonthName(InValue){
	// Changed to return short month...
	return szShortMonthName(InValue);

	switch(InValue){
	case 1: return 'January';
	case 2: return 'February';
	case 3: return 'March';
	case 4: return 'April';
	case 5: return 'May';
	case 6: return 'June';
	case 7: return 'July';
	case 8: return 'August';
	case 9: return 'September';
	case 10: return 'October';
	case 11: return 'November';
	case 12: return 'December';
	}
}

function szShortMonthName(InValue){
	switch(InValue){
	case 1: return 'Jan';
	case 2: return 'Feb';
	case 3: return 'Mar';
	case 4: return 'Apr';
	case 5: return 'May';
	case 6: return 'Jun';
	case 7: return 'Jul';
	case 8: return 'Aug';
	case 9: return 'Sep';
	case 10: return 'Oct';
	case 11: return 'Nov';
	case 12: return 'Dec';
	}
}

function szFormatShortDate(szInDate) {
	if (szInDate!=null && szInDate != 'null' && szInDate != ''){
		var dtNew = new Date(szInDate);
		return szShortMonthName(dtNew.getMonth() + 1) + ' ' + dtNew.getDate() + ', ' + dtNew.getFullYear();
	}
	else
		return '';
}

function szFormatDate(szInDate) {
	if (szInDate!=null && szInDate != 'null' && szInDate != ''){
		szInDate = String(szInDate);
		if(szInDate.indexOf("-") > -1)
			szInDate = subAwithBinC("-", ",", szInDate)
		arDate = szInDate.split(",");
		// Reverse the date into a format mm/dd/yyyy
		if(arDate[0] && String(arDate[0]).length == 4)
			szInDate = arDate[1]  + "/" + arDate[2] + "/" + arDate[0];

		var dtNew = new Date(szInDate);
		return szMonthName(dtNew.getMonth() + 1) + ' ' + dtNew.getDate() + ', ' + dtNew.getFullYear();
	}
	else
		return '';
}

function szFormatDateTime(szInDate) {
	if (szInDate!=null && szInDate != 'null' && szInDate != ''){
		var dtNew = new Date(szInDate);
		h = parseInt(dtNew.getHours())
		if(h > 0)
			return szFormatDate(szInDate) + ' ' + dtNew.getHours() + ':' + dtNew.getMinutes();
		else
			return szFormatDate(szInDate);
		}
	else
		return '';
}

function getFloatFromMoney(szValue){
	szValue = String(szValue);
	szValue = szValue.replace(',', '');
	szValue = szValue.replace(' ', '');
	return parseFloat(szValue);
}

/* This function validates that the input passed in is of the required type. 
 * Parameters:
 * szInput		-	the value to be validated	(Required)
 * intMinLength	-	the minimum length			(default 0) 
 *					if > 0
 *					the field is required
 * intMaxLength	-	the maximum length for		(default 0) 
 *					string type only
 * returns:		-	true if valid, false otherwise. 
 *					Set the fields on oValidation as appropriate
 */

oValidation = new Object;
oValidation.isTooShort = false;
oValidation.isTooLong = false;
oValidation.isWrongType = false;
oValidation.szTypeMessage = '';

function isValid(szInput, szType, szFieldName, blnShowMessages, intMinLength, intMaxLength){
	oValidation.isTooShort = false;
	oValidation.isTooLong = false;
	oValidation.isWrongType = false;
	oValidation.szTypeMessage = '';

	switch(szType){
		case 'DATE':
			isValidDate(szInput, intMinLength);
			break;
		case 'INTEGER':
			isValidInteger(szInput, intMinLength, intMaxLength);
			break;
		case 'MONEY':
			szInput = getFloatFromMoney(szInput);
			isValidFloat(szInput, intMinLength, intMaxLength);
			break;
		case 'FLOAT':
			isValidFloat(szInput, intMinLength, intMaxLength);
			break;
		case 'NAME':
			isValidName(szInput, intMinLength, intMaxLength)
			break;
		case 'EMAIL':
			isValidEmail(szInput, intMinLength, intMaxLength)
			break;
		case 'TELEPHONE':
			isValidTelephone(szInput, intMinLength)
			break;
		case 'SEARCH':
			isValidSearch(szInput)
			break;
		case 'TEXT':
			isValidText(szInput, intMinLength, intMaxLength)
			break;
		case 'XMLTEXT':
			isValidXMLText(szInput, intMinLength, intMaxLength)
			break;
		case 'URL':
			isValidURL(szInput, intMinLength, intMaxLength)
			break;
		case 'CSS':
			break;
		case 'HTML':
			break;
		case 'HTMLWITHSCRIPT':
			break;
		default:
			alert('You have passed in an incorrect type.');
			oValidation.isTooShort = true;
			oValidation.isTooLong = true;
			oValidation.isWrongType = true;
	}
	//return the default error messages if required.
	if(blnShowMessages && (oValidation.isTooShort || oValidation.isTooLong ||
			oValidation.isWrongType)){
		szMsg = '';
		if (szFieldName && szFieldName != '')
			szMsg = '<B>' + szFieldName + '</B>: ';
		if (szType == "INTEGER" || szType == "FLOAT") {
			if(oValidation.isTooShort || oValidation.isTooLong)
				if(intMinLength && intMaxLength)
					szMsg += 'Please enter a number between ' + intMinLength + ' and ' + intMaxLength + '.<BR>';
				else
					szMsg += 'You must enter a value for this field.<BR>';

		} else {
			if(oValidation.isTooShort){
				if(intMinLength == 0)
					szMsg += 'You must enter a value.<BR>';
				else if(intMinLength == 1)
					szMsg += 'You must enter a value for this field.<BR>'
				else
					szMsg += 'The value must be at least ' + intMinLength + ' characters in length.<BR>'
			}
			if(oValidation.isTooLong){
				szMsg += 'The value cannot be longer that ' + intMaxLength + ' characters in length.<BR>'
			}
		}
		if(oValidation.isWrongType){
			szMsg += oValidation.szTypeMessage + '<BR>'
		}
		oErrMessages = getElement('oErrorMessages');
		oErrDisplay = getElement('oErrorDisplay');
		oErrMessages.innerHTML += szMsg;
		oErrDisplay.style.display = 'inline';
	}
	return 	!(oValidation.isTooShort || oValidation.isTooLong || oValidation.isWrongType)
}

function getFormValue(szFormValue, szForm){
	if(szFormValue == '' || szFormValue == 'null'){
		alert('You have not specified a form value.');
		return false;
	}
	var szReturn = null;
	if(szForm == null)
		szForm = 'frmMain'
	try{
		szReturn = eval('document.' + szForm + '.' + szFormValue + '.value');
	} catch(frmErr){
		alert('The form value: document.' + szForm + '.' + szFormValue + '.value was not found.');
		return false;
	}
	return szReturn;
}

function isValidDate(szDate, intMinLength){
	szDate = Trim(szDate);
	if(intMinLength > 0 && szDate.length ==0)
		oValidation.isTooShort = true;
}

function isValidName(szName, intMinLength, intMaxLength){
	szName = Trim(szName);
	var re = /[^a-zA-Z\s\'-]/
	if(re.test(szName)){
		oValidation.isWrongType = true;
		oValidation.szTypeMessage = 'This field can only contain letters, a single quote, and the hyphen.'
	}
	if(intMinLength && szName.length < intMinLength)
		oValidation.isTooShort = true;
	if(intMaxLength > 0 && szName.length > intMaxLength)
		oValidation.isTooLong = true;
}

function isValidURL(szURL, intMinLength, intMaxLength){
	szURL = Trim(szURL);
	if (szURL.indexOf("http") > -1 && szURL.indexOf("http://") == -1) {
		oValidation.isWrongType = true;
		oValidation.szTypeMessage = 'A valid URL must begin with "http://".';
	} else {
		var re = /[^a-zA-Z\s\d\.:+\_\-\?\%\&\/\\]/
		if(re.test(szURL)){
			oValidation.isWrongType = true;
			oValidation.szTypeMessage = 'This field can only contain valid URL characters.'
		}
		if(intMinLength && szURL.length <= intMinLength)
			oValidation.isTooShort = true;
		if(intMaxLength > 0 && szURL.length > intMaxLength)
			oValidation.isTooLong = true;
	}
}

function isValidSearch(szSearch){
	szName = Trim(szSearch);
	var re = /[^a-zA-Z\"\s\d\*]/
	if(re.test(szSearch)){
		oValidation.isWrongType = true;
		oValidation.szTypeMessage = 'The search string can only contain letters and numbers and the * character.'
	}
}

function isValidEmail(szEmail, intMinLength, intMaxLength){
	szEmail = Trim(szEmail);
	if((String(intMinLength) == 'undefined' || intMinLength == 0) && szEmail.length == 0)
		return true;
	else {
		if (szEmail.indexOf(",") > -1)
			arrEmail = szEmail.split(",");
		else
			arrEmail = szEmail.split(";");
		var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
		for (key in arrEmail) {
			szEmail = Trim(arrEmail[key]);
			if(!re.test(szEmail)){
				oValidation.isWrongType = true;
				oValidation.szTypeMessage = 'This field must contain a valid email address.';
				break;
			}
		}
	}
}


function isValidTelephone(szNumber, intMinLength){
	szNumber= Trim(szNumber);
	var re = /[^\s\d()-]/
	if(szNumber.length > 0 && re.test(szNumber)){
		oValidation.isWrongType = true;
		oValidation.szTypeMessage = 'Telphone numbers can only contain numbers and (, ), -.'
	}

	if(intMinLength && szNumber.length < intMinLength)
		oValidation.isTooShort = true;
}

function isValidFloat(szFloat, intMinLength, intMaxLength){
	var re = /^[-+]?\d+(\.\d+)?$/
	if(re.test(szFloat)){
		;
	} else {
		oValidation.isWrongType = true;
		oValidation.szTypeMessage = 'This field must contain a valid number.'
	}
	if (!oValidation.isWrongType) {
		if(intMinLength && szFloat < intMinLength)
			oValidation.isTooShort = true;
		if(intMaxLength > 0 && szFloat > intMaxLength)
			oValidation.isTooLong = true;
	}
}

function isValidInteger(szInteger, intMinLength, intMaxLength){
	var re = /[^\d]/
	if(re.test(szInteger) || isNaN(parseInt(szInteger))){
		oValidation.isWrongType = true;
		oValidation.szTypeMessage = 'This field must contain a valid integer.'
	}
	if(intMinLength && parseInt(szInteger) < intMinLength)
		oValidation.isTooShort = true;
	if(intMaxLength > 0 && parseInt(szInteger) > intMaxLength)
		oValidation.isTooLong = true;
}

function isValidText(szText, intMinLength, intMaxLength){
	szText = Trim(szText);
	var re = /[^\w\s\'\",.?:;\\\(\)\-\+\=\\[\]&\*\%\$\#\@\<\>\!\@\/]/
	if(re.test(szText)){
		oValidation.isWrongType = true;
		oValidation.szTypeMessage = 'This field can only contain letters, numbers and some special characters.'
	}
	if(intMinLength && szText.length < intMinLength)
		oValidation.isTooShort = true;
	if(intMaxLength > 0 && szText.length > intMaxLength)
		oValidation.isTooLong = true;
}

function isValidXMLText(szXMLText, intMinLength, intMaxLength){
	szXMLText = Trim(szXMLText);
	var re = /[^\w\s\'\",.?:;\!]/
	if(re.test(szXMLText)){
		oValidation.isWrongType = true;
		oValidation.szTypeMessage = 'This field can only contain letters, numbers and some special characters.'
	}
	if(intMinLength && szXMLText.length <= intMinLength)
		oValidation.isTooShort = true;
	if(intMaxLength > 0 && szXMLText.length > intMaxLength)
		oValidation.isTooLong = true;
}

function clearErrors(){
	oErrDiv = getElement('oErrorMessages');
	oErrDisplay = getElement('oErrorDisplay');
	if(oErrDiv) {
		oErrDiv.innerHTML = '';
		oErrDisplay.style.display = 'none';
	} else
		alert('The error div does not exist.');
}

function checkForErrors(){
	oErrDiv = getElement('oErrorMessages');
	if(oErrDiv)
		return oErrDiv.innerHTML.length > 0;
	else
		alert('The error div does not exist.');
}

function addError(szError, szFieldName){
	oErrDiv = getElement('oErrorMessages');
	oErrDisplay = getElement('oErrorDisplay');

	if(!szError || szError == '')
		alert('You have not passed an error message to this function.')
	else {
		if(oErrDiv){
			if (szFieldName && szFieldName != '')
				oErrDiv.innerHTML += '<B>' + szFieldName + '</B>: ';
			oErrDiv.innerHTML += szError + '<BR>';
			oErrDisplay.style.display = 'inline';
		} else
			alert('The error div does not exist.');
		
	}
}

// ******************************************************************
// Start of Credit card validation

var Cards = new makeArray(8);
Cards[0] = new CardType("Mastercard", "51,52,53,54,55", "16");
var Mastercard = Cards[0];
Cards[1] = new CardType("Visa", "4", "13,16");
var Visa = Cards[1];
Cards[2] = new CardType("Amex", "34,37", "15");
var Amex = Cards[2];
Cards[3] = new CardType("DinersClubCard", "30,36,38", "14");
var DinersClubCard = Cards[3];
Cards[4] = new CardType("DiscoverCard", "6011", "16");
var DiscoverCard = Cards[4];
Cards[5] = new CardType("enRouteCard", "2014,2149", "15");
var enRouteCard = Cards[5];
Cards[6] = new CardType("Bank Card", "", "16");
var JCBCard = Cards[6];
var LuhnCheckSum = Cards[7] = new CardType();

function isValidCC(oCCTypeList, szCardNumber, szCardExpiryDate, blnRequired) {
	// Get the card type...
	szCardType = oCCTypeList.options[oCCTypeList.selectedIndex].text;
	if(oCCTypeList.value == 0 && (szCardNumber.length > 0 || szCardExpiryDate.length > 0)){
		addError('Please select a credit card type.', 'Credit card');
		return false;
	} else {
		if(szCardNumber.length > 0 || oCCTypeList.value > 0 || szCardExpiryDate.length > 0)
			blnRequired = true;
	}

	if(!blnRequired && szCardNumber.length == 0)
		return true;

	if (szCardExpiryDate.length == 0) {
		addError('Please enter an expiry date.', 'Expiry date')
		return false;
	}
	
	// We do not validate card of type bank card...
	if(szCardType == 'Bank card')
		return true;
	// Do not validate the expiry date if the expiry date is set to DONOTVALIDATE
	if(szCardExpiryDate != 'DONOTVALIDATE'){
		szExpiryYear  = szCardExpiryDate.substr(szCardExpiryDate.indexOf('/') + 1);
		szExpiryMonth = szCardExpiryDate.substr(0, 2);
		var tmpyear;
		if (szExpiryYear > 96)
			tmpyear = "19" + szExpiryYear;
		else if (szExpiryYear < 21)
			tmpyear = "20" + szExpiryYear;
		else {
			addError('The Expiration Year is not valid.', 'Expiry date')
			return;
		}
		tmpmonth = szExpiryMonth;
		if (!(new CardType()).isExpiryDate(tmpyear, tmpmonth)) {
			addError('The card has already expired.', 'Expiry date')
			return;
		}
	} else {
		tmpmonth = "1";
		tmpyear = "2099";
	}

	var retval = eval(szCardType + ".checkCardNumber(\"" + szCardNumber + "\", " + tmpyear + ", " + tmpmonth + ");");
	cardname = "";
	if (retval)
		return true;
	else {
		// The cardnumber has the valid luhn checksum, but we want to know which
		// cardtype it belongs to.
		for (var n = 0; n < Cards.size; n++) {
			if (Cards[n].checkCardNumber(szCardNumber, tmpyear, tmpmonth)) {
				cardname = Cards[n].getCardType();
				break;
		   }
		}
		if (cardname.length > 0) {
			addError("This looks like a " + cardname + " number, not a " + szCardType + " number.", 'Credit card')
		}else {
			addError('This card number is not valid.', 'Credit card')
		}
	}
}
/*************************************************************************\
Object CardType([String cardtype, String rules, String len, int year, 
                                        int month])
cardtype    : type of card, eg: MasterCard, Visa, etc.
rules       : rules of the cardnumber, eg: "4", "6011", "34,37".
len         : valid length of cardnumber, eg: "16,19", "13,16".
year        : year of expiry date.
month       : month of expiry date.
eg:
var VisaCard = new CardType("Visa", "4", "16");
var AmExCard = new CardType("AmEx", "34,37", "15");
\*************************************************************************/
function CardType() {
	var n;
	var argv = CardType.arguments;
	var argc = CardType.arguments.length;

	this.objname = "object CardType";

	var tmpcardtype = (argc > 0) ? argv[0] : "CardObject";
	var tmprules = (argc > 1) ? argv[1] : "0,1,2,3,4,5,6,7,8,9";
	var tmplen = (argc > 2) ? argv[2] : "13,14,15,16,19";

	this.setCardNumber = setCardNumber;  // set CardNumber method.
	this.setCardType = setCardType;  // setCardType method.
	this.setLen = setLen;  // setLen method.
	this.setRules = setRules;  // setRules method.
	this.setExpiryDate = setExpiryDate;  // setExpiryDate method.

	this.setCardType(tmpcardtype);
	this.setLen(tmplen);
	this.setRules(tmprules);
	if (argc > 4)
	this.setExpiryDate(argv[3], argv[4]);

	this.checkCardNumber = checkCardNumber;  // checkCardNumber method.
	this.getExpiryDate = getExpiryDate;  // getExpiryDate method.
	this.getCardType = getCardType;  // getCardType method.
	this.isCardNumber = isCardNumber;  // isCardNumber method.
	this.isExpiryDate = isExpiryDate;  // isExpiryDate method.
	this.luhnCheck = luhnCheck;// luhnCheck method.
	return this;
}

/*************************************************************************\
boolean checkCardNumber([String cardnumber, int year, int month])
return true if cardnumber pass the luhncheck and the expiry date is
valid, else return false.
\*************************************************************************/
function checkCardNumber() {
	var argv = checkCardNumber.arguments;
	var argc = checkCardNumber.arguments.length;
	var cardnumber = (argc > 0) ? argv[0] : this.cardnumber;
	var year = (argc > 1) ? argv[1] : this.year;
	var month = (argc > 2) ? argv[2] : this.month;

	this.setCardNumber(cardnumber);
	this.setExpiryDate(year, month);

	if (!this.isCardNumber())
		return false;
	if (!this.isExpiryDate())
		return false;

	return true;
}
/*************************************************************************\
String getCardType()
return the cardtype.
\*************************************************************************/
function getCardType() {
	return this.cardtype;
}
/*************************************************************************\
String getExpiryDate()
return the expiry date.
\*************************************************************************/
function getExpiryDate() {
	return this.month + "/" + this.year;
}
/*************************************************************************\
boolean isCardNumber([String cardnumber])
return true if cardnumber pass the luhncheck and the rules, else return
false.
\*************************************************************************/
function isCardNumber() {
	var argv = isCardNumber.arguments;
	var argc = isCardNumber.arguments.length;
	var cardnumber = (argc > 0) ? argv[0] : this.cardnumber;
	if (!this.luhnCheck())
		return false;

	for (var n = 0; n < this.len.size; n++)
	if (cardnumber.toString().length == this.len[n]) {
		for (var m = 0; m < this.rules.size; m++) {
			var headdigit = cardnumber.substring(0, this.rules[m].toString().length);
			if (headdigit == this.rules[m])
				return true;
		}
		return false;
	}
	return false;
}

/*************************************************************************\
boolean isExpiryDate([int year, int month])
return true if the date is a valid expiry date,
else return false.
\*************************************************************************/
function isExpiryDate() {
	var argv = isExpiryDate.arguments;
	var argc = isExpiryDate.arguments.length;

	year = argc > 0 ? argv[0] : this.year;
	month = argc > 1 ? argv[1] : this.month;

	if (!isNum(year+""))
		return false;
	if (!isNum(month+""))
		return false;
	today = new Date();
	today = new Date(today.getYear(), today.getMonth());

	expiry = new Date(year, month);
	if (today.getTime() > expiry.getTime())
		return false;
	else
		return true;
}

/*************************************************************************\
boolean isNum(String argvalue)
return true if argvalue contains only numeric characters,
else return false.
\*************************************************************************/
function isNum(argvalue) {
	argvalue = argvalue.toString();

	if (argvalue.length == 0)
		return false;

	for (var n = 0; n < argvalue.length; n++)
	if (argvalue.substring(n, n+1) < "0" || argvalue.substring(n, n+1) > "9")
		return false;

	return true;
}

/*************************************************************************\
boolean luhnCheck([String CardNumber])
return true if CardNumber pass the luhn check else return false.
Reference: http://www.ling.nwu.edu/~sburke/pub/luhn_lib.pl
\*************************************************************************/
function luhnCheck() {
	var argv = luhnCheck.arguments;
	var argc = luhnCheck.arguments.length;

	var CardNumber = argc > 0 ? argv[0] : this.cardnumber;

	if (! isNum(CardNumber)) {
		return false;
	}

	var no_digit = CardNumber.length;
	var oddoeven = no_digit & 1;
	var sum = 0;

	for (var count = 0; count < no_digit; count++) {
		var digit = parseInt(CardNumber.charAt(count));
		if (!((count & 1) ^ oddoeven)) {
			digit *= 2;
			if (digit > 9)
				digit -= 9;
		}
		sum += digit;
	}
	if (sum % 10 == 0)
		return true;
	else
		return false;
}

/*************************************************************************\
ArrayObject makeArray(int size)
return the array object in the size specified.
\*************************************************************************/
function makeArray(size) {
	this.size = size;
	return this;
}

/*************************************************************************\
CardType setCardNumber(cardnumber)
return the CardType object.
\*************************************************************************/
function setCardNumber(cardnumber) {
	this.cardnumber = cardnumber;
	return this;
}

/*************************************************************************\
CardType setCardType(cardtype)
return the CardType object.
\*************************************************************************/
function setCardType(cardtype) {
	this.cardtype = cardtype;
	return this;
}

/*************************************************************************\
CardType setExpiryDate(year, month)
return the CardType object.
\*************************************************************************/
function setExpiryDate(year, month) {
	this.year = year;
	this.month = month;
	return this;
}

/*************************************************************************\
CardType setLen(len)
return the CardType object.
\*************************************************************************/
function setLen(len) {
	// Create the len array.
	if (len.length == 0 || len == null)
	len = "13,14,15,16,19";

	var tmplen = len;
	n = 1;
	while (tmplen.indexOf(",") != -1) {
		tmplen = tmplen.substring(tmplen.indexOf(",") + 1, tmplen.length);
		n++;
	}
	this.len = new makeArray(n);
	n = 0;
	while (len.indexOf(",") != -1) {
		var tmpstr = len.substring(0, len.indexOf(","));
		this.len[n] = tmpstr;
		len = len.substring(len.indexOf(",") + 1, len.length);
		n++;
	}
	this.len[n] = len;
	return this;
}

/*************************************************************************\
CardType setRules()
return the CardType object.
\*************************************************************************/
function setRules(rules) {
	// Create the rules array.
	if (rules.length == 0 || rules == null)
	rules = "0,1,2,3,4,5,6,7,8,9";
	  
	var tmprules = rules;
	n = 1;
	while (tmprules.indexOf(",") != -1) {
		tmprules = tmprules.substring(tmprules.indexOf(",") + 1, tmprules.length);
		n++;
	}
	this.rules = new makeArray(n);
	n = 0;
	while (rules.indexOf(",") != -1) {
		var tmpstr = rules.substring(0, rules.indexOf(","));
		this.rules[n] = tmpstr;
		rules = rules.substring(rules.indexOf(",") + 1, rules.length);
		n++;
	}
	this.rules[n] = rules;
	return this;
}
// End of CC validation
// **************************************************************************


function showParamWindow(szURL){
	szFeatures = 'width=600,height=542,left=140,top=150,status=no,menubar=no,resizable=no,toolbar=no';
	myWindow = window.open(szURL, 'winParamDetail', szFeatures);
	myWindow.focus();
}


function getElement(id){
	if(document.getElementById != null){
		return document.getElementById(id);
	} 
	if(document.all != null){
		return document.all[id];
	}
	if(document.layers != null){
		return document.layers[id];
	}
	return null;
}


function addToExisting(szValue, szSpacer){
	if(szValue != ''){
		return szSpacer  + szValue ;
	} else
		return '';
}

function addName(szName, szInitial){
	if(szName != '')
		return szName;
	else
		return szInitial;
}

function getPrintName(szLast, szFirst, szInitial, szTitle1, isIndividual, szLast2, szFirst2, szInitial2, szTitle2){
	szName = '';

	// Return the organisations name
	if(isIndividual == 0){
		return szLast;
	} else {
		if(szTitle1 != '')
			szName += szTitle1;

		if(szLast2 == ''){
			// There is no other lastname
			if(szInitial2 != ''){
				szName += addToExisting(addName(szInitial, szFirst), ' ');
				if(szTitle2 != '' ){
					szName += addToExisting(szTitle2, ' &amp; ');
					szName += addToExisting(addName(szInitial2, szFirst2), ' ');
				} else {
					szName += addToExisting(addName(szInitial2, szFirst2), ' &amp; ');
				}

			} else {
				szName += addToExisting(addName(szInitial, szFirst), ' ');
				szName += addToExisting(addName(szInitial2, szFirst2), ' &amp; ');	
			}	
			szName += addToExisting(szLast, ' ');
		} else{
			szName += addToExisting(addName(szFirst, szInitial), ' ');
			szName += addToExisting(szLast, ' ');
			if(szInitial2 != ''){
				szName += addToExisting(szTitle2, ' &amp; ');
				szName += addToExisting(addName(szFirst2, szInitial2),' ');
			} else {
				szName += addToExisting(addName(szFirst2, szInitial2), ' &amp; ');
			}
			szName += addToExisting(szLast2, ' ');
		}
	}
	return szName.replace('&amp;', '&');
}