// Note: This script does not use a third-party library.

// Volunteer form arrays

var targets = [
	'fname',
	'lname',
	'address1',
	'city',
	'state_province',
	'zip_postal',
	'phone',
	'email',
	'birth_year',
	'license',
	'hours'
	];

var errorMessages = new Array();
	
errorMessages['fname'] = 'Please enter your first name and check that it contains only letters.';	// 0
errorMessages['lname'] = 'Please enter your last name and check that it contains only letters.';	// 1
errorMessages['address1'] = 'Please enter your street address.';									// 2
errorMessages['city'] = 'Please enter your city.';													// 3
errorMessages['state_province'] = 'Please enter your state or province.';							// 4
errorMessages['zip_postal'] = 'Please enter your zip or postal code.';								// 5
errorMessages['phone'] = 'Please enter your phone number.';											// 6
errorMessages['email'] = 'Please enter a valid e-mail address.';									// 7
errorMessages['birth_year'] = 'Please enter your birth year in the format YYYY.';					// 8
errorMessages['license'] = 'Please enter your driver\'s license and state.';						// 9		
errorMessages['hours'] = 'Please enter the number of hours you\'d like to volunteer, using digits.'	// 10

var errors = new Array();
emptyErrors();

// Handlers and start-up

window.onload = function() {
	setEventHandlers();
	setYearBox();
}

function setEventHandlers() {
	var item;
	
	for (var target = 0; target < targets.length; target++) {
		item = document.getElementById(targets[target]);
		
		if (item != null) {
			item.onblur = function(event) {
				if (!event) {
					var event = window.event;
				}
				
				validate(this);
				this.className = this.className.replace(/focus/i, '');
			};
		}
	}
	
	setBlurAndFocus( document.getElementById('volunteer_form').getElementsByTagName('input') );
	setBlurAndFocus( document.getElementById('volunteer_form').getElementsByTagName('select') );
	setBlurAndFocus( document.getElementById('volunteer_form').getElementsByTagName('textarea') );
	
	document.getElementById('birth_month').onchange = updateDay;
	document.getElementById('volunteer_form').onsubmit = finalValidation;
}

function setBlurAndFocus(targets) {
	for (var i = 0; i < targets.length; i++) {
		if (targets[i].onblur == undefined && targets[i].type != 'submit' && targets[i].type != 'reset') {
			targets[i].onblur = blurEvent;
		}
		
		if (targets[i].onfocus == undefined && targets[i].type != 'submit' && targets[i].type != 'reset') {
			targets[i].onfocus = focusEvent;
		}
	}
}

function blurEvent(event) {

	if (!event) {
		var event = window.event;
	}
	
	this.className = this.className.replace(/focus/i, '');

}

function focusEvent(event) {
	
	if (!event) {
		var event = window.event;
	}
	
	if ( this.className.search(/focus/i) < 0 ) {
		this.className += ' focus';
	}
}

// Validation functions

function emptyErrors() {
	var item;

	for ( item in targets ) {
		errors[ targets[item] ] = '';
	}
}

function validate(input) {
	var pass;

	switch (input.name) {
		case 'fname': pass = validName(input); break;
		case 'lname': pass = validName(input); break;
		case 'address1': pass = containsCharacters(input); break;
		case 'city': pass = containsCharacters(input); break;
		case 'state_province': pass = containsCharacters(input); break;
		case 'zip_postal': pass = containsCharacters(input); break; // Because any country can be entered this isn't thoroughly validated.
		case 'phone': pass = containsCharacters(input); break;
		case 'email': pass = validEmail(input); break;
		case 'birth_year': pass = validBirthYear(input); break;
		case 'license': pass = containsCharacters(input); break;
		case 'hours': pass = validHours(input); break;
		default: pass = true;
	}
	
	var help_element = document.getElementById('help_messages');
	
	if (help_element != null) {
		help_element.innerHTML = printErrors();
	}
	
	return pass;
}

function validateAll() {
	var pass = true;
	var inputs = document.getElementById('volunteer_form').getElementsByTagName('input');

	for (var i = 0; i < inputs.length; i++) {
		if (!validate(inputs[i])) {
			pass = false;
		}
	}
	
	return pass;
}

function finalValidation(event) {
	
	var pass = validateAll();
	
	if (pass) {
		return true;
	}
	else {
		return false;
	}
}

function containsCharacters(input) {
	return matchesExpression(input, /^.+$/i);
}

function validName(input) {
	return containsCharacters && matchesExpression(input, /^[a-zA-Z\-\']{1,30}$/i);  
	/* KRH 10/8/09: original code seemed to contain an extra apostrophe befoer the right square bracket: 	
	return containsCharacters && matchesExpression(input, /^[a-zA-Z\-\']{1,30}$/i);  
	*/
}

function validEmail(input) {
	return containsCharacters && matchesExpression(input, /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/i);
}

function validBirthYear(input) {
	return containsCharacters && matchesExpression(input, /^\d{4}$/i);
}

function validHours(input) {
	return containsCharacters && matchesExpression(input, /^\d{1,2}$/i);
 }

function matchesExpression(input, expression) {
	var target = input.name;

	if (!expression.test(input.value)) {
		
		errors[target] = errorMessages[target];
		highlightLabel(input);
		
		return false;
	}
	else {
		
		errors[target] = '';
		highlightOffLabel(input);
		
		return true;
	}
}

function highlightLabel(input) {
	var label = getLabel(input);
	
	if ( label != null && label.className.search(/red/i) < 0 ) {
		label.className += ' red';
	}
	
	if ( input.className.search(/red_border/i) < 0 ) {
		input.className += ' red_border';
	}
}

function highlightOffLabel(input) {
	var label = getLabel(input);
	
	if (label != null) {
		label.className = label.className.replace(/red/i, '');
	}
	
	input.className = input.className.replace(/red_border/i, '');
}

function getLabel(input) {
	var parent = input;

	while ( parent.tagName != 'body' && parent.className.search(/field/i) < 0 ) {
		parent = parent.parentNode;
	}
	
	return parent.getElementsByTagName('label')[0];
}

function updateSubmit(pass) {
	var submit = document.getElementById('submit');

	if (pass) {
		submit.disabled = false;
	}
	else {
		submit.disabled = true;
	}
}

function printErrors() {
	
	var allErrors = '';
	var count = 0;
	var delimiter = '<br />';
	
	for (var i = 0; i < targets.length; i++) {
		if ( errors[ targets[i] ] != '' ) {
			allErrors += errors[ targets[i] ];
			
			if (i != errors.length - 1) {
				allErrors += delimiter;
			}
			
			count++;
		}
	}
	
	if (count < 2) {
		updateSubmit(true);
	}
	else {
		updateSubmit(false);
	}
	
	return allErrors;
}

// Birth date functions

function setYearBox() {
	var year = document.getElementById('birth_year');
	
	var today = new Date();
	var startYear = today.getFullYear() - 100;
	var endYear = today.getFullYear() - 5;
	
	var select = document.createElement('select');
	
	for (var i = startYear; i <= endYear; i++) {
		appendOption(select, i);
	}
	
	// select.onchange = updateDay; // Year changes need to account for leap years.  <--KRH 10/9/09: Commenting out because it causes weird behavior with the date & year fields. Nice to have functionality, but not necessary> 
	select.onblur = blurEvent;
	select.onfocus = focusEvent;
	replaceElement(year, select, 'birth_year', 'adjacent');
}

function updateDay(event) {
	var month = document.getElementById('birth_month');
	var day = document.getElementById('birth_day');
	var year = document.getElementById('birth_year');
	
	if (isNaN(year.text)) {
		year = year.options[year.selectedIndex].text;
	}
	
	var endDay = getNumDaysInMonth( month.options[month.selectedIndex].value, year );
	var select = document.createElement('select');
	
	for (var i = 1; i <= endDay; i++) {
		appendOption(select, i);
	}
	
	select.onblur = blurEvent;
	select.onfocus = focusEvent;
	replaceElement(day, select, 'birth_day', 'adjacent');
	
	
	var count = 0;
	
	for ( var i = 0; i < days.childNodes.length; i++ ) {
		if ( !isNaN( days.childNodes[i].innerHTML ) ) {
			count++;
		}
	}
	
}

function getNumDaysInMonth(month, year) {
	var date = new Date(year, month, 0);
	return date.getDate();
}

// Utility functions

function appendOption(selectBox, value) {
	var option = document.createElement('option');
	option.value = value;
	var text = document.createTextNode(value);
	option.appendChild(text);
	// option.text = value; Doesn't fly in Internet Explorer
	selectBox.appendChild(option);
}

function replaceElement(target, replacement, id, classes) {
	var parent = target.parentNode;
	
	parent.removeChild(target);
	replacement.id = id;
	replacement.name = id;
	
	if (classes != null) {
		replacement.className = classes;
	}
	
	parent.appendChild(replacement);
}
