var ONEHAT = ONEHAT || {
	browser: {},
	util: {},
	widget: {}
};
if (YAHOO) {
	var YUE = YAHOO.util.Event;
	ONEHAT.widget.formValidator = function() {
		var obj = {
			init: function() {
				var oThis = this;
				
				// get elements to work with
				this.form = document.getElementById('contactForm');
				
				// customer
				this.cName = this.form.Customer_Name;
				this.cEmail = this.form.Customer_E_mail_Address;
				this.cAddress1 = this.form.Customer_Street_Address_1;
				this.cAddress2 = this.form.Customer_Street_Address_2;
				this.cCity = this.form.Customer_City;
				this.cState = this.form.Customer_State_Province;
				this.cZip = this.form.Customer_Zip_Postal_Code;
				this.cCountry = this.form.Customer_Country;
				this.cPhone = this.form.Customer_Daytime_Phone;
				this.shipHome = this.form.ship_to_home;
				
				// church
				this.chName = this.form.Church_Name;
				this.chAddress1 = this.form.Church_Street_Address_1;
				this.chAddress2 = this.form.Church_Street_Address_2;
				this.chCity = this.form.Church_City;
				this.chState = this.form.Church_State_Province;
				this.chZip = this.form.Church_Zip_Postal_Code;
				this.chCountry = this.form.Church_Country;
				this.chPhone = this.form.Church_Daytime_Phone;
				
				this.customerForm = document.getElementById('customerForm');
				
				// set initial state
				this.customerVerified = window.customerVerified;
				if (this.shipHome.value == 'Yes') {
					YAHOO.util.Dom.removeClass(this.customerForm, 'hide');
				} else {
					YAHOO.util.Dom.addClass(this.customerForm, 'hide');
				}
				
				
				// assign events
				YUE.addListener(this.shipHome, 'change', function(e) {
					oThis.handleAddressChange(e);
				});				
				YUE.addListener(this.form, 'submit', function(e) {
					oThis.handleSubmit(e);
				});
				
				
				var n, form;
				// hijack all Paypal forms
				for(n = 0; n < document.forms.length; n++) {
					form = document.forms[n];
					if (form.target == 'paypal') {
						YUE.addListener(form, 'submit', function(e) {
							oThis.hijackPaypal(e);
						});
					}
				}
			},
			
			handleAddressChange: function(e) {
				if (this.shipHome.value == 'Yes') {
					YAHOO.util.Dom.removeClass(this.customerForm, 'hide');
				} else {
					YAHOO.util.Dom.addClass(this.customerForm, 'hide');
				}
			},
			
			hijackPaypal: function(e) {
				if (!this.customerVerified) {
					if (YUE.stopEvent) { YUE.stopEvent(e); }
					YAHOO.util.Dom.removeClass(document.getElementById('verificationContainer'), 'hide');
					
					alert('Please fill out the form at the top before adding items to your cart.');
				}
			},
			
			handleSubmit: function(e) {
				var oThis = this;
				
				if (YUE.stopEvent) { YUE.stopEvent(e); }
				
				try {
					// Validate that form at top of page has been filled out
					// customer
					if (!this.cName.value.match(this.patterns.name.pattern)) { throw new Error('Please enter your name.'); }
					if (!this.cEmail.value.match(this.patterns.email.pattern)) { throw new Error('Please enter your email.'); }

					// church
					if (!this.chName.value.match(this.patterns.name.pattern)) { throw new Error('Please enter the church\'s name.'); }
					if (!this.chAddress1.value.match(this.patterns.street.pattern)) { throw new Error('Please enter the church\'s street address.'); }
					if (this.chAddress2.value && !this.chAddress2.value.match(this.patterns.street.pattern)) { throw new Error('Please enter the church\'s street address 2.'); }
					if (!this.chCity.value.match(this.patterns.name.pattern)) { throw new Error('Please enter the church\'s city.'); }
					if (!this.chState.value.match(this.patterns.territory.pattern)) { throw new Error('Please select the church\'s state/province.'); }
					if (!this.chZip.value.match(this.patterns.zip.pattern)) { throw new Error('Please enter the church\'s zip/postal code.'); }
					if (!this.chCountry.value.match(this.patterns.name.pattern)) { throw new Error('Please enter the church\'s country.'); }
					if (!this.chPhone.value.match(this.patterns.phone.pattern)) { throw new Error('Please enter the church\'s phone number.'); }
	
					if (this.shipHome.value == 'Yes') {
						if (!this.cAddress1.value.match(this.patterns.street.pattern)) { throw new Error('Please enter your street address.'); }
						if (this.cAddress2.value && !this.chAddress2.value.match(this.patterns.street.pattern)) { throw new Error('Please enter your street address 2.'); }
						if (!this.cCity.value.match(this.patterns.name.pattern)) { throw new Error('Please enter your city.'); }
						if (!this.cState.value.match(this.patterns.territory.pattern)) { throw new Error('Please select your state/province.'); }
						if (!this.cZip.value.match(this.patterns.zip.pattern)) { throw new Error('Please enter your zip/postal code.'); }
						if (!this.cCountry.value.match(this.patterns.name.pattern)) { throw new Error('Please enter your country.'); }
						if (!this.cPhone.value.match(this.patterns.phone.pattern)) { throw new Error('Please enter your phone number.'); }
					}
					
					// Send Ajax request to submit customer form
					YAHOO.util.Connect.setForm(this.form); 
					YAHOO.util.Connect.asyncRequest('POST', 'handlers/handleCustomerForm.php', {
						success: function(o) {
							var data = eval(o.responseText);
							if (data.status === 'OK') {
								this.customerVerified = true;
								YAHOO.util.Dom.removeClass(document.getElementById('materialsContainer'), 'hide');
								YAHOO.util.Dom.addClass(document.getElementById('verificationContainer'), 'hide');
							} else {
								alert(data.message);
							}
						}, 
						failure: function(o) {
							alert('There was a problem submitting the form. Materials cannot be purchased at this time.');
						}, 
						scope: this
					});
					
				} catch (err) {
					alert('You must fill out the form completely. ' + err.message);
				}
				
			},
			
			patterns: {
			   	alpha: {
			   		pattern: /^[a-z]{1,}$/i,
			   		errmsg: 'only letters (no spaces or special characters)'
			   	},
			   	alnum: {
			   		pattern: /^[a-z0-9]{1,}$/i,
			   		errmsg: 'only letters or numbers'
			   	},
			   	alnumSpace: {
			   		pattern: /^[\w\s]{1,}$/,
			   		errmsg: 'only letters, numbers, spaces, or the underscore'
			   	},
			   	alnumUnderscore: {
			   		pattern: /^[\w]{1,}$/,
			   		errmsg: 'only letters, numbers, or the underscore'
			   	},
			   	digit: {
			   		pattern: /^[0-9]{1,}$/,
			   		errmsg: 'only numbers'
			   	},
			   	yesno: {
			   		pattern: /^1|0|y|n|yes|no$/i,
			   		errmsg: 'yes or no'
			   	},
			   	bool: {
			   		pattern: /^1|0|true|false$/i,
			   		errmsg: 'a boolean value'
			   	},
			   	words: {
			   		pattern: /^[a-z\s]$/i,
			   		errmsg: 'letters or spaces'
			   	},
			   	title: {
			   		pattern: /^[\w\s\-\/\'\",\.!]{1,}$/,
			   		errmsg: 'only letters, numbers, dashes, quotes, exclamation marks, or the underscore'
			   	},
			   	message: {
			   		pattern: /^[\w\s\.\,\'\"\?!]{1,}$/,
			   		errmsg: 'letters, numbers, or spaces'
			   	},
			   	paragraph: {
			   		pattern: /^[\w\s\.\(\)\'\"\!\?\$\/,:;&@<>#\-]{1,}$/,
			   		errmsg: 'letters, numbers, spaces, or standard punctuation'
			   	},
			   	email: {
			   		pattern: /^([\w\.\-\_]+)@[a-zA-Z0-9\.\-]+\.[a-zA-Z]{2,4}$/,
			   		errmsg: 'a valid email address'
			   	},
			   	url: {
			   		pattern: new RegExp('^' +
				   		'((http|https|ftp|ftps|news)\:\/\/|~\/|\/)?' + // protocol
						'([\\w\\.]+:[\\w\\.]+@)?' + // username:password@
						'([a-zA-Z]{1}([\\w\\-]+\\.)+([\\w]{2,5}))?' + // domain
						'(:[0-9]{1,5})?' + // port
						'((\/?[\\w~]+\/?)+|\/?)' + // directory
						'(\\w+\.[\\w]{2,4})?' + // file & extension
						'((\\?\\w+=[\\w\\.%]+)?((&|&amp;)\\w+=[\\w\\.%]+)*)?' + // query string
						'(#[\\w\\-]+)?' + // anchor
						'$', 'i'),
					errmsg: 'a valid URL'
				},
				zip: {
					pattern: /^(([0-9]{5})(-[0-9]{4})?)|(([a-z][0-9][a-z])[\s\-]?([0-9][a-z][0-9]))$/i, // US or Candaian zip code
					errmsg: 'a valid zip code'
				},
				loose: {
					pattern: /^.+$/,
					errmsg: 'anything'
				},
				stateAbbr: {
					pattern: /^A[KLRZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY]$/,
					errmsg: 'a valid US state abbreviation'
				},
				street: {
					pattern: /^[\w\s\.\-\/]{1,128}$/,
					errmsg: 'a valid US street address'
				},
				phone: {
					pattern: /^(\(?[0-9]{3}\)?)?[\s\.\-]?[0-9]{3}[\s\.\-]?[0-9]{4}$/,
					errmsg: 'a valid US phone number'
				},
				ip: {
					pattern: /^(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])$/,
					errmsg: 'a valid IP address'
				},
				html: {
					pattern: /.*/, // /(<\/?)(?i:(?<element>a(bbr|cronym|ddress|pplet|rea)?|b(ase(font)?|do|ig|lockquote|ody|r|utton)?|c(aption|enter|ite|(o(de|l(group)?)))|d(d|el|fn|i(r|v)|l|t)|em|f(ieldset|o(nt|rm)|rame(set)?)|h([1-6]|ead|r|tml)|i(frame|mg|n(put|s)|sindex)?|kbd|l(abel|egend|i(nk)?)|m(ap|e(nu|ta))|no(frames|script)|o(bject|l|pt(group|ion))|p(aram|re)?|q|s(amp|cript|elect|mall|pan|t(r(ike|ong)|yle)|u(b|p))|t(able|body|d|extarea|foot|h|itle|r|t)|u(l)?|var))(\s(?<attr>.+?))*>/, // Matches all valid HTML 4.01
					errmsg: 'only html tags and content'
				},
				file: {
					pattern: /^[\w\s\.\-_]*\.[a-zA-Z0-9](3)$/,
					errmsg: 'a file with html content (.php, .htm, .html, .txt)'
				},
				'date ISO-8601': {
					pattern: /^([[:digit:]]{4})[\/-]{1}([[:digit:]]{1,2})[\/-]{1}([[:digit:]]{1,2})$/,
					errmsg: 'a date in the form YYYY/MM/DD or YYYY-MM-DD'
				},
				name: {
					pattern: /^[\w\s\.\']{1,}$/,
					errmsg: 'letters, numbers, spaces, the period, or the apostrophe'
				},
				territory: {
					pattern: /^A[BKLRSZ]|BC|C[AOT]|D[CE]|F[LM]|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ABDEINOST]|NMI|N[BCDEHJLMSTUVY]|O[HKNR]|P[AER]|QC|RI|S[CDK]|T[NX]|UT|V[AIT]|W[AIVY]|YT$/,
					errmsg: 'a valid US state abbreviation, territory, or Canadian province'
				}
			}
		};
		obj.init();
		return obj;
	}();
}
