function add_fields(title,named,typed,mandatoryd,lengthd,confirmit)	{
	user_fields[title]=new Array;
	user_fields[title]['name']=named;
	user_fields[title]['type']=typed;
	user_fields[title]['mandatory'] = mandatoryd;
	user_fields[title]['length'] = lengthd||0;//0=do not check for length
	user_fields[title]['confirm'] = confirmit||0;//0=do not check against another field called CONFIRM_name
}
function remove_field(title)	{
	if(user_fields[title]){
		user_fields[title]['mandatory']=0;
	}
}

function getKeyCode(e) {
	// for IE, we use e.keyCode
	if (window.event || !e.which)
	{
		return e.keyCode;
	}
	// for Netscape, we use e.which
	else if (e)
	{
		return e.which;
	}
	// otherwise, return 0
	return 0;
}

var lastValue;

// integer 

function constrain_integer(e) {
	var kc = getKeyCode(e);
	return kc >= 48 && kc <= 57;
}

function integer_validate_error(input, name) {
	if (input.value.length = 0 || (Math.round(input.value) != input.value)) {
		return 'The "' + name + '" field has to be a whole number.';
	}
	return '';
}

// float

function constrain_float(e) {
	var kc = getKeyCode(e);
	return constrain_integer(e) || kc == 46 || kc == 45;
}

function float_validate_error(input, name) {
	if (input.value.length = 0 || (input.value*1 != input.value)) {
		return 'The "' + name + '" field has to be a number.';
	}
	return '';
}

// decimal

function constrain_decimal(e) {
	return constrain_float(e);
}

function decimal_validate_error(input, name) {
	var rexp = /^[\-\+]?[0-9]+(\.[0-9][0-9]?)?$/;
	if (!rexp.test(input.value)) {
		return 'The "' + name + '" field has to be a number specified to 2 decimal places.';
	}
	return '';
}

// alphanumeric

function constrain_alphanumeric(e) {
	var kc = getKeyCode(e);
	return constrain_integer(e) || (kc >= 65 && kc <= 90)
		|| (kc >= 97 && kc <= 122) || (kc == 95);
}

function alphanumeric_validate_error(input, name) {
}

// email

function constrain_email(e) {
	var kc = getKeyCode(e);
	return constrain_alphanumeric(e) || kc == 45 || kc == 46 || kc == 64 || kc == 222;
}

function email_validate_error(input, name) {
	var test = (input.value);
	var email = /^([\w-'.]+)\@(([\w-])+\.)+([a-z]{2,4})$/i;
	var emailvalidate = test.match(email);
	if(!emailvalidate)	{
		return 'The "' + name + '" field has to be an email address of the form aaa@bbb.ccc\n';
	}

	return '';
}

// url

var URLchars = "#%&-./:?~=+;"

function constrain_url(e) {
	var kc = getKeyCode(e);
	for (var i=0; i<URLchars.length; i++) {
		if (kc == URLchars.charCodeAt(i)) { return true; }
	}
	return constrain_alphanumeric(e);
}

function url_validate_error(input, name) {
	if (Math.round(input.value*100) != input.value * 100) {
		return 'The "' + name + '" field has to be a number specified to 2 decimal places.\n';
	}
	return '';
}

// password

function password_validate_error(input, name) {
	var confirmInput = input.form[input.name+'_CONFIRM'];
	if (!confirmInput) {
		input.value='';
		return 'You cannot change the "' + input.name + '" field on this page.';	
	}
	if (input.value != confirmInput.value) {
		input.value = '';
		confirmInput.value = '';
		return 'The "' + input.name + '" fields do not match. Please retype "' + input.name +'"\n' ;
	}
else if(input.value==""){
		return 'You have not filled in a '+input.name+'\n';
	}
	return '';
}

// form validation

var validators = new Array;
validators['integer'] = integer_validate_error;
validators['email'] = email_validate_error;
validators['float'] = float_validate_error;
validators['alphanumeric'] = alphanumeric_validate_error;
validators['decimal'] = decimal_validate_error;
validators['password'] = password_validate_error;

var constrained = new Array;
constrained['integer'] = 1;
constrained['email'] = 1;
constrained['float'] = 1;
constrained['alphanumeric'] = 1;
constrained['decimal'] = 1;
constrained['url'] = 1;

function validateForm(form, metadata) {
	var errall="";
	var testradio="";
	for (var i=0; i<form.elements.length; i++) {
		var el = form.elements[i];
		var el_metadata = metadata[el.name];
		if ((el_metadata)) {
			var value = el.value;
			if (el.type == 'select-one' || el.type == 'select-multiple') { 
				value = '';
				if (el.selectedIndex >= 0) {
					value = el.options[el.selectedIndex].value;
				}
			}
			else if (el.type == 'checkbox') { value = el.checked }
			else if(el.type == 'radio'){
				value="";
				for (j=0;j<form[el.name].length;j++){
					if(form[el.name][j].checked){
						value=form[el.name][j].value;
					}
				}
			}
			
			if(el_metadata['confirm']){
				var confirmInput = document.getElementById(el.name +'_CONFIRM');
				if(confirmInput){
					if(el.value!=confirmInput.value){
						if(errall==""){
							el.focus();
						};
						errall+= 'The "' + el.name + '" fields do not match. Please retype "' + el.name +'"\n' ;
					}
				}
				else{
					errall+= 'The "' + el.name + '" field can not be changed on this form \n' ;
				}
			}
			
			if((el_metadata['length']>0)&& (value!='')&&(el_metadata['type']=='short_text')){
				var thislen=el.value.length;
				var testlen = el_metadata['length'];
				if(thislen>testlen){
					if(errall==""){
						el.focus();
					};
					errall+=  'the field "' + el_metadata['name'] + '" is too long, please reduce the content\n';

					
				//	return false;
				}
			}
			
			if ((el_metadata['mandatory']) && (value=='') && (el.type!='password')) {
				if(el.type=='radio'){
					if(testradio!=el.name){
						testradio=el.name;
						if(errall==""){
							el.focus();
						};
						errall+= '- ' + el_metadata['name'] + '\n';
					}
				}
				else{
					if(errall==""){
						el.focus();
					};
					errall+= '- ' + el_metadata['name'] + '\n';
				}
				//return false;
			}
			var validator = validators[el_metadata['type']];
			if ((validator)) {
			 	var err = validator(el, el_metadata['name']);				
			 	if (err) {
			 		if(errall==""){
						el.focus();
					};
					errall+= (err);
				//	return false;
				}
			}
		}
	}
	if(errall){
		alert("Please complete the following fields:\n"+errall);
		return false;
	}
	return true;
}

function constrainFormInputs(form, metadata) {
	for (var i=0; i<form.elements.length; i++) {
		var el = form.elements[i];
		var el_metadata = metadata[el.name];
		if ((el_metadata)) {
			if (constrained[el_metadata['type']]) {
				el.onkeypress = new Function('return constrain_' + el_metadata['type'] + '(event)');
			}
		}
	}
}