/*
	mquirk
	Validation tool for forms. Adds icons next to inputs in the form,
	which indicate to the user if the fields are valid in real-time.

	Usage:
		1) call: setupFormValidation(document.myForm)
		
		2) set up the form to use validation:
			- for any field that needs checkmark/X validation, give it a 'v_someType' class name. Many validation types are already written, below.
			- if a field is required (must be nonempty), also give it a 'required' class name.
			- if a field needs constraints on what characters can be entered into the text box, give it a 'c_someType' class name.
		   
		3) make a button at the bottom of the form that calls validateAndSubmit(document.myForm)
*/

special_chars = [ 127, 8, 9, 37, 39, 46, 36, 35, 116 ];

con = Object();
con['c_numbers']		= function(ch, form) { return (ch > 47 && ch < 58) || (ch > 95 && ch < 106); };
con['c_letters']		= function(ch, form) { return ((ch > 64 && ch < 91)); };
con['c_alphanum']		= function(ch, form) { return (con['c_letters'](ch, form) || con['c_numbers'](ch_form)); };
con['c_zip'] = con['c_numbers'];

val = Object();
val['v_phone']			= function(value,form){ return value.match( /^[0-9]{10}$/ ); };
val['v_zip_usa']		= function(value,form){ return value.match( /^[0-9]{5}([0-9]{4})?$/ ); };	// Only necessarily valid for USA
val['v_zip_other']		= function(value,form){ return value.length > 0; };							// Otherwise we won't really worry about it
val['v_email']			= function(value,form){ return value.match( /^[\w\-\.\+]+\@[a-zA-Z0-9\.\-]+\.[a-zA-z0-9]{2,4}$/ ); };
val['v_email_reenter']	= function(value,form){ return form['Email'].value == value && val['v_email'](value,form); };		// Re-entry must be the same as the other email
val['v_pass']			= function(value,form){ return value.match( /^.{6,}$/ ); };
val['v_pass_reenter']	= function(value,form){ return form['Password'].value == value && val['v_pass'](value,form); };	// Re-entry must be the same as the other password
val['v_name']			= function(value,form){ return value.match( /^[0-9\w\.\-]+( [0-9\w\.\-]+)+$/ ); };
val['v_text']			= function(value,form){ return value.match( /^([0-9\w\.\-\#]+\ ?)+$/ ); };
val['v_numbers']		= function(value,form){ return value.match( /^[0-9]+$/ ); };
val['v_nonempty']		= function(value,form){ return value.match( /^.+$/ ); };
val['v_exp']			= function(value,form){ return value.length>0 && form.view_ccMonthSel.value.length>0; }
val['v_zip'] = val['v_zip_usa'];

iconX = "/images/icon_x.gif";
iconCheck = "/images/icon_check.gif";
iconRequired = "/images/icon_required.png";

function oc(a)
{
  var o = {};
  for(var i=0;i<a.length;i++)
  {
    o[a[i]]='';
  }
  return o;
}

function isValElem(e){	//Is this element one to be validated?
	return (e && typeof e.className != "undefined" && e.className != null &&
	(e.className.indexOf("required") != -1 || e.className.indexOf("v_") != -1))
}

function validateField(e, form){
	if(e.offsetWidth == 0){ return true; }
	if(!e.className){ return true; }
	required = false;
	validator = null;
	
	if(e.className.indexOf("required") == -1 && e.value == "")	//If the field is not required, the value can be empty
	{
		return true;
	}	

	if(e.className.indexOf("v_") != -1)
	{
		validator = /.*(v_\S+).*/i.exec(e.className)[1];
		if (val[validator](e.value, form)){
			return true;
		}
	}
	return false;
}

function validateForm(form, alerts){
	var elems = form.elements;
	var fail = false;
	for( i in elems ){
		e = elems[i];
		if(isValElem(e)){
			valimg=document.getElementById(form.getAttribute("name")+e.name+"_valImg");
			if(e.className.indexOf("required")!=-1 && e.value=="" && e.offsetWidth > 0)
			{
				valimg.setAttribute("src",iconRequired);
				if(alerts) {
					alert("Please fill in all required fields (marked with a blue arrow)");
					alerts=false;
				}
				fail = true;
			}
			else if(!validateField(e, form)){
				valimg.style.display="";
				valimg.setAttribute("src",iconX);
				fail = true;
			}
			else{
				valimg.style.display="";
				valimg.setAttribute("src",iconCheck);
				if(e.className.indexOf("required")==-1 && e.value=="")
				{
					valimg.style.display="none";
				}
			}
		}
	}
	// console.log('fail',fail);
	if ( fail )
	{
		if(alerts) { alert("Please correct the errors (marked with a red \"x\")"); }
		return false;
	}
	return 1;
}

function isConElem(e)
{
	return (e && e.className && e.className.indexOf("c_") != -1);
}

function checkConstraints(form, e, event)
{
	if(window.event) { ch = window.event.keyCode; }
	else if(event.which) { ch = event.which; }
	
	if(e && e.className && e.className.indexOf("c_") != -1)
	{
		constraint = /.*(c_\S+).*/i.exec(e.className)[1];
		if (ch > 126 || ch in oc(special_chars) || con[constraint](ch, form)){
			return true;
		}
	}
	
	if(event && event.which){event.preventDefault();}
	if(window.event){window.event.returnValue = false;}
	
	return false;
}

function setupFormValidation(form){
	var elems = form.elements;
	window.onkeyup = function(){validateForm(form, false)};
	document.onkeyup = function(){validateForm(form, false)};
	window.onmouseup = function(){validateForm(form, false)};
	document.onmouseup = function(){validateForm(form, false)};
	for(i=0; i < elems.length; i++){ // 'for ... in' does not work across all browsers
		e=elems[i];
		if(isValElem(e)){
			var valimg = document.createElement("img");
			valimg.setAttribute("src", iconCheck);
			valimg.setAttribute("id", form.getAttribute("name")+e.name+"_valImg");
			e.parentNode.appendChild(valimg);
		}
		if(isConElem(e)){
			e.onkeydown = function(event){checkConstraints(form, this, event) };
			
		}
	}
	validateForm(form, false);
}

function validateAndSubmit(form){
	if(validateForm(form, true)){ form.submit(); }
	else { return false;}
}
