/*
Validation 1.1
queriousDesigns.com
08.19.2002

---------------------
SECTIONS:
	MAIN_FUNCTION
	CHECKFIELD_FUNCTIONS
	OPTION_FUNCTIONS
	INTERNAL_FUNCTIONS
	ERROR_FUNCTIONS
---------------------
---------------------
INFORMATION:

1. Options
	-  :option tag (hyphen)
	-l :validates for an instance of a lowercase character
	-u :validates for an instance of an uppercase character
	-L :validates ALL characters to be lowercase
	-U :validates ALL characters to be uppercase
	-n :(where n is an integer) validates field length of n
	
	Combinations can be strung together.  Only one hyphen is needed
---------------------
---------------------
BUGS:

---------------------
---------------------
ENHANCEMENTS:
1. Logical ANDS
---------------------
---------------------
FIXES:
1. Checkbox element cannot have sets.
---------------------
---------------------
*/

//Global Variables for Input List
var form_name = "";
var field_type = "";
var field_name = "";
var error_message = "";

//Global Variables for Error List
var message = "1.1 - Please supply the following information:                ";
var focal = "";
var errorlist = "";
var foo = true;

//Global Variables for Options List
var uppercase = 0;
var lowercase = 0;
var ilower = 0;
var iupper = 0;
var size = 0;
var sizelength = "";

//MAIN_FUNCTION
//-------------------------------------------main function--------------------------------------------------
function validate(array) {
	resetOptions();
	var maxfields = (array.length - 1) / 3;
	var pointer = 0;
	var valid = true;
	
	//going through the array(three fields at a time)
	for(var i = 0; i < maxfields; i++) {
		pointer = (i * 3) + 1;
		
		//set variables
		form_name = (array[0]) ? array[0] : "forms[0]";
		field_type = array[pointer];
		field_values = array[pointer + 1];
		
		field_array = field_values.split("&&");
		field_name = field_array[0];
		
		error_message = array[pointer + 2];
		
		//set the item for focus
		if(foo) {
			focal = cleanName(form_name,field_type,field_name);
			
			if(focal == null) {
				errorMe(field_type,field_name,"focal_null");
			}
		}
		
		//check field type
		if(field_type == "text") {
			valid = checkText(form_name,field_values);
		} else if(field_type == "alpha") {
			valid = checkAlpha(form_name,field_values);
		} else if(field_type == "numeric") {
			valid = checkNumeric(form_name,field_values);
		} else if(field_type == "email") {
			valid = checkEmail(form_name,field_values);
		} else if(field_type == "select") {
			valid = checkSelect(form_name,field_values);
		} else if(field_type == "radio") {
			valid = checkRadio(form_name,field_values);
		} else if(field_type == "checkbox") {
			valid = checkCheckbox(form_name,field_values);
		} else {
			valid = false;
			errorMe(field_type,field_name,"wrong_type");
		}
		
		//fill the error list
		if(!valid) {
			errorlist += "    " + error_message + "\n";
			foo = false;
		}
	}
	
	//display if not valid
	if(!foo || !valid) {
		alert(message + "\n\n" + errorlist);
		focal.focus();
		
		errorlist = "";
		focal = "";
		foo = true;
		return false;
		
	} else if (foo || valid) {
		return true;
	} else {
		return false;
	}
}
//-------------------------------------------main function--------------------------------------------------


/************************************************************************************************************/

//CHECKFIELD_FUNCTIONS
//------------------------------------------Check Text Field------------------------------------------------
function checkText(form_name,field_values) {
	
	var valid = true;
	
	if(field_values.indexOf("&&") > -1) {
		var conditions = field_values.split("&&");
		var field_name = conditions[0];
		
		for(var c = 1; c < conditions.length; c++) {
			add_check = checkText(form_name,conditions[c]);
			if(!add_check) {
				valid = false;
			}
		}
	} else {
		var field_name = field_values;
	}
	
	//setOptions(field_name,LOW,low,UP,up,size)
	field_name = setOptions(field_name,true,true,true,true,true);
	
	var field = eval("document." + form_name + "." + field_name + ".value");
	var len = field.length;
	
	//check if field is empty
	if(valid) {
		valid = isEmpty(field);
	}
	
	//check for lowercase
	if(valid && lowercase == 1) {
		valid = isLower(field);
	}
	
	//check for instance of lowercase
	if(valid && ilower == 1) {
		valid = isILower(field);
	}
	
	//check for uppercase
	if(valid && uppercase == 1) {
		valid = isUpper(field);
	}
	
	//check for instance of uppercase
	if(valid && iupper == 1) {
		valid = isIUpper(field);
	}
	
	//check field length
	if(valid && size == 1) {
		valid = isSized(field,sizelength);
	}
	
	resetOptions();
	
	return valid;
}
//------------------------------------------Check Text Field------------------------------------------------


//------------------------------------------Check Alpha Field-----------------------------------------------
function checkAlpha(form_name,field_values) {
	
	var valid = true;
	
	if(field_values.indexOf("&&") > -1) {
		var conditions = field_values.split("&&");
		var field_name = conditions[0];
		
		for(var c = 1; c < conditions.length; c++) {
			add_check = checkAlpha(form_name,conditions[c]);
			if(!add_check) {
				valid = false;
			}
		}
	} else {
		var field_name = field_values;
	}
	
	//setOptions(field_name,LOW,low,UP,up,size)
	field_name = setOptions(field_name,true,true,true,true,true);

	var field = eval("document." + form_name + "." + field_name + ".value");
	var len = field.length;
	
	//check if field is empty
	if(valid) {
		valid = isEmpty(field);
	}

	//check if field is numeric
	if (valid && (isNumeric(field))) {
		valid = false;
	}
	
	//check for lowercase
	if(valid && lowercase == 1) {
		valid = isLower(field);
	}

	//check for instance of lowercase	
	if(valid && ilower == 1) {
		valid = isILower(field);
	}

	//check for uppercase
	if(valid && uppercase == 1) {
		valid = isUpper(field);
	}

	//check for instance of uppercase
	if(valid && iupper == 1) {
		valid = isIUpper(field);
	}

	//check field length
	if(valid && size == 1) {
		valid = isSized(field,sizelength);
	}
	
	resetOptions();
	
	return valid;
}
//------------------------------------------Check Alpha Field------------------------------------------------


//------------------------------------------Check Numeric Field----------------------------------------------
function checkNumeric(form_name,field_values) {
	
	var valid = true;
	
	if(field_values.indexOf("&&") > -1) {
		var conditions = field_values.split("&&");
		var field_name = conditions[0];
		
		for(var c = 1; c < conditions.length; c++) {
			add_check = checkNumeric(form_name,conditions[c]);
			if(!add_check) {
				valid = false;
			}
		}
	} else {
		var field_name = field_values;
	}
	
	//setOptions(field_name,LOW,low,UP,up,size)
	field_name = setOptions(field_name,false,false,false,false,true);
	
	var field = eval("document." + form_name + "." + field_name + ".value");
	var len = field.length;
	
	//check if field is empty
	if(valid) {
		valid = isEmpty(field);
	}
	
	//check if field is non-numeric
	if(valid && !isNumeric(field)) {
		valid = false;
	}
	
	//check field length
	if(valid && size == 1) {
		valid = isSized(field,sizelength);
	}
	
	resetOptions();
	
	return valid;
}
//------------------------------------------Check Numeric Field----------------------------------------------


//------------------------------------------Check Email Field------------------------------------------------
function checkEmail(form_name,field_values) {

	var valid = true;
	
	if(field_values.indexOf("&&") > -1) {
		var conditions = field_values.split("&&");
		var field_name = conditions[0];
		
		for(var c = 1; c < conditions.length; c++) {
			add_check = checkEmail(form_name,conditions[c]);
			if(!add_check) {
				valid = false;
			}
		}
	} else {
		var field_name = field_values;
	}
	
	//setOptions(field_name,LOW,low,UP,up,size)
	field_name = setOptions(field_name,true,false,true,false,false);
	
	var field = eval("document." + form_name + "." + field_name + ".value");

	var atsign = field.indexOf("@");
	var period = field.indexOf(".");
	
	//check if field is empty
	if(valid) {
		valid = isEmpty(field);
	}
	
	//check for atsign and period
	if((atsign <= 0) || (period < 0)) {
		valid = false;
	}
		
	//check for additional atsigns after initial atsign
	if(field.indexOf("@", atsign + 1) > 0) {
		valid = false;
	}
		
	//check extension
	if(period + 3 > field.length) {
		valid = false;
	}
	
	return valid;
}
//------------------------------------------Check Email Field------------------------------------------------


//------------------------------------------Check Select Field-----------------------------------------------
function checkSelect(form_name,field_values) {

	var valid = true;
	
	if(field_values.indexOf("&&") > -1) {
		var conditions = field_values.split("&&");
		var field_name = conditions[0];
		
		for(var c = 1; c < conditions.length; c++) {
			add_check = checkSelect(form_name,conditions[c]);
			if(!add_check) {
				valid = false;
			}
		}
	} else {
		var field_name = field_values;
	}
	
	//setOptions(field_name,LOW,low,UP,up,size)
	field_name = setOptions(field_name,false,false,false,false,false);

	var field = eval("document." + form_name + "." + field_name);
	
	//check if first position is still highlighted
	if(field.selectedIndex == "0") {
		valid = false;
	}
	
	return valid;
}
//------------------------------------------Check Select Field-----------------------------------------------


//------------------------------------------Check Radio Field---------------------------------------------
function checkRadio(form_name,field_values) {

	var valid = true;
	
	if(field_values.indexOf("&&") > -1) {
		var conditions = field_values.split("&&");
		var field_name = conditions[0];
		
		for(var c = 1; c < conditions.length; c++) {
			add_check = checkRadio(form_name,conditions[c]);
			if(!add_check) {
				valid = false;
			}
		}
	} else {
		var field_name = field_values;
	}
	
	//setOptions(field_name,LOW,low,UP,up,size)
	field_name = setOptions(field_name,false,false,false,false,false);

	var field = eval("document." + form_name + "." + field_name);

	//Check if one instance of radio set is checked
	if(!setTest(field)) {
		valid = false;
	}
	
	return valid;
}
//------------------------------------------Check Radio Field---------------------------------------------


//-----------------------------------------Check Checkbox Field----------------------------------------------
function checkCheckbox(form_name,field_values) {

	var valid = true;
	
	if(field_values.indexOf("&&") > -1) {
		var conditions = field_values.split("&&");
		var field_name = conditions[0];
		
		for(var c = 1; c < conditions.length; c++) {
			add_check = checkCheckbox(form_name,conditions[c]);
			if(!add_check) {
				valid = false;
			}
		}
	} else {
		var field_name = field_values;
	}
	
	//setOptions(field_name,LOW,low,UP,up,size)
	field_name = setOptions(field_name,false,false,false,false,false);
	
	var field = eval("document." + form_name + "." + field_name);
	
	if(field.length != "undefined" && field.length >= 2) {
		errorMe("checkbox",field_name,"cannot_set");
		valid = false;
		
	} else {
		
		//Check if one instance of checkbox set is checked
		if(!isChecked(field)) {
			valid = false;
		}
	}
	
	return valid;
}
//------------------------------------------Check Checkbox Field---------------------------------------------


/************************************************************************************************************/

//OPTION_FUNCTIONS
//------------------------------------------Set Field Options------------------------------------------------
function setOptions(field_name,allow_low,allow_ilow,allow_up,allow_iup,allow_size) {
	
	var allow = true;
	var len = field_name.length;
	var option = field_name.indexOf("-");
	
	if(option > 0) {
	
		var olist = field_name.substring(field_name.length, option + 1);
		field_name = field_name.substring(option, 0);

		//get specified length if any
		for(var i = 0; i < olist.length;i++) {
			var temp = olist.substring(i + 1, i);
			
			if(isNumeric(temp)) {
				sizelength += temp;
			}
		}
		
		//turn on any specified options
		for(var i = 0; i < olist.length;i++) {
			var temp = olist.substring(i + 1, i);

			if(allow_low && temp == "L") {
				lowercase = 1;
			} else if(allow_ilow && temp == "l") {
				ilower = 1;
			} else if(allow_up && temp == "U") {
				uppercase = 1;
			} else if(allow_iup && temp == "u") {
				iupper = 1;
			} else if(allow_size && sizelength > 0) {
				size = 1;
			} else {
				allow = false;
			}
		}
		
		//Option tag with no options listed
		if(olist.length == 0) {
			errorMe(field_type,field_name,"incomplete_option");
		}
		
		//both options are selected for a single field
		if((lowercase == 1) && (uppercase == 1)) {
			errorMe(field_type,field_name,"conflicting_options");
		}
		
		//option is not allowed for that field
		if(!allow) {
			errorMe(field_type,field_name,"invalid_option");
		}
	}

	return field_name;
}
//------------------------------------------Set Field Options------------------------------------------------
function resetOptions() {
	
	lowercase = 0;
	ilower = 0;
	uppercase = 0;
	iupper = 0;
	size = 0;
	sizelength = "";
	field = "";
	field_name = "";
}

//------------------------------------------Take options out of field names-------------------------------------------
function cleanName(form_name,field_type,field_name) {
	
	var field_name;
	var len = field_name.length;
	var ding = 0;
	
	var option = field_name.indexOf("-");
	
	//Check for options
	if(option > 0) {
		field_name = field_name.substring(option, 0);
	}
	
	if(field_type == "radio") {
		field_name = eval("document." + form_name + "." + field_name + "[0]");
	} else {
		field_name = eval("document." + form_name + "." + field_name);
	}
	
	return field_name;
}
//------------------------------------------Take options out of field names-------------------------------------------


/************************************************************************************************************/

//INTERNAL_FUNCTIONS
//------------------------------------------Check a Set------------------------------------------
function setTest(field) {
	
	for (var i = 0; i < field.length; ++i) {
    	if (field[i].checked) {
			return true;
		}
	}
    return false;
}
//------------------------------------------Check a Set------------------------------------------


//------------------------------------------Check a Single Check------------------------------------------
function isChecked(field) {
	if(field.checked) {
		return true;
	}
	return false;
}
//------------------------------------------Check a Single Check------------------------------------------


//------------------------------------------Check for Empty Field------------------------------------------
function isEmpty(field) {
	
	if(field.length == 0) {
		return false;
	} else {
		return true;
	}
}
//------------------------------------------Check for Empty Field------------------------------------------


//------------------------------------------Check for lowercase characters------------------------------------------
function isLower(field) {

	for(var i = 0; i < field.length; i++) {
		if(!lowTest(field.substring(i+1,i))) {
			return false;
		}
	}
	
	return true;
}

function isILower(field) {
	
	for(var i = 0; i < field.length; i++) {
		if(lowTest(field.substring(i+1,i))) {
			return true;
		}
	}
		
	return false;
}

function lowTest(field) {

	var low = /[\a-z]/;

	if(low.test(field)) {
		return true;
    }
}
//------------------------------------------Check for lowercase characters------------------------------------------


//------------------------------------------Check for uppercase characters------------------------------------------
function isUpper(field) {

	for(var i = 0; i < field.length; i++) {
		if(!upTest(field.substring(i+1,i))) {
			return false;
		}
	}
	
	return true;
}

function isIUpper(field) {

	for(var i = 0; i < field.length; i++) {
		if(upTest(field.substring(i+1,i))) {
			return true;
		}
	}
	
	return false;
}

function upTest(field) {

	var high = /[\A-Z]/;

    if(high.test(field)) {
    	return true;
	}
}
//------------------------------------------Check for uppercase characters------------------------------------------


//------------------------------------------Check for numeric values------------------------------------------
function isNumeric(field) {
	
	for(var i = 0; i < field.length; i++) {
		if(!numTest(field.substring(i+1,i))) {
			return false;
		}
	}
	
	return true;
}

function numTest(field) {

	var nums = /[\0-9]/;
	
    if(nums.test(field)) {
  		return true;
	}
}
//------------------------------------------Check for numeric values------------------------------------------


//------------------------------------------Check for length------------------------------------------
function isSized(field,sizelength) {
	
	if(field.length != sizelength) {
		return false;
	} else {
		return true;
	}
}
//------------------------------------------Check for length------------------------------------------

/************************************************************************************************************/

//ERROR_FUNCTIONS
//------------------------------------------Alert all various functions------------------------------------------------
function errorMe(field,name,type) {
	
	var error = "";

	if(type == "wrong_type") {
		error = field + " is an undefined Field Type.";
	} else if(type == "invalid_option") {
		error = name + " was given an Invalid Option.";
	} else if(type == "conflicting_options") {
		error = name + " has Conflicting Options.";
	} else if(type == "incomplete_option") {
		error = name + " has listed no Options.";
	} else if(type == "focal_null") {
		error = field + " [ "+ name +" ] does not have a focus object.";
	} else if(type == "cannot_set") {
		error = "[ " + name + " ] is the name of multiple fields.";
	} else {
		error = "Mismatch Error.\n" + "  name: " + name;
	}

	alert(error);
}

function onerror(msg,url,line) {

	if (msg.indexOf("has no properties.")) {
		alert("A field set in the array does not match the field type in the HTML document.");
	}

	return false;
}
//------------------------------------------Alert all various functions------------------------------------------------