jQuery(document).ready(function() {
// JS For validation v1.0 20110426
	
	jQuery.validator.addMethod("generalvalid", function(field, element) {
		if(jQuery(element).is('.unchanged.required')) return false;
		if(jQuery(element).is('.unchanged')) return true;
		
		return this.optional(element) || field.match(/^[\w\s\-~`\.\?!,:\'\"\$\^;&_\+\*@#\%\(\)\/=\\]*$/);
	}, "Allowed chars: a-z,0-9,()\\?/!$^@#&%+-_=,'.\"");	

	jQuery.validator.addMethod("firstlastname", function(field, element) {
		if(jQuery(element).is('.unchanged.required')) return false;
		if(jQuery(element).is('.unchanged')) return true;
		
		field = field.replace(/[\s]+/g, ""); 
		return this.optional(element) || field.match(/^[0-9A-Za-z\-_\.'\s\!\,]*$/);
	}, "Please specify a valid name");

	jQuery.validator.addMethod("phoneUS", function(phone_number, element) {
		if(jQuery(element).is('.unchanged.required')) return false;
		if(jQuery(element).is('.unchanged')) return true;
		
		phone_number = phone_number.replace(/[\s\(\)_\-]+/g, ""); 
		var phone_number_empty = phone_number.replace(/[x]+/g, "");
		return this.optional(element) || phone_number_empty.length == 0 || phone_number.length > 9 &&
			phone_number.match(/^(1-?)?(\([2-9]\d{2}\)|[2-9]\d{2})-?[2-9]\d{2}-?\d{4}(x\d{0,5})?$/);
	}, "Please specify a valid phone");

	jQuery.validator.addMethod("currency", function(field, element) {
		if(jQuery(element).is('.unchanged.required')) return false;
		if(jQuery(element).is('.unchanged')) return true;
		
		field = field.replace(/[\s\$_]+/g, ""); 
		return this.optional(element) || field.match(/^[0-9\.,]*$/);
	}, "Please specify a valid amount (ex: 20000)");

	jQuery.validator.addMethod("rate", function(field, element) {
		if(jQuery(element).is('.unchanged.required')) return false;
		if(jQuery(element).is('.unchanged')) return true;
		
		field = field.replace(/[\s\%_]+/g, ""); 
		return this.optional(element) || field.match(/^[0-9\.]*$/);
	}, "Please specify a valid rate (ex: 0.5)");

	jQuery.validator.addMethod("alphanumeric", function(field, element) {
		if(jQuery(element).is('.unchanged.required')) return false;
		if(jQuery(element).is('.unchanged')) return true;
		
		field = field.replace(/[\s]+/g, ""); 
		return this.optional(element) || field.match(/^[a-zA-Z0-9]*$/);
	}, "Please specify a alpanumeric value");

	jQuery.validator.addMethod("zip", function(field, element) {
		if(jQuery(element).is('.unchanged.required')) return false;
		if(jQuery(element).is('.unchanged')) return true;
		
		field = field.replace(/[\s_]+/g, ""); 
		return this.optional(element) || field.length == 0 || field.match(/^\d{5}([\-]\d{4})?$/);
	}, "Please specify a valid zip code (5-digit)");

	jQuery.validator.addMethod("date", function(field, element) {
		if(jQuery(element).is('.unchanged.required')) return false;
		if(jQuery(element).is('.unchanged')) return true;
		
		field = field.replace(/[\s_]+/g, ""); 
		var digits = field.replace(/[\s_\/]+/g, ""); 
		var res = field.match(/^(0[1-9]|1[0-2])\/(0[1-9]|[1-2][0-9]|30|31)\/(19\d{2}|20\d{2}|\d{2})$/);
		return this.optional(element) || digits.length == 0 || field.match(/^(0[1-9]|1[0-2])\/(0[1-9]|[1-2][0-9]|30|31)\/(19\d{2}|20\d{2}|\d{2})$/);
	}, "Please specify a valid date (mm/dd/yyyy)");

// Start Validation Plugin for all forms on the page
// also find elements that have .submit_form and assign safe submit action
jQuery("form").not('.novalidation').each(function(){
		
		jQuery(this).find('.submit_form').click(function(){
			jQuery(this).closest('form').submit(); //find form it should submit
			return false;                     // so that viewport doesnt jump to start of page
		})

		
		jQuery(this).validate({
			
			
			submitHandler: function(form) {
			//Before sending, clean default-values in inputs that have it
				jQuery('.default.unchanged').val('');
				form.submit();
			},
			

			errorElement: "div",
			wrapper: "div",  // a wrapper around the error message
			errorPlacement: function(error, element){
				// Place error labels above the input
				error.insertAfter(element);
				
				error.addClass('error-message'); // add a class to the wrapper
				
				//get width of error label to understand how much space is available to the right
				var totalWidthAvailable = error.outerWidth();
				var toTheRightAvailable = totalWidthAvailable - element.outerWidth();
				
				// apply general error css
				error.css({'opacity' : 0.9});
				error.attr('title','Click to hide error message');
				error.css('position', 'absolute');
				
				// see how much space is needed to display error
				var toTheRightNeeded = error.outerWidth();

				// get how high is the input
				var elementHeight = element.outerHeight();
				
				//decide where to display the error label
				if (toTheRightAvailable < toTheRightNeeded){  //place error above the input
				
					error.addClass('down');
					var position = element.position();
					error.css('left', position.left + 2);  // after we do this, height can change (could be forged to go two lines in height)
					document.body.className = document.body.className;
					var errorHeight = error.outerHeight(); 
					error.css('top', position.top - errorHeight + 3);
						
					
					
					
				}else{  // place error to the left of the input
					error.addClass('left');
					var position = element.position();
					error.css('left', position.left + element.outerWidth() - 3);  //element.innerWidth()
					var errorHeight = error.outerHeight(); // after we do this, height can change (could be forged to go two lines in height)
					error.css('top', position.top);
					if (elementHeight < errorHeight) error.find(':first-child').css('padding', '1px');					
				}
				

				//error.css('left', position.left + 2);  //element.innerWidth()
				//error.css('top', position.top - errorHeight + 3);
				
			
				// Assign click event to close error label
				error.click(function(event){
					jQuery(this).hide(); 
				});
            }

		})});
			

/* Assign MASKS to inputs following naming convention
 * you can cancel masking by specifying .nomask class for any input
 * you can cancel validation by specifying .novalidation for any input
 *
 * === main inputs (predeffined) ===
 */
	//maxlength in case you din tspecify it is 500
	jQuery("form input:not([maxlength]), form textarea:not([maxlength])").attr('maxlength','500');
	
	jQuery("form input, form textarea").not('.novalidation').addClass('generalvalid');//!!! general validation for all fields (to make sure it is the same as on the php side)
	jQuery("form input[name='first_name']").not('.novalidation').attr('maxlength','100').addClass('firstlastname');
	jQuery("form input[name='last_name']").not('.novalidation').attr('maxlength','100').addClass('firstlastname');
	jQuery("form input[name='email']").not('.novalidation').addClass('email');
	
	var dom_phones_main = jQuery("form input[name='phone_cell'], form input[name='phone_work'], form input[name='phone_home']");
	dom_phones_main.not('.nomask').mask("(999) 999-9999? x99999");
	dom_phones_main.not('.novalidation').addClass('phoneUS');
	

	var dom_zip = jQuery("form input[name*='zip']");
	dom_zip.not('.nomask').mask("99999");
	dom_zip.not('.novalidation').addClass('zip');

 //	=== secondary, that have a type (have preffix) ====
	var dom_emails = jQuery("form input[name^='_em_']");
	dom_emails.not('.novalidation').addClass('email');
	
	var dom_dates = jQuery("form input[name^='_dt_']");
	dom_dates.not('.nomask').mask("99/99/9999");
	dom_dates.not('.novalidation').addClass('date');
	
	var dom_currencies = jQuery("form input[name^='_cr_']");
	dom_currencies.not('.nomask').mask("$ ?99999999");
	dom_currencies.not('.novalidation').addClass('currency');
	
	var dom_rates = jQuery("form input[name^='_rt_']");
	dom_rates.not('.nomask').mask("?9.99");
	dom_rates.not('.novalidation').addClass('rate');
	
	var dom_phoneUS = jQuery("form input[name^='_ph_']").not("input[name$=']']");
	dom_phoneUS.not('.nomask').mask("(999) 999-9999? x99999");
	dom_phoneUS.not('.novalidation').addClass('phoneUS');//,{placeholder:" "}); 
});
