/**
 * formValidate
 * The primary form validation routine, ensuring fields within li.Required have a value.
 * Calls validationRules for each field.
 */
(function($){
	$.fn.formvalidate = function( callback ){
		return this.each( function(){

			var self	= this;
			self.ok		= true;

			// if the form is set to not validate, return false
			if( $(self).is('.no-validate') ){
				return false;
			}

			//------------------------------------------
			// internal functions
			//------------------------------------------

			self.rules = {
				// default validator
				'notNull': function( elm ){
					var v = $(elm).val();
					switch( elm.type.toLowerCase() ){
						case 'checkbox':
						case 'radio':
							// grab all radio/checkboxes with this name and see if one of them is checked
							return $(self).find('[name="' + $(elm).attr('name') + '"]').is(':checked');
							break;
						case 'select':
						case 'select-one':
							return ( v ? v.length > 0 : false );
							break;
						default:
							return ( v ? v.length > 0 : false );
					}
					return true;
				},

				// default validator
				'notNullOrZero': function( elm ){
					var v = $(elm).val();
					switch( elm.type.toLowerCase() ){
						case 'checkbox':
						case 'radio':
							// grab all radio/checkboxes with this name and see if one of them is checked
							return self.find('[name="' + $(elm).attr('name') + '"]').is(':checked');
							break;
						case 'select':
						case 'select-one':
							return ( v ? v.length > 0 && v != '0' : false );
							break;
						default:
							return ( v ? v.length > 0 && v != '0' : false );
					}
					return true;
				},

				// Checkout-Address.xml
				'email': function( elm ){
					var v = $(elm).val();
					// can't be null
					if( !this.notNull(elm) ){
						return false;
					}
					// must be the correct format
					var emailReg = "^[\\w-_\.]*[\\w-_\.]\@[\\w]\.+[\\w]+[\\w]$";
					var regex = new RegExp(emailReg);
					if( !regex.test(v) ){
						//this.msg.push( ' -- Your email address does not appear to be a valid email.' );
						return false;
					}
					return true;
				},

				// Checkout-Address.xml
				'emailmatch': function( elm ){
					var v = $(elm).val();
					// must match email if there is one ... assume the first email field is one <li> prior to this one
					var email = $(elm).parent().prev().find('input:eq(0)');
					if( email.length > 0 ){
						if( v != email.val() ){
							//this.msg.push( ' -- Your email addresses must match each other.' );
							return false;
						}
					}
					return true;
				}
			}

			self.check = function(){
				// start with a clean slate
				self.ok = true;
				// check all required fields which are visible
				$('li.required :input',self).filter( function(){ return !$(this).parents().not(':visible')[0]; } ).each( function(){
					// get the parent field
					var vfield = $(this).parents('li:eq(0)')[0];
					// remove flags
					vfield.resetflags();
					// determine the validator to use
					var vfunc = $(vfield).attr('alt') || 'notNull';
					// make sure there's a rule for vfunc
					if( self.rules[ vfunc ] ){
						if( !self.rules[ vfunc ].apply( self.rules, new Array(this) ) ){
							self.ok = false;
							vfield.missing();
						}
					}
				});
				return self.ok;
			}

			self.block = function(){
				// set the "submitting" flag so we don't do it twice
				$(self).data('status', 'submitting');
				// disable all buttons and fade out the form
				$(self).data('buttons', $('button:enabled', self));
				$(self).data('buttons').attr('disabled', 'disabled');
				$(self).css('opacity', '0.5');
			}

			self.unblock = function(){
				$(self).data('status', '');
				$(self).data('buttons').removeAttr('disabled');
				$(self).css('opacity', '1');
			}

			self.go = function( event, callbackoverride ){
				if($(self).data('status') == 'submitting') return false;
				// disable further user interaction
				self.block();
				// process everything
				if( $.msg ) $.msg('reset');
				if( !self.check() ){
					if( $.msg ) $.msg( 'error', 'Please handle the items in red, then try again.' );
					self.unblock();
					return false;
				}
				if( $.msg ) $.msg( 'wait', 'Please wait while we receive your information...' );
				// set up a "complete" function
				var complete = function(payload){
					// return the form to full opacity
					self.unblock();
					// run callback
					var finalcallback = callbackoverride ? callbackoverride : callback;
					if( $.isFunction(finalcallback) ){
						return finalcallback(payload);
					}
					// if no callback, return true so the browser will behave as it would if we hadn't used ajax
					return true;
				}
				$(self).ajaxSubmit({success: complete});
				return false;
			}

			//------------------------------------------
			// run on load
			//------------------------------------------

			// apply field plugin
			$('fieldset ol > li, .more',self).field();

			// set all forms to submit on enter
			// turn off submit via enter key, per r.fox 20090203
			$(self).keypress( function(e){
				// allow any keys if we're in a textarea
				if( (e.target.nodeName.toLowerCase() != 'textarea') && (e.keyCode == 13) ) return false;
			});
			// main submit function, overriding browser's default behavior
			$(self).submit( self.go );

		});
	}
})(jQuery);
