(function(window, undefined) {
	var document = window.document;
	
	var trim = function(str) {
		return str.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
	};
	
	var noValue = function(error) {
		error = error || 'This field is required.';
		return function(el) {
			el.value = trim(el.value);
			if(!el.value) {
				alert(error);
				el.focus();
				return false;
			}
		};
	};
	
	var requireDetails = function(field, value, error) {
		error = error || 'This field is required.';
		value = value || 'No';
		return function(el) {
			el.value = trim(el.value);
			var select = document.getElementsByName(field);
			if(!el.value && select[0] && select[0].value === value) {
				alert(error);
				el.focus();
				return false;
			}
		};
	};
	
	
	var field = {
		
		// basic information
		title: noValue(),
		full_name: noValue('Please enter your full name.'),
		dob_month: noValue(),
		dob_day: noValue(),
		dob_year: noValue(),
		
		// contact information
		email: noValue('Please enter your e-mail address.'),
		address: noValue('Please enter your street address.'),
		city: noValue('Please enter your city.'),
		state: noValue('Please enter your state.'),
		zip: noValue('Please enter your zip code.'),
		
		// driver license
		license: function(el) {
			el.value = trim(el.value);
			var state = document.getElementsByName('license_state');
			if(!el.value || (state[0] && state[0].value==='CA' && !/^[a-z][0-9]{7}$/i.test(el.value))) {
				alert('Please enter a valid '+ state[0].value + ' driver license number.');
				el.focus();
				return false;
			}
		},
		commercial_license: noValue('Please specify whether or not your license is a commercial license.'),
		
		// citizenship
		citizen: noValue('Please specify whether or not you are a US citizen.'),
		immigration_status: requireDetails('citizen', 'No', 'Please explain your immigration status.'),
		
		// past DUI arrests/convictions
		past_dui: noValue(),
		past_dui_description: requireDetails('past_dui', 'Yes', 'Please describe your citation/arrest.'),
		past_dui_conviction: requireDetails('past_dui', 'Yes', 'Please explain your misdemeanor/felony.'),
		
		// past criminal arrests/convictions
		past_criminal: noValue(),
		past_criminal_description: requireDetails('past_criminal', 'Yes', 'Please describe your criminal conviction(s).'),
		
		// present DUI arrest
		arrest_location: noValue(),
		arrest_agency: noValue(),
		arrest_date_month: noValue(),
		arrest_date_day: noValue(),
		arrest_date_year: noValue(),
		station_test: noValue(),
		station_test_result: function(el) {
			el.value = trim(el.value);
			var select = document.getElementsByName('station_test');
			if(!el.value && select.length && select[0].value!=='No') {
				alert('What was your station test result?');
				el.focus();
				return false;
			}
		},
		alcohol_screening: noValue(),
		alcohol_screening_result: requireDetails('alcohol_screening', 'Yes', 'What was your alcohol screening test result?'),
		children_present: noValue(),
		speeding: noValue(),
		refused_test: noValue(),
		other_crimes: noValue(),
		other_charges: requireDetails('other_crimes', 'Yes', 'Please describe your other charge(s).'),
		license_status: noValue(),
		
		// court information
		suspension_date: noValue(),
		court_date_month: false, // defined here to preserve order and redefined below
		court_date_day: false, // defined here to preserve order and redefined below
		court_date_year: false, // defined here to preserve order and redefined below
		court_time: false, // defined here to preserve order and redefined below
		court_location: noValue(),
		
		// hearing information
		hearing: noValue(),
		hearing_type: requireDetails('hearing', 'Yes'),
		hearing_date: requireDetails('hearing', 'Yes'),
		hearing_officer: requireDetails('hearing', 'Yes'),
		hearing_discovery: requireDetails('hearing', 'Yes'),
		
		// car accident
		accident: noValue(),
		accident_victim: requireDetails('accident', 'Yes'),
		accident_injuries: requireDetails('accident', 'Yes'),
		accident_injuries_description: requireDetails('accident', 'Yes'),
		
		// alcohol details
		alcohol_consumption: noValue(),
		alcohol_effects: noValue(),
		medication: noValue(),
		other_drugs: noValue(),
		
		// police stop
		police_reason: noValue(),
		police_reason_description: requireDetails('police_reason', 'Yes'),
		police_reason_validity: requireDetails('police_reason', 'No'),
		car_problems: noValue(),
		field_sobriety_test: noValue(),
		alone: noValue(),
		passengers: requireDetails('alone', 'No'),
		
		// background information
		education: noValue(),
		reading_writing_problems: noValue(),
		physical_disabilities: noValue(),
		mental_disabilities: noValue(),
		other_medication: noValue(),
		drug_alcohol_problem: noValue(),
		drug_alcohol_program: noValue(),
		drug_alcohol_program_details: requireDetails('drug_alcohol_program', 'Yes'),
		accomplishments: noValue()
		
	}
	
	field.court_date_month =
	field.court_date_day =
	field.court_date_year =
	field.court_time = function(el) {
		el.value = trim(el.value);
		var checkbox = document.getElementsByName('court_date_unknown');
		if(!el.value && checkbox.length && !checkbox[0].checked) {
			alert('Please enter the date and time when you must appear for court, or check "I don\'t know" if you do not know.');
			el.focus();
			return false;
		}
	};
	
	
	var validate = [];
	for(var k in field) {
		for(var el = document.getElementsByName(k), i = el.length; i--;) {
			if(field[k].call) {
				validate.push([el[i], field[k]]);
			}
		}
	}
	validate.reverse();
	
	// fix empty option values for IE
	var options = document.getElementsByTagName('option');
	for(var i=options.length; i--;) {
		if(!options[i].getAttribute('value')) {
			options[i].setAttribute('value', options[i].innerHTML);
		}
	}
	
	document.getElementsByTagName('form')[0].onsubmit = function() {
		for(var i=validate.length; i--;) {
			if(validate[i][1](validate[i][0]) === false) {
				return false;
			}
		}
	};
	

})(window);
