// add the current page to favourites page title unless a substitute is supplied
function addToFavorite( favTitle ){
   if ((navigator.appVersion.indexOf("MSIE") > 0) && (parseInt(navigator.appVersion) >= 4)) {
      ft = (favTitle) ? favTitle : document.title;
      window.external.AddFavorite(location.href, unescape(ft));
   }
}

// call from the onsubmit event to display the contents of the form in an alert box, returning false unless true is specified
// e.g. onsubmit="return showFormElements( this )"
function showFormElements( oForm ){
	els = oForm.elements;
	txt = 'FORM ' + oForm.name + " (" + els.length + " element" + ((els.length>1) ? "s" : "") + ")\n\n";
	for (var x=0; x<els.length; x++){
		txt += els[x].name + " = " + els[x].value + "\n";
		}
  txt += "\nClicking OK to submit form, CANCEL to, well, cancel";

	return confirm(txt);
}

// this lot will allow a field to be cleared when it it receives the focus for the first time (ONLY!)
var rClearOnFirstClick = new Array();

function clearOnFirstClick(thisfield) {
	if (!rClearOnFirstClick[thisfield.id]) {
		thisfield.value = "";
		rClearOnFirstClick[thisfield.id]=1;
	}
}

//##################################################     T R I M     F U N C T I O N S     #############################
// remove trailing spaces from a string
function rTrim( strText ) {
strTemp = strText;
while( strTemp.length > 0 && strTemp.charAt(strTemp.length-1)==" " ) {
	strTemp = strTemp.substring(0,strTemp.length-1);
}
return strTemp;
}

// remove leading spaces from a string
function lTrim( strText ) {
strTemp = strText;
while( strTemp.length > 0 && strTemp.charAt(0)==" " ) {
	strTemp = strTemp.substring(1,strTemp.length-1);
}
return strTemp;
}

// remove leading & trailing spaces from a string
function Trim( strText ) {
return lTrim( rTrim( strText ) );
}

//##################################################     T R I M     M E T H O D S     #############################
// http://www.developingskills.com/ds.php?article=jstrim&page=1
function strltrim() {
	//Match spaces at beginning of text and replace with a null string
	return this.replace(/^\s+/,'');
}

function strrtrim() {
	//Match spaces at end of text and replace with a null string
	return this.replace(/\s+$/,'');
}

function strtrim() {
	//Match spaces at beginning and end of text and replace with null strings
	//return this.replace(/^\s+/,'').replace(/\s+$/,'');
	return this.ltrim().rtrim();
}

String.prototype.ltrim = strltrim;
String.prototype.rtrim = strrtrim;
String.prototype.trim  = strtrim;
                  

//##############################################      F O R M     V A L I D A T I O N      ################################

function validateForm( oForm ) {
//  alert( oForm.elements.length );
	ok = true;
	str = "";
	
	// this loop basically checks to see that all required fields have a value in
	for (ii=0;ii<oForm.elements.length;ii++) {
		xx = oForm.elements[ii];

		// this bit changes the class on any description fields for images/thumbs/supers
		if (xx.name && (prefix=xx.name.substr(0,5).toLowerCase()))
			if (prefix == 'image' || prefix == 'thumb' || prefix == 'super') {
				// getting the prefix allows for image10..image999 etc.
				prefix = (pos = xx.name.indexOf('_')) ? xx.name.substr(0,pos) : xx.name;
				if (desc = eval("oForm." + prefix + "Desc"))	{		// e.g. Image1Desc
					desc.className = xx.value ? 'required' : '';
//					alert( desc.name + " class changed to : " + desc.className );
					window.status = desc.name + " class changed to : " + desc.className;
				}
			}
		fldName = (xx.title) ? xx.title : (xx.name) ? xx.name : xx.id;		// use Title, else Name, else Id for alert box
		
		// if field classname says it's a required field
		if (xx.className.substr(0,8) == "required") {

			if (xx.type != "radio") {
				xx.value = xx.value.trim();		// remove leading and trailing spaces
				if (xx.value == "") {
					str += fldName + "\n";
					if (ok) oField = xx;    		// identify first field in error
					ok = false;
	//				alert( fldName + " classname=" + xx.classname + " type=" + xx.type +  " value=" + xx.value + " result=" + ok);
				}
			}	// not radio
		}	// required
	}	// for
		 
	// if all required fields have a value, check to see that it's of the required (!) type
	if (ok) {
		for (ii=0;ii<oForm.elements.length;ii++) {
			xx = oForm.elements[ii];
			fldName = (xx.title) ? xx.title : (xx.name) ? xx.name : xx.id;
			if (xx.value != '') {
				switch( (xx.className.substr(8)).toLowerCase() ) {		// drop off 'required' or 'optional'
					case "n" :
						xx.value = xx.value.replace("%","");					// handle percentages
						xx.value = eval(xx.value.replace(",",""));		// remove commas from numbers
						if (xx.value.match(/^{\d}$/)==null) {
							str += fldName + " must be a valid integer\n";
							if (ok) oField = xx;    		// identify first field in error
							ok = false;
						}
						break;
					case "price" :
						xx.value = xx.value.replace("£","");					// remove pound signs
						xx.value = eval(xx.value.replace(",",""));		// remove commas from numbers
						// match pounds only or pounds and 2 decimal pence
						if (xx.value.match(/^\d+(\.\d{2})?$/) == null) {
							str += fldName + " must be a valid price\n";
							if (ok) oField = xx;    		// identify first field in error
							ok = false;
						}
						break;
					case "file" :
//					allow colons and back slashes through as they'll go during the POST process.
						if (xx.value.match(/^([\w]|[-]|[ ]|[:]|[\\])+\./) == null) {
							str += fldName + " = filename can only contain letters, digits, space, hyphen or underscore\n";
							if (ok) oField = xx;    		// identify first field in error
							ok = false;
						}
						// must END with one of specified document types
						if (xx.value.match(/\.(doc|csv|mdb|pdf|ppt|sfi|xls|zip)+$/) == null) {
							str += fldName + " = filename can only be of the following types : .doc, .csv, .mdb, .pdf, .ppt, .sfi, .xls, .zip\n";
							if (ok) oField = xx;    		// identify first field in error
							ok = false;
						}
						break;
					case "date" :
						// match dates in 1900-2099, no checks on days in month though
						// match 1-9, 01-09 or 10-29, or 30-31, then /, then 1-9, 01-09, or 10-12, then /, then 20, or null, then 00-99
						if ((dtArr = xx.value.match(/^([0]?[1-9]|[1-2][0-9]|[3][0-1])(\/)([0]?[1-9]|[1][0-2])(\/)((19|20)?[0-9][0-9])$/)) != null) {
							dt = new Date();
							if ((dtYear = dtArr[5]).length == 2) dtYear = dt.getFullYear().toString().substr(0,2) + dtYear;
							dtLeap = (dtYear % 4 == 0) && (dtYear % 400 != 0); 
	//						window.status = xx.value + " = " + dtArr + " " + dtLeap;
							switch ( dtArr[3] * 1 ) {		// month entered
								case 4:	case 6: case 9: case 11:
									if (!(ok = (dtArr[1]*1 <= 30))) {
										str += fldName + " must be a valid date\n";
										window.status = xx.value + " is not a valid date [2]";
										oField = xx;				    		// identify first field in error
									}
									break;
								case 2:
									if (!(ok = (dtArr[1]*1 <= (28+dtLeap)))) {
										str += fldName + " must be a valid date\n";
										window.status = xx.value + " is not a valid date [3]";
										oField = xx;				    		// identify first field in error
									}
									break;
								default:
							} // switch							
						}
						else {
							str += fldName + " must be a valid date\n";
							window.status = xx.value + " is not a valid date [1]";
							oField = xx;				    		// identify first field in error
							ok = false;
						}
						break;
					case "date2" :
						// match dates in 2003-9, no checks on days in month though
						// match 1-9, 01-09 or 10-29, or 30-31, then /, then 1-9, 01-09, or 10-12, then /, then 20, or null, then 00-99
						window.status = xx.value + " = " + 
							(xx.value.match(/^([0]?[1-9]|[1-2][0-9]|[3][0-1])(\/)([0]?[1-9]|[1][0-2])(\/)((20)?[0-9][0-9])?$/));
						break;
					default :
				}		// switch
			}
		}	// for
		if (!ok) {
			alert( str += "\nErrors must be corrected before you can update this record" );
			if (oField.type != "hidden")
				oField.focus();   // set focus on first field in error
		}
	}
	else {
		alert( str += "\nmust be entered before you can update this record" );
		if (oField.type != "hidden")
			oField.focus();   // set focus on first field in error
	}

	window.status = "final value WOULD have been : " + ok;
	if (oForm.debug && oForm.debug.value.toLowerCase()=='y')			// if debugging is 'on'
		ok = ok && showFormElements(oForm);		// do whatever user wants to do, if OK

	return ok;											// go ahead and submit
}
