function formValidator( form_id )
{
	this.form 			= document.getElementById(form_id);
	this.submits		= NW.Dom.select("button[type=submit]",		this.form);
	var fields 			= NW.Dom.select("textarea, input, select",	this.form);
	var warnings		= {};
	
	//Note: returns the number of errors, NOT whether the form validates.
	this.submit 		= function()
	{
		for (var i in fields) 
			this.check(fields[i], true);
		
		var iwarnings = [];
		
		for (var i in warnings) 
		{
			if (warnings[i]) 
			{
				if ( !iwarnings.length )
					document.getElementById(i).focus();
					
				iwarnings.push(warnings[i]);
			}
		}
		
		if (iwarnings.length) alert(iwarnings.join("\n"));
		
		return iwarnings.length;
	}
	
	this.checkWarnings	= function ()
	{
		NW.Dom.expireCache();
		
		if (!NW.Dom.select("label.fv_warn", this.form).length) 
		{
			for (var i in this.submits) this.submits[i].disabled = false;
		}
	}
	
	this.warn			= function ( el, ok, warning )
	{
		var el_label = NW.Dom.select("label[htmlFor=" + el.id + "]",this.form)[0];

		warnings[el.id] = warning ? warning.replace( "%L%", el_label.firstChild.nodeValue ) : warning;
	
		if ( ok )
		{
			el_label.className		= "";
			el_label.style.color	= "";
	
			this.checkWarnings();
		}
		else		
		{
			el_label.className		= "fv_warn";
			el_label.style.color	= "Crimson";
			
			for (var i in this.submits) this.submits[i].disabled = "disabled";
		}
	}
	
	this.check			= function ( el )
	{
		var ok;
		
		if ( NW.Dom.match( el, "textarea, input[type=text]" ) )
			el.value = el.value.replace(/^\s+|\s+$/g, "");
			
		if ( el.id !== "AppMI" && NW.Dom.match( el, "dd.req>*" ) )
		{
			ok = el.style.display === "none" || el.value !== "" && (el.nodeName !== "SELECT" || !(el.value == "Choose One" || el.value == "Select"));
			this.warn(el, ok, !ok ? "'%L%' must be entered." : null );
			if (!ok) return ok;
		}
			
		if ( el.value === "" ) return true;
		
		if ( NW.Dom.match( el, "input.fv_zipcode" ) )
		{
			ok = /^(\d{5}|\d{9})$/.test(el.value.replace(/\D/g, ""));
			this.warn(el, ok, !ok ? "'%L%' must be a valid 5 or 9 digit zip code." : null );
			return ok;
		}
			
		if ( NW.Dom.match( el, "input.fv_phone_ext" ) )
		{
			ok = /^\d{10}/.test(el.value.replace(/\D/g,"").replace(/^[0,1]/, ""));
			this.warn(el, ok, !ok ? "'%L%' must be a ten-digit phone number (plus extension, if applicable)." : null );
			return ok;
		}
			
		if ( NW.Dom.match( el, "input.fv_phone_no_ext" ) )
		{
			ok = /^\d{10}$/.test(el.value.replace(/\D/g,"").replace(/^[0,1]/, ""));
			this.warn(el, ok, !ok ? "'%L%' must be a ten-digit phone number." : null );
			return ok;
		}
			
		if ( NW.Dom.match( el, "input.fv_email" ) )
		{
			ok = /^[\w\-\.\+]+\@[a-z0-9\.\-]+\.[a-z0-9]{2,4}$/i.test(el.value);
			this.warn(el, ok, !ok ? "'%L%' must be a valid email address." : null );
			return ok;
		}
			
		if ( NW.Dom.match( el, "input[type=file]" ) )
		{
			ok = /\.(doc|txt)$/i.test(el.value);
			this.warn(el, ok, !ok ? "'%L%' must be in .doc or .txt format." : null );
			return ok;
		}
	}
	
	this.trimValue		= function ( el )
	{
		el.value = el.value.replace(/^\s+|\s+$/g, "");
	}
}

var nextStep = 
{
	init: function()
	{
		this.fv = new formValidator("contactform");
		
		for (var i in this.fv.submits) 
		{
			this.fv.submits[i].disabled = "disabled";
		}
		
		this.xhr = new XHR("getCounties.xml.php", this.fillCounties);
		NW.Event.appendDelegate("textarea, input, select", "blur", function()
		{
			nextStep.fv.check(this);
		}, nextStep.fv.form);
		setHandlers();
		
		// Note that while these start as single elements, after processing they will be nodeLists.
		this.fs = {};
		this.fs.Lic = document.getElementById("HasInsuranceLicenseYes");
		this.fs.Exp = document.getElementById("MgmtExperienceYes");
		
		for (var i in this.fs) 
		{
			while (this.fs[i].parentNode && this.fs[i].nodeName != "FIELDSET") 
			{
				this.fs[i] = this.fs[i].parentNode;
			}
			
			this.fs[i].id = i;
			this.fs[i] = NW.Dom.select("#" + i + " dt~dt,#" + i + " dd~dd", this.fs[i]);
			this.toggle(this.fs[i], false);
		}
		
		var tmp = document.getElementById("HowDidYouFindUs");
		
		while (tmp.parentNode && tmp.nodeName != "DD") 
			tmp = tmp.parentNode;
		
		tmp.id = "hdyfu";
		this.fs.RtO = NW.Dom.select("dd#hdyfu+dt,dd#hdyfu+dt+dd", tmp.parentNode)
		this.fs.RtF = NW.Dom.select("dd#hdyfu~dt~dt,dd#hdyfu~dd~dd", tmp.parentNode)
		this.toggle(this.fs.RtO, false);
		this.toggle(this.fs.RtF, false);
		
		this.selCounty 		= document.createElement("select");
		this.selCounty.id 	= "County";
		this.selCounty.name = "County";
		
		var counties = this.selCounty.options;
		counties[0] = new Option("Select One", "");
		
		var state = document.getElementById("AddressState");
		var county = document.getElementById("County");
		
		if (state.value)	this.fetchCounties(state.value);
		if (county.value)	this.county = county.value;
		
		county.parentNode.replaceChild(this.selCounty, county);
	},
	
	fetchCounties: function(state)
	{
		if (state !== "Select") this.xhr.send("state=" + state);
	},
	
	fillCounties: function(ok)
	{
		if (ok && nextStep.xhr.getXML().documentElement.getElementsByTagName("error").length === 0) 
		{
			var xdata = nextStep.xhr.getXML().documentElement.getElementsByTagName("county");
			var i = xdata.length;
			nextStep.selCounty.options.length = 1;
			var opt;
			
			while (i--) 
			{
				xdr = xdata[xdata.length - i - 1].childNodes[0].nodeValue;
				opt = new Option(xdr, xdr);
				if ( nextStep.county && xdr == nextStep.county ) opt.selected = "selected";
				nextStep.selCounty.options[nextStep.selCounty.options.length] = opt;
			}
		}
	},
	
	toggle: function(fss, show)
	{
		if (show) 
		{
			for (var i in fss) 
			{
				if ( isNaN(i) ) continue;
				fss[i].className 		= "req";
				fss[i].style.display 	= "";
			}
		}
		else 
		{
			for (var i in fss) 
			{
				if ( isNaN(i) ) continue;
				fss[i].className 		= "";
				fss[i].style.display 	= "none";
			}
		}
	}
};

NW.Event.appendHandler( window, "load", function(){ nextStep.init(); } );

var oHandlers = 
{
	"AddressState"				: { "blur"   : function(e){ nextStep.fetchCounties( this.value ) } 										},
	"contactform"				: { "submit" : function(e){ if (nextStep.fv.submit()) NW.Event.stop(e); }								},
	"HasInsuranceLicenseYes"	: { "click"  : function(e){ nextStep.toggle( nextStep.fs.Lic, true ) } 									},
	"HasInsuranceLicenseNo"		: { "click"  : function(e){ nextStep.toggle( nextStep.fs.Lic, false ) }									},
	"MgmtExperienceYes"			: { "click"  : function(e){ nextStep.toggle( nextStep.fs.Exp, true ) }									},
	"MgmtExperienceNo"			: { "click"  : function(e){ nextStep.toggle( nextStep.fs.Exp, false ) }									},
	"HowDidYouFindUs"			: { "change" : function(e){ nextStep.toggle( nextStep.fs.RtO, this.value == "Other" ); 
															nextStep.toggle( nextStep.fs.RtF, this.value == "Referred by Friend" ); }	}
};

function setHandlers()
{
	for (var i in oHandlers) 
	{
		if (document.getElementById(i)) 
		{
			for (var j in oHandlers[i]) 
			{
				NW.Event.appendHandler(document.getElementById(i), j, oHandlers[i][j]);
			}
		}
	}
}