/*
 * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
 *
 * Uses the built in easing capabilities added In jQuery 1.1
 * to offer multiple easing options
 *
 * TERMS OF USE - jQuery Easing
 * 
 * Open source under the BSD License. 
 * 
 * Copyright Â© 2008 George McGinley Smith
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification, 
 * are permitted provided that the following conditions are met:
 * 
 * Redistributions of source code must retain the above copyright notice, this list of 
 * conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice, this list 
 * of conditions and the following disclaimer in the documentation and/or other materials 
 * provided with the distribution.
 * 
 * Neither the name of the author nor the names of contributors may be used to endorse 
 * or promote products derived from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 *  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
 * OF THE POSSIBILITY OF SUCH DAMAGE. 
 *
*/

// t: current time, b: begInnIng value, c: change In value, d: duration
jQuery.easing['jswing'] = jQuery.easing['swing'];

jQuery.extend( jQuery.easing,
{
	def: 'easeOutQuad',
	swing: function (x, t, b, c, d) {
		//alert(jQuery.easing.default);
		return jQuery.easing[jQuery.easing.def](x, t, b, c, d);
	},
	easeInQuad: function (x, t, b, c, d) {
		return c*(t/=d)*t + b;
	},
	easeOutQuad: function (x, t, b, c, d) {
		return -c *(t/=d)*(t-2) + b;
	},
	easeInOutQuad: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t + b;
		return -c/2 * ((--t)*(t-2) - 1) + b;
	},
	easeInCubic: function (x, t, b, c, d) {
		return c*(t/=d)*t*t + b;
	},
	easeOutCubic: function (x, t, b, c, d) {
		return c*((t=t/d-1)*t*t + 1) + b;
	},
	easeInOutCubic: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t*t + b;
		return c/2*((t-=2)*t*t + 2) + b;
	},
	easeInQuart: function (x, t, b, c, d) {
		return c*(t/=d)*t*t*t + b;
	},
	easeOutQuart: function (x, t, b, c, d) {
		return -c * ((t=t/d-1)*t*t*t - 1) + b;
	},
	easeInOutQuart: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
		return -c/2 * ((t-=2)*t*t*t - 2) + b;
	},
	easeInQuint: function (x, t, b, c, d) {
		return c*(t/=d)*t*t*t*t + b;
	},
	easeOutQuint: function (x, t, b, c, d) {
		return c*((t=t/d-1)*t*t*t*t + 1) + b;
	},
	easeInOutQuint: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
		return c/2*((t-=2)*t*t*t*t + 2) + b;
	},
	easeInSine: function (x, t, b, c, d) {
		return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
	},
	easeOutSine: function (x, t, b, c, d) {
		return c * Math.sin(t/d * (Math.PI/2)) + b;
	},
	easeInOutSine: function (x, t, b, c, d) {
		return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
	},
	easeInExpo: function (x, t, b, c, d) {
		return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
	},
	easeOutExpo: function (x, t, b, c, d) {
		return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
	},
	easeInOutExpo: function (x, t, b, c, d) {
		if (t==0) return b;
		if (t==d) return b+c;
		if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
		return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
	},
	easeInCirc: function (x, t, b, c, d) {
		return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
	},
	easeOutCirc: function (x, t, b, c, d) {
		return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
	},
	easeInOutCirc: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
		return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
	},
	easeInElastic: function (x, t, b, c, d) {
		var s=1.70158;var p=0;var a=c;
		if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
		if (a < Math.abs(c)) { a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin (c/a);
		return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
	},
	easeOutElastic: function (x, t, b, c, d) {
		var s=1.70158;var p=0;var a=c;
		if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
		if (a < Math.abs(c)) { a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin (c/a);
		return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
	},
	easeInOutElastic: function (x, t, b, c, d) {
		var s=1.70158;var p=0;var a=c;
		if (t==0) return b;  if ((t/=d/2)==2) return b+c;  if (!p) p=d*(.3*1.5);
		if (a < Math.abs(c)) { a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin (c/a);
		if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
		return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
	},
	easeInBack: function (x, t, b, c, d, s) {
		if (s == undefined) s = 1.70158;
		return c*(t/=d)*t*((s+1)*t - s) + b;
	},
	easeOutBack: function (x, t, b, c, d, s) {
		if (s == undefined) s = 1.70158;
		return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
	},
	easeInOutBack: function (x, t, b, c, d, s) {
		if (s == undefined) s = 1.70158; 
		if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
		return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
	},
	easeInBounce: function (x, t, b, c, d) {
		return c - jQuery.easing.easeOutBounce (x, d-t, 0, c, d) + b;
	},
	easeOutBounce: function (x, t, b, c, d) {
		if ((t/=d) < (1/2.75)) {
			return c*(7.5625*t*t) + b;
		} else if (t < (2/2.75)) {
			return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
		} else if (t < (2.5/2.75)) {
			return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
		} else {
			return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
		}
	},
	easeInOutBounce: function (x, t, b, c, d) {
		if (t < d/2) return jQuery.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
		return jQuery.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
	}
});

/*
 *
 * TERMS OF USE - EASING EQUATIONS
 * 
 * Open source under the BSD License. 
 * 
 * Copyright Â© 2001 Robert Penner
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification, 
 * are permitted provided that the following conditions are met:
 * 
 * Redistributions of source code must retain the above copyright notice, this list of 
 * conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice, this list 
 * of conditions and the following disclaimer in the documentation and/or other materials 
 * provided with the distribution.
 * 
 * Neither the name of the author nor the names of contributors may be used to endorse 
 * or promote products derived from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 *  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
 * OF THE POSSIBILITY OF SUCH DAMAGE. 
 *
 */


(function($) {
	
	function validateEmail(email) {
	    if(email.length <= 0) {
		  return false;
		}
	    var splitted = email.match(/^(.+)@(.+)$/);
	    if(splitted == null) return false;
	    if(splitted[1] != null ) {
			var regexp_user=/^\"?[\w-_\.]*\"?$/;
			if(splitted[1].match(regexp_user) == null) return false;
	    }
	    if(splitted[2] != null) {
			var regexp_domain=/^[\w-\.]*\.[A-Za-z]{2,4}$/;
			if(splitted[2].match(regexp_domain) == null) {
				var regexp_ip =/^\[\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\]$/;
				if(splitted[2].match(regexp_ip) == null) return false;
			}
			return true;
	    }
		return false;
	}
	
	var fadeId = null;
	function showError(message, obj){
		$('.validate_error').removeClass('validate_error');
		obj.addClass('validate_error');
		
		if($("#error").length <= 0) {
			$("body").append('<div id="error"><div></div></div>');
			$("#error").click(hideError);
		}
		
		positionError(obj);
		$(window).bind("resize", function(){
			positionError(obj);
		});
		$("#error div").html(message);
		if ($("#error").css("display") != "block" || $("#error").css("display") == "block" && $("#error").css("opacity") < 1) {
			$('#error').css('left', (parseInt($('#error').css('left'))+20)+'px').css('opacity',0).show().animate({left:(parseInt($('#error').css('left'))-20)+'px',opacity:1},300,'easeOutBounce');
		}
		clearTimeout(fadeId);
		fadeId = setTimeout(hideError,6000,'slow');
	}
	
	function hideError(speed) {
		if(speed == 0) {
			$("#error").hide();
		} else {
			if(speed==undefined) {speed='slow'}
			$("#error").fadeOut(speed);
		}
		$(window).unbind("resize");
	}
	
	function positionError(obj) {
		var offset = obj.offset();
		$('#error').css('left', ((offset.left+obj.outerWidth())-5)+'px');
		$('#error').css('top', offset.top+'px');
	}

	$.fn.validate = function() {
		var form = $(this);
		var valid = true;
		if(form.data('fields')) {
			
			fields = form.data('fields');

			var form = $(this);
			validate_loop:
			for(var j=0,jlen=fields.length;j<jlen;j++){
				
				var field_selection = form.find("[name="+fields[j].field+"]"); 
				
				for(var x=0,l=field_selection.size(); x<l; x++) { //sometimes fields will have the same name (php arrays of fields etc) eg. first_name[], $.each won't work here because of the breaks 
						
					var field = field_selection.eq(x);

					if(field.parents(':hidden').size()==0) { //only validate fields with parents that are visible
					
						val = field.val().replace(/^\s\s*/, '').replace(/\s\s*$/, ''); //get value and trim white space
						if(field.attr('type')=='checkbox' && !field.is(":checked")) {
							val = '';
						}
						
						if(field.is(':visible')) { //only some fields must be visible to validate
							//required
							if(fields[j].date == undefined && fields[j].required != undefined && val == '') {
								valid = false;
								showError('this is required',field);
								field.focus();
								break validate_loop;
							}
							
							//emails
							if(fields[j].email != undefined && val !='' && validateEmail(val) == false) {
								valid = false;
								showError('please enter a valid email address',field);
								field.focus();
								break validate_loop;
							}
							
							//email confirmation
							if(fields[j].emailconfirm != undefined) {
								if(val!='' && validateEmail(val) == false) {
									valid = false;
									showError('please enter a valid email address',field);
									field.focus();
									break validate_loop;
								} else if(val != form.find('input[name='+fields[j].emailconfirm+']').val()) {
									valid = false;
									showError('Confirmation email doesn\'t match',field);
									field.focus();
									break validate_loop;
								}
							}
							
							//minlength
							if(fields[j].minlength != undefined && val.length > 0 && val.length < fields[j].minlength) {
								valid = false;
								showError('a minimum of '+fields[j].minlength+' characters is required',field);
								field.focus();
								break validate_loop;
							}
							
							//url
							var regexp = /^(https?|ftp):\/\/([A-Z0-9][A-Z0-9_-]*(?:.[A-Z0-9][A-Z0-9_-]*)+):?(d+)?\/?/i;
							if(fields[j].url != undefined && val.length > 0 && val.match(regexp) == null) {
								valid = false;
								showError('Please include a valid URL',field);
								field.focus();
								break validate_loop;
							}
							
							//number
							if(fields[j].number != undefined) {
								if(fields[j].max != undefined && val > fields[j].max) {
									valid = false;
									showError('a maximum of '+fields[j].max+' is required',field);
									field.focus();
									break validate_loop;
								}
								if(fields[j].min != undefined && val < fields[j].min) {
									valid = false;
									showError('a minimum of '+fields[j].min+' is required',field);
									field.focus();
									break validate_loop;
								}
							}
							
						}
					};	
							
		
					//date required or incomplete
					if(fields[j].date != undefined && val == '') {
						y = field.prev();
						m = field.prev().prev();
						d = field.prev().prev().prev();
						
						if(fields[j].required != undefined) {
							if(d.val()=='') {
								d.focus();
							} else if(m.val()=='') {
								m.focus();
							} else if(y.val()=='') {
								y.focus();
							}
							valid = false;
							showError('this is required',y);
							break;
						} else if(d.val() != '' || m.val() != '' || y.val() != '') {	
							if(d.val()=='') {
								d.focus();
							} else if(m.val()=='') {
								m.focus();
							} else if(y.val()=='') {
								y.focus();
							}
							showError('please enter a complete date',y);
							valid = false;
							break;
						}
					}
					
					//time required
					if(fields[j].time != undefined && val == '') {
						
						s = field.prev();
						m = field.prev().prev();
						h = field.prev().prev().prev();
						v = field.prevAll("select:visible"); //find previous visible field
						
						if(fields[j].required != undefined) {
							if(h.val()=='') {
								h.focus();
							}
							if(m.val()=='') {
								m.focus();
							}
							if(s.val()=='') {
								s.focus();
							}
							showError('this is required',v);
							valid = false;
							break;
						} else if(s.val() != '' || m.val() != '' || h.val() != '') {
							if(h.val()=='') {
								h.focus();
							} else if(m.val()=='') {
								m.focus();
							} else if(s.val()=='') {
								s.focus();
							}
							showError('please enter a complete time',v);
							valid = false;
							break;
						}
					};					
				};
			};
		}
		return valid;
	}
	
	$.fn.addValidation = function(fields) {
		var new_fields = current_fields = $(this).data('fields');
		for(var i=0,l=fields.length;i<l;i++) {
			var insert = true;
			for(var j=0,l1=current_fields.length;j<l1;j++) {
				if(fields[i].field==current_fields[j].field) {
					insert = false;
					break;
				}
			}
			if(insert) {
				new_fields.push(fields[i]);
			}
		}
		$(this).data('fields',new_fields)
		this.validation(new_fields);
	};

	$.fn.validation = function(fields) {
		
		this.each(function() {
			
			var form = $(this);
			if(form.data('fields') == undefined) {
				form.data('fields',fields);
			}
	
			form.bind("submit",$(this).validate);
			
			$(fields).each(function(){
				
				var field_selection = form.find("[name="+this.field+"]"); 
				
				for(var x=0,l=field_selection.size(); x<l; x++) { //sometimes fields will have the same name (php arrays of fields etc) eg. first_name[], $.each won't work here because of the breaks 
						
					var field = field_selection.eq(x);

					if(field.data('validation') == undefined) {

						var val = field.val();
						
						//date
						if(this.date != undefined) {
	
							field.data('validation','date');
							var input = field.hide();
							
							var select_year = select_month = select_day = '';
							var value = input.val().match(/([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})/);
							if(value != null) {
								select_year = parseInt(value[1],10);
								select_month = parseInt(value[2],10);
								select_day = parseInt(value[3],10);
							}
							
							var dateregex = new RegExp('([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})[|]([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})');
							var range = this.range.match(dateregex);
							
							var start_year = parseInt(range[1],10);
							var start_month = parseInt(range[2],10);
							var start_day = parseInt(range[3],10);
							var end_year = parseInt(range[4],10);
							var end_month = parseInt(range[5],10);
							var end_day = parseInt(range[6],10);
							
							var html = '<select><option></option>';
							for(var i=1;i<=31;i++) {
								html += '<option';
								if(select_day==i) {
									html += ' selected="selected"';
								}
								html += '>'+i+'</option>';
							}
							html += '</select>';
							
							html += '<select><option></option>';
							var m_names = new Array("January","February","March","April","May","June","July","August","September","October","November","December");
							for(var i=1;i<=12;i++) {
								html += '<option';
								if(select_month==i) {
									html += ' selected="selected"';
								}
								html += ' value="'+i+'">'+m_names[i-1]+'</option>';
							}
							html += '</select>';
							
							html += '<select><option></option>';;
							for(var i=end_year;i>=start_year;i--) {
								html += '<option';
								if(select_year==i) {
									html += ' selected="selected"';
								}
								html += '>'+i+'</option>';	
							}
							html += '</select>';
							
							input.before(html);
							
							input.prevAll('select:lt(3)').change(function(){
		
								var input = $(this).nextAll('input:first');
								var year = input.prev();
								var month = input.prev().prev();
								var day = input.prev().prev().prev();
								
								var y = year.val();
								var m = month.val();
								var d = day.val();
								var val = '';
								
								month.find("option").show(); //reset months
								//hide months not available
								if(y==start_year || start_year==end_year){
									selval = month.find('option:selected').val();
									if(selval!='' && selval<start_month){
										month.val(start_month);
										m = start_month;
									}
									month.find("option:gt(0):lt("+(start_month-1)+")").hide();	
								}
								if(y==end_year || start_year==end_year){
									selval = month.find('option:selected').val();
									if(selval!='' && selval>end_month){
										month.val(end_month);
										m = end_month;
									}
									month.find("option:gt("+end_month+")").hide();
								}
								//calculate and hide days not in month
								var days_in_month = 31;
								if(y != '' && m != '') {
									days_in_month = 32 - new Date(y, m-1, 32).getDate();
									if(end_day>days_in_month) {
										end_day = days_in_month;
									}
								}
								day.find("option").show().filter(':gt('+days_in_month+')').hide();
								if(day.find("option:selected").is(':hidden')) {
									end_day = day.find('option:visible:last').val();
									day.val(end_day);
								}
								//hide days not available
								if(y==start_year && m==start_month || start_year==end_year && start_month==end_month){
									selday = day.find('option:selected').val();
									
									if(selday!='' && selday<start_day){
										day.val(start_day);
										d = start_day;
									}
									day.find("option:gt(0):lt("+(start_day-1)+")").hide();							
								}
								if(y==end_year && m==end_month || start_year==end_year && start_month==end_month) {
									selday = day.find('option:selected').val();
									if(selday!='' && selday>end_day){
										day.val(end_day);
										d = end_day;
									}
									day.find("option:gt("+end_day+")").hide();
								}
								//format date with leading 0's
								if(y != '' && m != '' && d != '') {
									while(y.length < 4) {
										y='0'+y;
									}
									while(m.length < 2) {
										m='0'+m;
									}
									while(d.length < 2) {
										d='0'+d;
									}
									val = y+'-'+m+'-'+d;
								}
								input.val(val);
		
							});
							
							input.prev().trigger('change');
							
						}
						
						//time
						if(this.time != undefined) {
							field.data('validation','time');
							var input = field.hide();
							
							var select_hour = select_minutes = select_seconds = '';
							var value = input.val().match(/([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})/);
							
							if(value != null) {
								select_hour = parseInt(value[1],10);
								select_minutes = parseInt(value[2],10);
								select_seconds = parseInt(value[3],10);
							}
							
							var timeregex = new RegExp('([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})[|]([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})');
							var range = this.range.match(timeregex);
		
							var start_hour = parseInt(range[1],10);
							var end_hour = parseInt(range[4],10);
							var start_minutes = parseInt(range[2],10);
							var end_minutes = parseInt(range[5],10);
							var start_seconds = parseInt(range[3],10);
							var end_seconds = parseInt(range[6],10);
						
							var html = '<select><option></option>';
							if(start_hour<12) {
								html += '<optgroup label="AM">';
								for(var i=0;i<12;i++) {
									v = (i<=9?'0'+i:i);
									html += '<option';
									if(select_hour===i) {
										html += ' selected="selected"';
									}
									html +=  ' value="'+v+'">'+i+'</option>';
								}
								html += '</optgroup>';
							}
							if(end_hour>12) {
								html += '<optgroup label="PM"><option>12</option>';
								for(var i=1;i<=11;i++) {	
									html += '<option';					
									if(select_hour===i) {
										html += ' selected="selected"';
									}
									html += ' value="'+(i+12)+'">'+i+'</option>';
								}
								html += '</optgroup>';
							}
							html += '</select>';
							
							html += ':<select><option></option>';
		
							for(var i=0;i<=59;i++) {
								v = (i<=9?'0'+i:i);
								html += '<option';
								if(select_minutes===i) {
									html += ' selected="selected"';
								}
								html += '>'+v+'</option>';
							}
							html += '</select>';
							
							if(this.showSeconds == true) {
								html += ':<select>';
							} else {
								html += '<select style="display:none">';
								select_seconds=0;
							}
							
							html += '<option></option>';;
							for(var i=start_seconds;i<=end_seconds;i++) {
								v = (i<=9?'0'+i:i);
								if(select_seconds===i) {
									html += '<option selected="selected">'+v+'</option>';
								} else {
									html += '<option>'+v+'</option>';
								}
							}
							html += '</select>';
							
							input.before(html);
							
							input.prev().prev().prev().find("option:gt(0):lt("+start_hour+")").hide();
							input.prev().prev().prev().find("option:gt("+(end_hour+1)+")").hide();
		
							input.prevAll('select:lt(3)').change(function(){
								var input = $(this).nextAll('input:first');
								var seconds = input.prev();
								var minutes = input.prev().prev();
								var hours = input.prev().prev().prev();
								
								var s = seconds.val();
								var m = minutes.val();
								var h = hours.val();
								
								
								
								val = '';
								if(h != '' && m != '' && s != '') {
									val = h+':'+m+':'+s;
								}
								input.val(val);
							});
							
							input.prev().trigger('change');
						}
						
						//state
						if(this.state != undefined) {
							field.data('validation','state');
							var input = field;
							var country = $('select[name='+this.country+']');
							
							input.before('<select></select>');
							
							country.bind('change',{input:input},function(e){
								var states = [];
							
								switch($(this).val()){
									case 'AU': //Australia
										states = ["Australian Antarctic Territory","Australian Capital Territory","Northern Territory","New South Wales","Queensland","South Australia","Tasmania","Victoria","Western Australia"];
									break;
									case 'BR': //Brazil
										states = ["Acre","Alagoas","Amazonas","Amapa","Baia","Ceara","Distrito Federal","Espirito Santo","Fernando de Noronha","Goias","Maranhao","Minas Gerais","Mato Grosso do Sul","Mato Grosso","Para","Paraiba","Pernambuco","Piaui","Parana","Rio de Janeiro","Rio Grande do Norte","Rondonia","Roraima","Rio Grande do Sul","Santa Catarina","Sergipe","Sao Paulo","Tocatins"];
									break;
									case 'CA': //Canada
										states = ["Alberta","Manitoba","Alberta","British Columbia","Manitoba","New Brunswick","Newfoundland and Labrador","Nova Scotia","Northwest Territories","Nunavut","Ontario","Prince Edward Island","Quebec","Saskatchewan","Yukon Territory"];
									break;
									case 'EI': //Ireland
										states = ["County Antrim","County Armagh","County Down","County Fermanagh","County Londonderry","County Tyrone","County Cavan","County Donegal","County Monaghan","County Dublin","County Carlow","County Kildare","County Kilkenny","County Laois","County Longford","County Louth","County Meath","County Offaly","County Westmeath","County Wexford","County Wicklow","County Galway","County Mayo","County Leitrim","County Roscommon","County Sligo","County Clare","County Cork","County Kerry","County Limerick","County Tipperary","County Waterford"];
									break;
									case 'NL': //Netherlands
										states = ["Drente","Flevoland","Friesland","Gelderland","Groningen","Limburg","Noord Brabant","Noord Holland","Overijssel","Utrecht","Zuid Holland","Zeeland"];
									break;
									case 'UK': //United Kingdom
										states = ["Avon","Bedfordshire","Berkshire","Buckinghamshire","Cambridgeshire","Cheshire","Cleveland","Cornwall","Cumbria","Derbyshire","Devon","Dorset","Durham","Essex","Gloucestershire","Greater London","Greater Manchester","Hampshire","Hereford &amp; Worcestershire","Hertfordshire","Humberside","Isle of Man","Isle of Wight","Kent","Lancashire","Leicestershire","Lincolnshire","Merseyside","Norfolk","Northamptonshire","Northumberland","Nottinghamshire","Oxfordshire","Shropshire","Somerset","Staffordshire","Suffolk","Surrey","Sussex","Warwickshire","West Midlands","Wiltshire","Yorkshire"];
									break;
									case 'US': //United States
										states = ["Alaska","Alabama","Arkansas","American Samoa","Arizona","California","Colorado","Connecticut","D.C.","Delaware","Florida","Micronesia","Georgia","Guam","Hawaii","Iowa","Idaho","Illinois","Indiana","Kansas","Kentucky","Louisiana","Massachusetts","Maryland","Maine","Marshall Islands","Michigan","Minnesota","Missouri","Marianas","Mississippi","Montana","North Carolina","North Dakota","Nebraska","New Hampshire","New Jersey","New Mexico","Nevada","New York","Ohio","Oklahoma","Oregon","Pennsylvania","Puerto Rico","Palau","Rhode Island","South Carolina","South Dakota","Tennessee","Texas","Utah","Virginia","Virgin Islands","Vermont","Washington","Wisconsin","West Virginia","Wyoming","Military Americas","Military Europe/ME/Canada","Military Pacific"];
									break;
								}
								if(states.length>0) {
									input.hide();
									input.prev().show();
									var html = '';
									$.each(states,function(i,n){
										html += '<option'+(n==input.val()?' selected="selected"':'')+'>'+n+'</option>';
									});
									input.prev().html(html);
								}else {
									input.show();
									input.prev().hide();	
								}
							});
							
							country.trigger('change');
							
							input.prev().change(function(){
								$(this).next().val($(this).val());
							})
						}
						
						//maxlength
						if(this.maxlength != undefined) {
							field.data('validation','maxlength');
							field.bind('input blur change keyup',{maxlength:this.maxlength},function(e){
								var value = $(this).val();
								if(value.length > e.data.maxlength) {
									$(this).val(value.substring(0,e.data.maxlength));
								}
							});
						}
						
						//phone
						if(this.phone != undefined) {
							field.data('validation','phone');
							field.bind('input blur change keyup',function(e){
								var value = $(this).val();
								formatted = '';
								if(value.length>0) {
									formatted = '('+value.substring(0,2);
								}
								if(value.length>=2) {
									formatted += ') ' + value.substring(2,6) + ' ' + value.substring(6,10);
								}
								$(this).next('span').text(formatted);
							});
						}
						
						//mobile
						if(this.mobile != undefined) {
							field.data('validation','mobile');
							field.bind('input blur change keyup',function(e){
								var value = $(this).val();
								formatted = '';
								if(value.length>0) {
									formatted = value.substring(0,4) + ' ' + value.substring(4,7) + ' ' + value.substring(7,10);
								}
								$(this).next('span').text(formatted);
							});
						}
						
						//number
						if(this.number != undefined) {
							field.data('validation','number');
							field.bind('input blur change keyup',{number:this.number},function(e){
								var value = $(this).val();
								if((pos = value.indexOf('.')) != -1) {
									value = value.substring(0,pos)+"."+value.substring(pos+1,(pos+1+e.data.number));
								}
								$(this).val(value);
							});
						}
						
						//restrict
						if(this.restrict != undefined) {
							field.data('validation','restrict');
							field.bind('input blur change keyup',{restrict:this.restrict},function(e){
								var value = $(this).val();
								var len = value.length;
								if (len > 0) {
									var newstring = '';
									for (var j = 0; j < len; j++) {
										var character = value.substr(j, 1);
										if (character.search(e.data.restrict) != -1) {
											newstring += character;
										} else if (character.toLowerCase().search(e.data.restrict) != -1) { //see if lowercase matches
											newstring += character.toLowerCase();
										} else if (character.toUpperCase().search(e.data.restrict) != -1) { //or upper case
											newstring += character.toUpperCase();
										} else if (e.data.restrict.search(/ /) == -1 && "-".search(e.data.restrict) != -1 && character == " ") { //replace spaces with -
											newstring += "-";
										}
									}	
									if(value != newstring) {
										$(this).val(newstring);
									}
								}
							});
						};
					
					};
				};
			});		
		
			return this;
		});
	
	};

})(jQuery);

preload_images("/puppy/images/error_tip.png");
