var FLD_UNDEFINED = 0;
var FLD_INTEGER = 3;
var FLD_BOOLEAN = 11;
var FLD_BYTE = 17;
var FLD_DATE = 135;
var FLD_TEXT = 202;
var FLD_MEMO = 203;

var FMT_BOOL_YES_NO = 1;
var FMT_BOOL_TRUE_FALSE = 2;
var FMT_BOOL_YES_NO_UNKNOWN = 3;
var FMT_BOOL_0_1 = 4;
var FMT_BOOL_MSACCESS = 5;
var FMT_BOOL_YES_NO_NO_DETAILS = 6;

var FMT_NULL_BLANK = 1;
var FMT_NULL_NOT_KNOWN = 2;
var FMT_NULL_NBSP = 3;
var FMT_NULL_UNDECIDED = 4;
var FMT_NULL_NO_DETAILS = 5;

var RE_WHITESPACE = /^\s+$/;
var	RE_SPECIAL_CHARS = /[^A-Za-z0-9'., -]+/gi;
var	RE_USER_TEXT_ENTRY_NOT_ALLOWED = /[^\sA-Za-z0-9()/?!\xA3&',.:+@*%;\x22-]/g; // \xA3 = , \x22 = "
var RE_ESCAPE_CHARS = /(['|;|\\])/g;
var RE_QUOTE_TILDE_CARET = /[\"|~|^]/g;
var	RE_BREAK_AND_TABS = /\r\n/gi;
var RE_MONEY = /^((\d+[\,]\d{3})|(\d+))([.]\d{2})*$/;
var RE_CHARS_ONLY = /A-Za-z/;
var RE_NUMBERS_AND_SPACES = /^[ 0-9]*$/
var RE_INTEGER = /d*/;
var RE_NON_ZERO_INTEGER = /[1-9]+[0-9]*/;
var RE_NI_NUMBER = /[A-Za-z]{2}\d{6}[A-Za-z]{1}/;
var RE_VALID_DATE = /^[\d]{2}[\/][\d]{2}[\/][\d]{4}$/;
var RE_UTC_STRING = /\w+\s\w+\s\d+\s\d+[:]\d+[:]\d+\sUTC/i;
var RE_JS_CHARS = /([';\\])/g;

var CLASS_OBJECT = 'Object';
var CLASS_ARRAY = 'Array';
var CLASS_STRING = 'String';
var CLASS_FIELDACTION = 'FieldAction';

var CHAR_RS_NEWLINE = "";

checkRequiredFields = testElements;

function testElements(form, elements)
{
  var errors = '';
	var elements = (!isBlank(elements)) ? elements : form.elements;

  for(var i = 0; i < elements.length; i++) {
		var obj = elements[i];
		if (elementHasVal(obj, form)) {
			if(!isBlank(obj.regExp) && !obj.regExp.test(getElementVal(obj)))
				errors += obj.errorMessage + '\n';
			if (!isBlank(obj.validationFunction)) {
				if (! obj.validationFunction()) {
					errors += (!isBlank(obj.validationFunctionMessage)) ? obj.validationFunctionMessage + '\n' : '';
				}
			}
		}
  	else
			errors += (obj.required == true) ? obj.emptyMessage + '\n' : '';
  }
  return (errors);
}

function setFieldProperties(obj, required, emptyMsg, errorMsg, regExp, source, categoryID, vFuncMsg, vFunc)
{
  obj.required = (!isBlank(required)) ? required : false;
	obj.emptyMessage = (!isBlank(emptyMsg)) ? emptyMsg : '';
	obj.errorMessage = (!isBlank(errorMsg)) ? errorMsg : '';
	obj.regExp = (!isBlank(regExp)) ? regExp : null;
	obj.datasource = (!isBlank(source)) ? source : null;
	obj.categoryID = (!isBlank(categoryID)) ? categoryID : null;
	// Gareth 29 Sept 2003
	// Extending setFieldProperties and testElements to
	// include a validation function
	// new field properties (arguments[7] and arguments[8]) validationFunctionMessage validationFunction
	//obj.validationFunctionMessage = (!isBlank(vFuncMsg)) ? vFuncMsg : null;
	//obj.validationFunction = (!isBlank(vFunc)) ? vFunc : null;
}

function isChanged(form) 
{
	var changed = false;
	var elements = (arguments.length >= 2) ? arguments[1] : form.elements;
	
	for (var i=0; i < elements.length; i++) {
		with (elements[i]) {
			if (type == 'text' || type == 'textarea' || type == 'password' || type == 'file' || type == 'hidden') {
	    		if (value != defaultValue)
						changed = true;
			}	
			else if (type == 'checkbox' || type == 'radio') {
					if (checked != defaultChecked)
						changed = true;
			}
	   		else if (type == 'select-one' || type == 'select-multiple') {
				if (!options[0].selected) {
	    			for (var j=0; j < options.length; j++) {
						if (options[j].selected != options[j].defaultSelected)
	      					changed = true;
	    			}
				}
			}
		}
	}
	return (changed);
}

function addSelectToAllSelects(theForm) {
	for (i = 0; i < theForm.elements.length; i++) {
		if (theForm.elements[i].type == 'select-one') {
			addSelectToSelect(theForm.elements[i]);
		}
	}
}

function addSelectToSelect(theSel) {
	newOption = document.createElement('<OPTION>');
	theSel.options.add(newOption, 0);
	newOption.value = "0";
	newOption.text = "Select...";
}

// Form routines
function joinSubForms(arrHTMLElements) {
	var arrSubForm = new Array();
	for (var i=0; i<arrHTMLElements.length; i++) {
		arrSubForm.concat(subFormArray(arrHTMLElements[i]))
	}
	return(arrSubForm);
}

function subFormArray(HTMLElement) {
	var theAll = (HTMLElement.all) ? HTMLElement.all : document.getElementById(HTMLElement).all;
	var arrSubForm = new Array();
	var j = 0;
	for (var i=0; i<theAll.length; i++) {
		if (theAll(i).tagName == 'INPUT' || theAll(i).tagName == 'SELECT' || theAll(i).tagName == 'TEXTAREA') {
			arrSubForm[j] = theAll(i);
			j++;
		}
	}
	return(arrSubForm);
}

function attachEventsWithinElement(eventName, htmlElementId, functionPointer) {
	// Example usagage: attachEventsWithinElement('onclick', 'SaveButton', onclickSaveButton)
       var arrEls = subFormArray(htmlElementId);
       for (var i = 0; i < arrEls.length; i++) {
           arrEls[i].attachEvent(eventName, functionPointer);
       }
   }
   
function clearVals(elementsArray) {
	//alert('caller\n' + clearVals.caller + '\n' + elementsArray.toString());
	for (var i=0; i<elementsArray.length; i++) {
		obj = elementsArray[i];
		clearVal(obj);
	}
}

function clearVal(obj) {
	if (obj.type == 'checkbox') {
		obj.checked = false;
	} else if (obj.type == 'radio') {
		obj.checked = false;
	} else if (obj.type == 'select-one' || obj.type == 'select-multiple') {
		if (obj.size > 1) {
			obj.selectedIndex = -1;
		} else {
			obj.options[0].selected = true;
		}
	} else if (obj.type == 'hidden' || obj.type == 'text' || obj.type == 'password' || obj.type == 'textarea') {
		obj.value = '';
	} else if (obj.type == 'file') {
		// Only way to clear the value programmatically?
		obj.value = '';
		obj.outerHTML = obj.outerHTML;
	}
}

function clearOrZeroVals(elementsArray) {
	//alert('caller\n' + clearVals.caller + '\n' + elementsArray.toString());
	for (var i=0; i<elementsArray.length; i++) {
		obj = elementsArray[i];
		clearOrZeroVal(obj);
	}
}

function clearOrZeroVal(obj) {
	if (obj.type == 'checkbox') {
		obj.checked = false;
	} else if (obj.type == 'radio') {
		obj.checked = false;
	} else if (obj.type == 'select-one' || obj.type == 'select-multiple') {
		if (obj.size > 1) {
			obj.selectedIndex = -1;
		} else {
			obj.options[0].selected = true;
		}
	} else if (obj.type == 'hidden' || obj.type == 'text' || obj.type == 'password' || obj.type == 'textarea') {
		obj.value = '0';
	} else if (obj.type == 'file') {
		// Only way to clear the value programmatically?
		obj.value = '';
		obj.outerHTML = obj.outerHTML;
	}
}

//end

function Subform(els, msg) 
{
	function validate()
	{
		if (!isChanged(this)) {
			alert(this.errorMsg);
			return (false);
		}
		return (true);	
	}

	this.validate = validate;
	this.elements = els;
	this.errorMsg = msg;
}

function getElement(form, name, index)
{
	for (var i = 0; i < form.elements.length; i++)	{
		if (form.elements[i].name == name) {
			if (typeof(index) != 'number')
				return (form.elements[i]);
			else {
				var radio = getRadioCollection(form.elements[i]);
				return (radio[index]);
			}
		}
	}
	return (null);
}

function elementHasVal(obj, frm)
{
	if (obj.type == 'checkbox')
		return (obj.checked == true);
	else if (obj.type == 'radio') {
		var ri = getRadioIndex(getRadioCollection(obj, frm));
		return (ri != -1 && ri != null);
	}
	else if (obj.type == 'select-one' || obj.type == 'select-multiple') {
		return (obj.selectedIndex > 0);
	}
	else				
		return (!isWhitespace(obj.value));
}

function getElementVal(obj)
{
	if (obj != null) {
		if (obj.type == 'radio') {
			var radio = getRadioCollection(obj);
			for (var i=0; i < radio.length; i++) {
				if (radio[i].checked) 
					return (radio[i].value);
			}
		}
		else if (obj.type == 'checkbox' && obj.checked)
			return (obj.value);
		else if (obj.type == 'select-one' || obj.type == 'select-multiple') {
			if (obj.selectedIndex > -1) {
				return (obj.options[obj.selectedIndex].value);
			}
		}
		else if (obj.type != 'checkbox')
			return (obj.value);
	}
	return (null);
}

function getElementDefaultVal(obj)
{
	if (obj != null) {
		if (obj.type == 'radio') {
			var radio = getRadioCollection(obj);
			for (var i=0; i < radio.length; i++) {
				if (radio[i].defaultChecked) 
					return (radio[i].value);
			}
		}
		else if (obj.type == 'checkbox' && obj.defaultChecked)
			return (obj.value);
		else if (obj.type == 'select-one' || obj.type == 'select-multiple') {
			for (var i=0; i < obj.options.length; i++) {
				if (obj.options[i].defaultSelected == true)
					return (obj.options[i].value);
			}
		}
		else if (obj.type != 'checkbox')
			return (obj.defaultValue);
	}
	return (null);
}

function setElement(obj, val)
{
	val = (isBlank(val)) ? '' : val;
	if (!isBlank(obj)) {
		if (obj.type == 'radio' || obj.type == 'select-one' || obj.type == 'select-multiple') {
			var items = (obj.type == 'radio') ? getRadioCollection(obj) : obj.options;
			var set = false;
			for (var i = 0; i < items.length; i++) {
				var set = (items[i].value.toString() == val.toString());
				(obj.type == 'radio') ? items[i].checked = set : items[i].selected = set;
				if (set)
					return (true);
			}
			return (set);
		}
		else if (obj.type == 'checkbox') {
			obj.checked = (obj.value.toString() == val.toString());
			return (obj.checked);
		}
		else {
			obj.value = val;
			return (true);
		}
	}
	return (false);
}

function setElementDefault(obj, val, set)
{
	if (typeof(val) != 'undefined' && val != null) {
		if (obj.type == 'radio' || obj.type == 'select-one' || obj.type == 'select-multiple') {
			var items = (obj.type == 'radio') ? getRadioCollection(obj) : obj.options;
			var found = false;
			for (var i = 0; i < items.length; i++)
				(obj.type == 'radio') ? items[i].defaultChecked = false : items[i].defaultSelected = false;	
			for (var i = 0; i < items.length; i++) {
				found = (items[i].value.toString() == val.toString());
				(obj.type == 'radio') ? items[i].defaultChecked = found : items[i].defaultSelected = found;
				if (found)
					break;
			}
		}
		else if (obj.type == 'checkbox')
			obj.defaultChecked = (obj.value.toString() == val.toString());
		else
			obj.defaultValue = (val == null) ? '': val;
		if (typeof(set) != 'undefined')
			setElementToDefault(obj);
	}
}

function setElementToDefault(obj)
{
	if (obj.type == 'radio' || obj.type == 'select-one' || obj.type == 'select-multiple') {
		var items = (obj.type == 'radio') ? getRadioCollection(obj) : obj.options;
		for (var i = 0; i < items.length; i++) {
			if (obj.type == 'radio') 
				items[i].checked = items[i].defaultChecked;
			else {
			  items[i].selected = items[i].defaultSelected;
			}
		}	
	}
	else if (obj.type == 'checkbox')
		obj.checked = obj.defaultChecked;
	else
		obj.value = obj.defaultValue;
}

function getSelectText(obj) 
{
	return obj.options[obj.selectedIndex].text;
}

function getIndexInSelectOptions(text, obj) {
	var index = null;
	if (obj.options) {
		for (var i=0; i<obj.options.length; i++) {
			if (obj.options[i].text.toString() == text.toString()) {
				index = i;
				break;
			}
		}
	}
	return index;
}

function getSelectValFromSelectText(text, obj) {
	var index = null;
	if (obj.options) {
		for (var i=0; i<obj.options.length; i++) {
			if (obj.options[i].text == text) {
				index = i;
				break;
			}
		}
	}
	if (index) {
		return obj.options[index].value;
	} else {
		return null;
	}
}

function getSelectTextFromSelectVal(value, obj) {
	var index = null;
	if (obj.options) {
		for (var i=0; i<obj.options.length; i++) {
			if (obj.options[i].value.toString() == value.toString()) {
				index = i;
				break;
			}
		}
	}
	return obj.options[index].text;
}

function getRadioCollection(obj, frm)
{
	var form = (typeof(form) != 'undefined') ? frm : obj.form;
	with (obj.form)
		var radio = eval(obj.name);
	if (typeof(radio.length) == 'undefined')
		radio = [radio];
	return (radio);
}

function getRadioIndex(obj)
{
	var idx = -1;

 	for (var i = 0; i < obj.length; i++) {
 		if (obj[i].checked)
     	idx = i;
	}
	return idx;
}

function initialiseElements(elements, list)
{
	var fields = (isList(list, '~')) ? listToArray(list) : list;
	for (var i = 0; i < fields.length; i++) {
		var field = fields[i]; 
		for (var j = 0; j < elements.length; j++)	{
			if (field[0] == elements[j].name) {
				initialiseElement(elements[j], field[1], field[2]);
				break;
			}
		}
	}
}

function initialiseElement(obj, value, type)
{
	obj.actions = new Array();
	if (obj.type == 'textarea')
		value = reinstateNewLines(value, CHAR_RS_NEWLINE);
	(obj.initialise) ? obj.initialise(value) : setElementDefault(obj, value, true);
	if (isBlank(obj.datatype)) {
		type = (isBlank(type)) ? FLD_UNDEFINED : parseInt(type);
		if (obj.type == 'radio') {
			radio = getRadioCollection(obj);
			for (var i = 0; i < radio.length; i++)
				radio[0].datatype = type;
		}
		else
			obj.datatype = type;
	}
}

function blankElements(elements, toDefault)
{
	for (var i = 0; i < elements.length; i++) {
		blankElement(elements[i], toDefault);
	}
}

function blankElement(element, toDefault)
{
	if (element.type == 'radio') {
		var radio = getRadioCollection(element);
		for (var i = 0; i < radio.length; i++) {
			if (toDefault == true)
				radio[i].defaultChecked = false;
			radio[i].checked = false;
		}
	}
	else if (element.type == 'select-one' || element.type == 'select-multiple') {
		if (toDefault == true)
			element.options[0].defaultSelected = true;
		element.options[0].selected = true;
	}
	else if (element.type == 'checkbox') {
		if (toDefault == true)
			element.defaultChecked = false;
		element.checked = false;
	}
	else if (!(element.type == 'button' || element.type == 'submit' || element.type == 'reset')) {
		if (toDefault == true)
			element.defaultValue = '';
		element.value = '';
	}
}

function resetElements(elements)
{
	for(var i = 0; i < elements.length; i++)
		resetElement(elements[i]);
}

function resetElement(element)
{
	(element.reset) ? element.reset() : setElementToDefault(element);
	element.actions = new Array();
	element.required = false;
}


function getIndexInArray(value, array) {
	var index = null;
	for (i=0; i<array.length; i++) {
		if (array[i] == value) {
			index = i;
			break;
		}
	}
	return index;
}

function isInArray(value, array) {
	for (i=0; i<array.length; i++) {
		if (array[i].toString() == value.toString()) {
			return true;
		}
	}
	return false;
}

function displayArray(fieldArray)
{
	var tempStr = '';
	var i=0;
	for (i=0; i< fieldArray.length; i++)
		tempStr += fieldArray[i][0] + " : " + fieldArray[i][1] + "\n";
	return (tempStr);
}

function list3DArray(arr) {
	// theArray[] is the record row, theArray[][] is thearray for the field, [][][0] is name, [][][1] is value, [][][3] is type
	var i, j = 0;
	var strRow = '';
	var strTemp = '';
	for (i=0;i<arr.length;i++) {
		strRow += '\nrow '+i+'\n';
		for (j=0;j<arr[i].length;j++) {
			strTemp += '          name= '+arr[i][j][0]+' (arr['+i+']['+j+'][0]), value= '+arr[i][j][1]+' (arr['+i+']['+j+'][1]), type= '+arr[i][j][2]+' (arr['+i+']['+j+'][2]).\n';
		}
		strRow += strTemp+'\n';
		strTemp = '';
	}
	return strRow;
}

function arrayToList(array)
{
	var list = "";
	var caret = "";
	
	if (!(array == null))	{
		for (var i = 0; i < array.length; i++) {				// For each element in the 1st dimension of array
			list += caret;																// Create a caret separated item
			tilde = "";
			var itemArray = array[i];
			for (var j = 0; j < itemArray.length; j++) {	// For each element in the 2nd dimension of array
				list += tilde + formatString(itemArray[j]);		// Create a tilde separated item
				tilde = "~";
			}
			caret = "^";
		}
	}
	return (list);
}

function listToRowColPropArray(list, rowSep, colSep, propSep) {
	//var rowSep = '', colSep = '', propSep = '';
	var rows = list.split(rowSep);
	for (var i = 0; i < rows.length; i++) {
		rows[i] = rows[i].split(colSep);
		for (var j = 0; j < rows[i].length; j++) {
			rows[i][j] = rows[i][j].split(propSep);
		}
	}
	return rows;
}

function listToArray(list) 
{
	var record = new Array();

	if (isList(list, '~')) {
		var arr = list.split('^');
		for (var i = 0; i < arr.length; i++) {
			var field = arr[i].split('~');
			record[record.length] = field;
		}
	} 
	return (record);
}

function elementsToArray(elements)
{
	var fields = new Array();
	var previous = '';
	for(var i = 0; i < elements.length; i++) {
		if (elements[i].name != previous) {
			var field = new Array(elements[i].name, getElementVal(elements[i]));
			if (!isBlank(elements[i].datatype))
				field[field.length] = elements[i].datatype;	
			fields[fields.length] = field;
		}
		previous = elements[i].name;
	} 
	return (fields);
}

function elementsToList(elements)
{
	return (arrayToList(elementsToArray(elements)));
}

function resetOptionsWithArray(targetObj, startIdx, twoDArray)
{
	targetObj.length = startIdx;

	for (var i=0; i < twoDArray.length; i++)
		targetObj.options[i + startIdx] = new Option(twoDArray[i][0],twoDArray[i][1]);
}

function setField(name, value, type)
{
	var field = new Array();
	field[0] = name;
	field[1] = (typeof(value) != 'undefined') ? value : 'No details';
	field[2] = (typeof(type) != 'number') ? FLD_TEXT : type;
	return (field);
}

function setRecord()
{
	var record = new Array();
	for (var i = 0; i < arguments.length; i++)
		record[record.length] = new Array(arguments[i][0], arguments[i][1], arguments[i][2]);
	return (record);
}

function setRecordset()
{
	var recordset = new Array();
	for (var i = 0; i < arguments.length; i++)
		recordset[recordset.length] = arguments[i];
	return (recordset);
}

function isWhitespace(str)
{
  return ((isBlank(str)) || (RE_WHITESPACE.test(str)));
}

function isEmpty(obj)
{
	return (typeof(obj) == 'undefined' || obj == null);
}

function isBlank(obj)
{  
	if (!isEmpty(obj)) {
		obj = obj + '';
		if (typeof(obj) == 'string')
			return (obj.length == 0 || obj == 'undefined' || obj == 'null');
		return (false);
	}
	return (true);
}

function oneOrOther(isVal, blankVal) {
	return (!isBlank(isVal)) ? isVal : blankVal;
}

function isDateObject(obj) {
// Gareth 39 Sept 2003
	if (obj != null && obj != 'undefined') {
		if (obj.constructor === new Date().constructor) {
			return true;
		}
	}
	return false;
}

function isClass(obj, classname)
{
	return (obj.constructor == Object);
}

function isArray(obj, d, len)
{
	var found = (!isBlank(obj) && obj.constructor == Array);

	if (!isBlank(d)) {
		d--;
		if (d < 0)
			return (!found);
		else if (d == 0)
			return (found && !isArray(obj[0]));
		else if (found && d > 0) {
			for (var i = 0; i < obj.length; i++) {
				if (!isArray(obj[i], d))
					return (false);
			}
			return (true);
		}
	}
	return ((!isBlank(len)) ? (found && len == obj.length) : found);
}

function isString(obj)
{
	return (typeof(obj) == 'string' || obj.constructor == String);
}

function isList(obj, delimiter)
{
	return (!isBlank(obj) && isString(obj) && obj.indexOf(delimiter) != -1)
}

function isInteger(obj) {
	if (isNaN(obj))
		return false;
	if (isNaN(parseInt(obj)))
		return false;
	if (isNaN(parseFloat(obj)))
		return false;
	if (parseInt(obj) != parseFloat(obj))
		return false;
	return true;
}

function zeroOrInt(val) {
	val *= 1;
	if (isInteger(val))
		return(val)
	else
		return(0);
}

function addEscapes(str)
{
	if (!(str == null || typeof(str) == 'undefined'))
	{
  	if (str.length > 0)
		{
  		var re = /(['|;|\\])/g;
  		return (str.replace(re, '\\'+'$1'));
  	}
 	}
	return(str);
}

function formatString(val)
{
	if (isString(val) && !isBlank(val))
		val = replaceNewLines(val.replace(RE_ESCAPE_CHARS, '\\'+'$1'), CHAR_RS_NEWLINE);
	return (val);
}

function formatBool(format, val)
{
	var value = String(val).toLowerCase();
	var yes = (value == 'true' || value == 'yes' || value == '1');
	var no = (value == 'false' || value == 'no' || value == '0');
	var unknown = (!yes && !no && !isBlank(value));

	if (format == FMT_BOOL_YES_NO_UNKNOWN && unknown)
		return ('Unknown');
	else if (format == FMT_BOOL_MSACCESS && (unknown || isBlank(value)))
		return ('false');
	else if (format == FMT_BOOL_YES_NO_NO_DETAILS && (unknown || isBlank(value)))
		return ('No details');
	else if (yes || no) {
		if (format == FMT_BOOL_YES_NO || format == FMT_BOOL_YES_NO_UNKNOWN || FMT_BOOL_YES_NO_NO_DETAILS)
			return ((yes) ? 'Yes' : 'No');
		else if (format == FMT_BOOL_TRUE_FALSE || FMT_BOOL_MSACCESS)
			return ((yes) ? 'true' : 'false');
	}
	return ('');
}

function formatNull(format, val) 
{
	if (isBlank(val))	{
		switch (format)	{
			case FMT_NULL_BLANK:
				return ('');
			case FMT_NULL_NOT_KNOWN:
				return ('Not known');
			case FMT_NULL_NBSP:
				return ('&nbsp\;');
			case FMT_NULL_UNDECIDED:
				return ('Undecided');
			case FMT_NULL_NO_DETAILS:
				return ('No details');
			default:
				return (new String(format));
		}
	}
	return (val);
}

function pad(str, len, char) 
{
	str = new String(str);
	char = new String(char.charAt(0));
	for (var i = 0; i < (len - str.length); i++)
		str = char + str;
	return (str);
}

function stripNewlines(str) {
	var newStr = '';
	for (i=0;i<str.length;i++) {
		if (!(str.charCodeAt(i) == 13 || str.charCodeAt(i) == 10)) {
			newStr += str.charAt(i);
		} else {
			newStr += ' ';
		}
	}
	return newStr.replace(/[ ]+/g, ' ');
}

function replaceNewLines(str, char) 
{
	var newStr = '';
	for (var i = 0; i < str.length; i++) {
		if (str.charCodeAt(i) == 13)
			newStr += char;
		else if (str.charCodeAt(i) != 10)
			newStr += str.charAt(i);
	}
	return (newStr);
}

function reinstateNewLines(str, char)
{
	var newStr = '';
	for (var i = 0; i < str.length; i++)
		newStr += (str.charAt(i) == char) ? String.fromCharCode(13,10) : str.charAt(i);
	return (newStr);
}

function cleanInput(str, textbox)
{
	var re = RE_USER_TEXT_ENTRY_NOT_ALLOWED;
	if (re.test(str)) {
		alert('You\'ve used a character which isn\'t allowed.');
		textbox.value = str.replace(re, '');
		return(RegExp.index);
	}
}

function memoLimit(theElement, theLimit) {
	var theText = theElement.value;
	if (theText.length > theLimit) {
		alert('The maximum number of keystrokes is '+theLimit+'.\nYou entered '+theText.length+' keystrokes.\nThe text will now be clipped to '+theLimit+' keystrokes.\n');
		theElement.value = theText.substring(0,theLimit);
	}
}

function textareaLimit() {
	// Uses global TEXTAREA_LIMIT DEFINED IN Application.js or PrototypeGlobals
	// Uses attribute/property maxlength or custom attribute textlimit or default global TEXTAREA_LIMIT
	var theElement = event.srcElement;
	var atrib = (theElement.getAttribute('maxlength')) ? theElement.getAttribute('maxlength') : theElement.getAttribute('textlimit');
	var limit = (!isBlank(atrib)) ? atrib : TEXTAREA_LIMIT;
	var theText = theElement.value;
	if (theText.length > limit) {
		alert('The maximum number of keystrokes is '+limit+'.\nYou entered '+theText.length+' keystrokes.\nThe text will now be clipped to '+limit+' keystrokes.\n');
		theElement.value = theText.substring(0,limit);
	}
}

function textareaEntryValidation() {
	// Uses global TEXTAREA_LIMIT DEFINED IN Application.js or PrototypeGlobals
	// Uses function cleanInput
	// Uses attribute/property textlimit or default global TEXTAREA_LIMIT
	// handler for onkeyup (keyboard entry and paste) and onfocus (drag and drop) events
	var del = 46, backspace = 8, shift = 16, leftArrow = 37, upArrow = 38, rightArrow = 39, downArrow = 40;
	var cursorPosition = null;
	if (event.keyCode != del && event.keyCode != shift && event.keyCode != leftArrow && event.keyCode != upArrow && event.keyCode != rightArrow && event.keyCode != downArrow) {
		var theTextarea = event.srcElement;
		var counterSpan = null;
		if (theTextarea.id) {
			// counterSpan = null if it doesn't exist.
			counterSpan = document.getElementById(theTextarea.id + 'CounterSPAN');
		}
		cursorPosition = cleanInput(theTextarea.value, theTextarea);
		var atrib = (theTextarea.getAttribute('maxlength')) ? theTextarea.getAttribute('maxlength') : theTextarea.getAttribute('textlimit');
		var limit = (!isBlank(atrib)) ? atrib : TEXTAREA_LIMIT;
		var len = event.srcElement.value.length;
		var charsRemaining = limit - len;
		if (counterSpan) {
			if (charsRemaining == limit) {
				counterSpan.innerHTML = '<BR>(Maximum ' + limit + ' keystrokes)';
			} else {
				counterSpan.innerHTML = '<BR><SPAN class=textBlue>' + charsRemaining + ' keystrokes remaining </SPAN> <BR>(Maximum ' + limit + ' keystrokes)';
			}
		}
		if (len >= limit) {
			if (len == limit) {
				if (event.type == 'keyup') {
					alert('You have now entered the maximum number of keystrokes ('+limit+') allowed in this text box.');
				}
			} else {
				alert('The maximum number of keystrokes is '+limit+'.\nYou entered '+len+' keystrokes.\nThe text will now be clipped to '+limit+' keystrokes.\n');
				theTextarea.value = theTextarea.value.substring(0, limit);
			}
		}
		if (cursorPosition != null) {
			var adjPos = theTextarea.value.substring(0, cursorPosition).replace(new RegExp("\n", "g"), '').length;
			var tr = theTextarea.createTextRange();
			tr.move('character', adjPos);
			tr.select();
		}
	}
}

function stripNonWordsAndDigits(inTxt) {
	if (isBlank(inTxt)) {
		return('');
	}
	var re = /[^\w\d]/gi;
	return(inTxt.replace(re, ''));
}

function getCookieVal(string, param, delim) {
	// returns value of param from string
	if (string.length == 0)
		return '';
	var sPos = string.indexOf(param + "=");
	if (sPos == -1)
		return '';
	sPos = sPos + param.length + 1;
	var ePos = string.indexOf(delim, sPos);
	if (ePos == -1)
		ePos = string.length;
	return unescape(string.substring(sPos, ePos));
}

