var jc = {
	init:function(o){
		jc.settings = $.extend({
			slideShow_interval:3000,
			slideShow_indexPosition:'bottom right',
			logoTicker_scollTolerance:350
		},o);
		jc.form.init();
		jc.ui.init();
		jc.fancybox.init();
	},
	util:{
		dump:function(o){
			x = function(obj,prefix){
				prefix = (typeof prefix == 'undefined')?'':prefix;
				var str = '';
				for (var i in obj) {
					str += prefix+''+i+' = '+obj[i]+'\n';
					str += x(obj[i],prefix+'   ');
				}
				return str;
			}	
			alert(x(o));
		},
		string:{
			regexCharFilters:{
				email:'[^a-zA-Z0-9@-_.~]', // 'abcdefghijklmnopqrstuvwxyz0123456789@-_.~'
				alpha:'[^a-zA-Z]', // 'abcdefghijklmnopqrstuvwxyz'
				noSymbols:'[^a-zA-Z0-9 ]', // 'abcdefghijklmnopqrstuvwxyz0123456789 '
				noSpace:'[^a-zA-Z0-9]', // 'abcdefghijklmnopqrstuvwxyz0123456789'
				integer:'[^0-9]', // '0123456789'
				numeric:'[^0-9-.]', // '0123456789-.'
				dollar:'[^0-9., -]' // '0123456789., -'
			},
			isClean:function(str,regexFilter){
				regex = jc.util.string.regexCharFilters[regexFilter];
				var reg = new RegExp(regex,'gi');
				return !reg.test(str);
			},
			isCharCodeClean:function(charCode,regexFilter){
				var str = String.fromCharCode(charCode);
				return jc.util.string.isClean(str,regexFilter);
			},
			clean:function(str,regexFilter){
				regex = jc.util.string.regexCharFilters[regexFilter];
				var reg = new RegExp(regex,'gi');
				return str.replace(reg,'');
			},
			passwordStrength:function(pwd){
				var strong = new RegExp("^(?=.{8,})(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*\\W).*$", "g"),
					medium = new RegExp("^(?=.{7,})(((?=.*[A-Z])(?=.*[a-z]))|((?=.*[A-Z])(?=.*[0-9]))|((?=.*[a-z])(?=.*[0-9]))).*$", "g"),
					weak = new RegExp("(?=.{6,}).*", "g"),
					r = '';
				if (!weak.test(pwd)) r = 'incomplete';
				else if (strong.test(pwd)) r = 'strong';
				else if (medium.test(pwd)) r = 'medium';
				else if (weak.test(pwd)) r = 'weak';
				return r;
			},
			isInt:function(n){
				var reInt = new RegExp(/^-?\d+$/);
				if (!reInt.test(n)) {
					return false;
				}
				return true;
			},
			isEmail:function(str) {
				var filter  = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
				return (filter.test(str));
			}
		},
		number:{
			commaFormat:function(nStr){
				nStr += '';
				x = nStr.split('.');
				x1 = x[0];
				x2 = x.length > 1 ? '.' + x[1] : '';
				var rgx = /(\d+)(\d{3})/;
				while (rgx.test(x1)) x1 = x1.replace(rgx, '$1' + ',' + '$2');
				return x1 + x2;
			},
			dollarFormat:function(n){
				if (typeof n != 'number') return '0.00';
				var n1 = n.toFixed(2);
				var n2 = jc.util.number.commaFormat(n1);
				return n2;
			},
			padZeros:function(num,zeros){
				var str = ''+num;
				while (str.length < zeros) str = '0'+str;
				return str;
			}
		}
	},
	ui:{
		init:function(){
			$.each($('div.jc-slideShow'),function(i,e){ jc.ui.slideShow.init($(e)) });
			$.each($('ul.jc-ddMenu'),function(i,e){ jc.ui.ddMenu.init($(e)) });
			$.each($('.jc-countdown'),function(i,e){ jc.ui.countdown.init($(e)) });
			$.each($('.jc-logoTicker'),function(i,e){ jc.ui.logoTicker.init($(e)) });
		},
		slideShow:{
			init:function(ss){
				var transition = 'slide',
					loop = 1,
					slideCount = $(ss).find('.jc-slide').length,
					control = $('<div class="jc-slide-control" />').appendTo(ss);
				
				// determine transition type
				if (ss.hasClass('jc-slideShowTrans-fade')) {
					transition = 'fade';	
				}
				
				// determine transition type
				if (ss.hasClass('jc-slideShow-noLoop')) {
					loop = 0;	
				}
				
				// save transition to the data property for use later
				ss.data({transition:transition,loop:loop,zindex:0});
				
				// size the slides properly (height and width of the parent holder of the slideshow)
				$(ss).find('.jc-slide').width($(ss).parent().width()).height($(ss).parent().height());
				
				// if they are fading
				
				// set first slide to be active
				if (ss.find('.jc-slide-active').length === 0) {
					ss.find('.jc-slide').first().addClass('jc-slide-active').addClass('jc-slide-played'); 
				}
				// start the timer
				if (slideCount > 1) {
					jc.ui.slideShow.restartTimer(ss);
				} 

				// position the slide index
				if (jc.settings.slideShow_indexPosition.indexOf('bottom') >= 0) control.css('bottom','5px');
				else if (jc.settings.slideShow_indexPosition.indexOf('top') >= 0) control.css('top','5px');
				if (jc.settings.slideShow_indexPosition.indexOf('left') >= 0) control.css('left','5px');
				else if (jc.settings.slideShow_indexPosition.indexOf('right') >= 0) control.css('right','5px');
				
				// create slide indexes
				$.each($(ss).find('.jc-slide'),function(i,e){
					$('<div class="jc-slide-control-node" />').appendTo(control).click(function(){ jc.ui.slideShow.slideTo($(e)); });
					$(e).attr('jc-index',i);
				});
				control.css('width',(slideCount*(12+5))+'px');
				
				// marker
				$('<div class="jc-slide-control-marker" />').appendTo(control);
			},
			next:function(ss){
				var e1 = ss.find('.jc-slide-active');
				var e2 = e1.next('.jc-slide');
				if (e2.length == 0) e2 = ss.find('.jc-slide').first();
				
				jc.ui.slideShow.slideTo(e2);
			},
			previous:function(ss){
				var e1 = ss.find('.jc-slide-active');
				var e2 = e1.previous('jc-slide');
				if (e2.length == 0) e2 = ss.find('jc-slide').last();
				jc.ui.slideShow.slideTo(e2);
			},
			slideTo:function(e2){
				var ss = $(e2).closest('.jc-slideShow'),
					s = ss.find('.jc-slides'),
					m = ss.find('.jc-slide-control-marker'),
					i = $(e2).attr('jc-index'),
					ss_d = ss.data(),
					t = ss_d.transition,
					z = ss_d.zindex;
				
				// stop the loop
				if (ss.find('.jc-slide').length === ss.find('.jc-slide-played').length && ss_d.loop == 0) { return false; }
				
				// transition image
				if (t === 'fade') {
					ss.data('zindex',++z);
					$(e2).css({'z-index':z,position:'absolute',top:'0px',left:'0px',display:'none'});
					$(e2).fadeIn(function(){
						s.find('.jc-slide-active').removeClass('jc-slide-active');
						$(e2).addClass('jc-slide-active').addClass('jc-slide-played');
						jc.ui.slideShow.restartTimer(ss);				  
					});
				} else if (t === 'slide') {
					$(s).animate({left:'-'+e2.position().left+'px'}, function(){
						s.find('.jc-slide-active').removeClass('jc-slide-active');
						$(e2).addClass('jc-slide-active').addClass('jc-slide-played');
						jc.ui.slideShow.restartTimer(ss);
					});
				}
				
				// animate marker
				$(m).animate({left:(i*16)+'px'});
			},
			restartTimer:function(ss){
				var t = $(ss).data('timer');
				if (typeof t != 'undefined')
					if (t != null)
						clearTimeout(t);
				$(ss).data('timer',setTimeout(function(){ jc.ui.slideShow.next(ss); },jc.settings.slideShow_interval));
			}
		},
		ddMenu:{
			init:function(a){
				// loop through all LI's, find and save the DD's
				$(a).find('li').each(function(i,li){
					var dd = $(li).find('ul').first(); // grab the first ul (its the dropdown inside the LI)
					if (dd.find('li').length > 0) {
						$(li).data('jc-ddClone',dd.clone()); // clone/store it for use later
						dd.css({display:'none'}); //dd.remove(); // remove original drop down HTML from DOM (waste of memory)
						$(li).mouseover(function(){ jc.ui.ddMenu.show($(this)); });
					}
				});	
			},
			show:function(li){
				var dd = $('<div />').addClass('jc-dd').append(li.data('jc-ddClone')), // create drop down
					p = li.offset(); // get position
				//jc.ui.ddMenu.hide($('.jc-dd')); // hide all other drop downs
				dd.appendTo(document.body); // append to DOM
				dd.css({top:(p.top+li.height())+'px',left:p.left+'px'}); // set position
				dd.slideDown('fast'); // show this dropdown
				$(document).click(function(e){
					if ($(e.target).closest('.jc-dd').length == 0)
						jc.ui.ddMenu.hide(dd);
				});
				$('.jc-ddMenu').mouseout(function(e){
					if ($(e.relatedTarget).closest('.jc-dd').length == 0) 
						jc.ui.ddMenu.hide(dd);
				});
			},
			hide:function(dd){
				dd.slideUp('fast',function(){ $(dd).remove(); });
			}
		},
		countdown:{
			init:function(e){
				var date1 = $(e).find('.jc-countdown-date-start').html();
				if (date1 != '') date1 = new Date(date1); else return;
				
				var date2 = $(e).find('.jc-countdown-date-end').html();
				if (date2 != '') date2 = new Date(date2); else return;
				
				var advance = $(e).find('.jc-countdown-advance').html();
				advance = (!isNaN(parseInt(advance)))?parseInt(advance):0;
				
				var complete_el = $(e).find('.jc-countdown-complete');
				if (complete_el.length == 0) complete_el = null;
				
				var day_el = $(e).find('.jc-countdown-days');
				var hr_el = $(e).find('.jc-countdown-hours');
				var min_el = $(e).find('.jc-countdown-minutes');
				var sec_el = $(e).find('.jc-countdown-seconds');
				if (day_el.length == 0 || hr_el.length == 0 || min_el.length == 0 || sec_el.length == 0) return;
				
				jc.ui.countdown.interval(date1, date2, advance, day_el, hr_el, min_el, sec_el, complete_el);
			},
			interval:function(date1,date2,advance,day_el,hr_el,min_el,sec_el,complete_el){
				var oneSec_ms = 1000;
				var oneMin_ms = oneSec_ms*60;
				var oneHr_ms = oneMin_ms*60;
				var oneDay_ms = oneHr_ms*24;
				var date1_ms = date1.getTime();
				var date2_ms = date2.getTime();
				var advance_ms = advance*oneMin_ms;
				
				if (date1_ms < (date2_ms-advance_ms)) {
					date1_ms += oneSec_ms;
					var diff = (date2_ms-advance_ms)-date1_ms;
									
					var days = Math.floor(diff/oneDay_ms); // days till date2
					diff -= (days*oneDay_ms);
					var hours = Math.floor(diff/oneHr_ms); // hours till end of today
					diff -= (hours*oneHr_ms);
					var mins = Math.floor(diff/oneMin_ms); // hours till end of hour
					diff -= (mins*oneMin_ms);
					var secs = Math.floor(diff/oneSec_ms); // seconds till end of min
					
					// populate html
					$(day_el).html(jc.util.number.padZeros(days,2));
					$(hr_el).html(jc.util.number.padZeros(hours,2));
					$(min_el).html(jc.util.number.padZeros(mins,2));
					$(sec_el).html(jc.util.number.padZeros(secs,2));
					
					date1 = new Date(date1_ms);
					date2 = new Date(date2_ms);
					
					// call this function again in 1 second
					setTimeout(function(){ jc.ui.countdown.interval(date1, date2, advance, day_el, hr_el, min_el, sec_el, complete_el); },1000);
				} else {
					$(day_el).html('00');
					$(hr_el).html('00');
					$(min_el).html('00');
					$(sec_el).html('00');
					if (complete_el != null) {
						var count = $(complete_el).parent('.jc-countdown').get(0);
						var dup = $(complete_el).clone().css({display:'block'});
						$(count).css({display:'none'}).after(dup);
					}
				}
			}
		},
		logoTicker:{
			timer:null,
			strength:0,
			//scrollTolerance:350, // pixel distance from left and right that initiates scrolling // jc.settings.logoTicker_scollTolerance
			tickerTape:null,
			width:null,
			maskWidth:null,
			init:function(el){
				/// ONLY SUPPORTS A SIGNLE INSTANCE
				jc.ui.logoTicker.tickerTape = $('.jc-logoTicker ul');
				jc.ui.logoTicker.calculateWidth();
				jc.ui.logoTicker.maskWidth = $('.jc-logoTicker-msk').width();
				// set the width of the ticker tape to the width of the elements inside
				$('.jc-logoTicker').mousemove(function(e){ jc.ui.logoTicker.trackMouse($(this), e); });
				$('.jc-logoTicker').mouseout(function(e){
					if ($(e.relatedTarget).closest('.jc-logoTicker').length == 0)
						jc.ui.logoTicker.stopTrackMouse(e);
				});
			},
			trackMouse:function(t, e){
				var mX = e.pageX-t.offset().left,
					min = 0,
					max = $(t).width(), //960
					grace = 0,
					tolerance = jc.settings.logoTicker_scollTolerance; // how far past the min/max will we allow them to scroll
				if (mX < (min+tolerance)) {
					jc.ui.logoTicker.strength = (min+tolerance)-mX;
					jc.ui.logoTicker.startTimer();
				} else if (mX > (max-tolerance)) {
					jc.ui.logoTicker.strength = -(mX-(max-tolerance));
					jc.ui.logoTicker.startTimer();
				} else {
					jc.ui.logoTicker.strength = 0;
					jc.ui.logoTicker.stopTimer();
				}
			},
			stopTrackMouse:function(){
				jc.ui.logoTicker.stopTimer();
			},
			startTimer:function(){
				if (jc.ui.logoTicker.width == null)
					jc.ui.logoTicker.calculateWidth();
				if (jc.ui.logoTicker.timer == null)
					jc.ui.logoTicker.timer = setInterval(function(){ 
						var l2 = jc.ui.logoTicker.tickerTape.position().left+(jc.ui.logoTicker.strength/30),
							maxRight = -(jc.ui.logoTicker.width-jc.ui.logoTicker.maskWidth+5),
							maxLeft = 0;
							
						if (l2 > maxLeft) {
							jc.ui.logoTicker.tickerTape.css({left:maxLeft+'px'});
							jc.ui.logoTicker.stopTimer();
							return;
						} else if (l2 < maxRight) {
							jc.ui.logoTicker.tickerTape.css({left:maxRight+'px'});
							jc.ui.logoTicker.stopTimer();
							return;
						} else {
							jc.ui.logoTicker.tickerTape.css({left:l2+'px'});
						}
					},10);
			},
			stopTimer:function(){
				if (jc.ui.logoTicker.timer != null) {
					clearInterval(jc.ui.logoTicker.timer);
					jc.ui.logoTicker.timer = null;
				}
			},
			calculateWidth:function(){
				var w = 0;
				$.each(jc.ui.logoTicker.tickerTape.find('li'),function(i,e){
					w += $(e).outerWidth();														
				});
				jc.ui.logoTicker.width = w;
			}
		}
	},
	form:{
		callback_onFieldError:function(e,msg){},
		callback_onFieldSuccess:function(e){},
		callback_onFormError:function(e,msg){},
		callback_onFormSuccess:function(e){},
		isBatchValidation:0,
		init:function(sel, formError, formSuccess, fieldError, fieldSuccess){
			if (typeof sel == 'undefined') sel = document.body; // search entire DOM by default
			if (typeof fieldError != 'function') fieldError = jc.form.callback_onFieldError;
			if (typeof fieldSuccess != 'function') fieldSuccess = jc.form.callback_onFieldSuccess;
			if (typeof formError != 'function') formError = jc.form.callback_onFormError;
			if (typeof formSuccess != 'function') formSuccess = jc.form.callback_onFormSuccess;
			
			// form handlers
			$(sel).find('form').submit(function(ev){
				var canSubmit = jc.form.validate($(this));
				if (canSubmit) {
					formSuccess($(this));
				} else { 
					formError($(this),'There are errors in the form.');
					ev.stopImmediatePropagation();
					return false;
				}
			});
			
			// initialize all form fields
			jc.form.field.init(sel, fieldError, fieldSuccess);
		},
		fireFn:function(input, test, fnError, errorMessage, fnSuccess){
			var er = '';
			// is required
			if (input.hasClass('required') && jc.form.field.isEmpty(input))
				er += 'This field is required. ';
			// match value test
			if (input.data('matchValue') != null) {
				if (input.val() != input.data().matchValue.val())
					if (input.hasClass('password'))
						er += 'The passwords do not match. ';
					else
						er += 'The value do not match. ';
			}
			
			// custom input type test
			if (!test)
				er += errorMessage+' ';
			
			if (er != '' && typeof fnError == 'function') fnError(input,er,jc.form.isBatchValidation);
			else if (er == '' && typeof fnSuccess == 'function') fnSuccess(input,jc.form.isBatchValidation);
			
			return (er == '');
		},
		// loop through a form and validates all the fields
		validate:function(form){
			// track errors
			var errors = 0;
			jc.form.isBatchValidation = 1;
			// loop through all form fields
			$.each($(form).find('input, select, textarea'),function(i,e){
				// call validation (what would usually happen onblur)
				var validate = $(this).data().validate;
				if (typeof validate == 'function') errors += Number(!validate($(this)));		
			});
			jc.form.isBatchValidation = 0;
			return (errors == 0);
		},
		unvalidate:function(formSel){
			// loop through all form fields
			$(formSel).find('input, select').each(function(i,e){
				// call validation (what would usually happen onblur)
				var onSuccess = $(this).data().onSuccess;
				if (typeof onSuccess == 'function') onSuccess($(this));		
			});
			return true;
		},
		restrictInput:{
			apply:function(e,type){
				$(e).keypress(function(ev){ ev.returnValue = jc.form.restrictInput.validateKeyPress(ev.keyCode,type); });
				$(e).blur(function(ev){ jc.form.restrictInput.cleanInput(e,type); });
			},
			validateKeyPress:function(charCode,type){
				return jc.util.string.isCharCodeClean(charCode,type);
			},
			cleanInput:function(e,type){
				var origStr = $(e).val();
				var cleanedStr = jc.util.string.clean(origStr,type);
				$(e).val(cleanedStr);
			}
		},
		field:{
			init:function(sel, fnError, fnSuccess){
				if (typeof sel == 'undefined') sel = document.body; // search entire DOM by default
				if (typeof fnError == 'undefined') fnError = null;
				if (typeof fnSuccess == 'undefined') fnSuccess = null;
				// common input bindings
				$.each($(sel).find('input, select, textarea'),function(i,e){
					$(e).data('onError',fnError); // store a pointer to the validation function in the data object
					$(e).data('onSuccess',fnSuccess); // store a pointer to the validation function in the data object
					if ($(e).attr('matchvalue') != null) $(e).data('matchValue',$('#'+$(e).attr('matchvalue')));
				});
				// add's type specific event handlers and formatting
				for (var i in jc.form.field.types) {
					$(sel).find('input.'+i+', textarea.'+i).each(function(j,e){ 
						jc.form.field.types[i].init(e);
					}); 
				}
			},
			isEmpty:function(input){
				// is the field empty or not (text value = '', selectbox selected index = 0, radio/checkbox = unchecked)
				var tag = $(input)[0].tagName;
				var type = $(input).attr('type');
				if (tag == 'INPUT' || tag == 'TEXTAREA')
					if (type == 'checkbox' || type == 'radio') return ($(input).attr('checked') == false);
					else return ($(input).val() == '');
				else if (tag == 'SELECT') return ($(input).selectedIndex == null);
			},
			types:{
				email:{
					init:function(input){
						$(input).data('validate',jc.form.field.types.email.validate); // store a pointer to the validation function in the data object
						jc.form.restrictInput.apply(input,'email');
						$(input).blur(function(){ $(this).data().validate($(this)); }); // BIND validation on blur
					},
					validate:function(input){
						var test = (jc.util.string.isEmail(input.val()));
						var d = $(input).data();
						return jc.form.fireFn(input, test, d.onError, 'Invalid email address.', d.onSuccess);
					}
				},
				text:{
					init:function(input){
						$(input).data('validate',jc.form.field.types.text.validate); // store a pointer to the validation function in the data object
						$(input).blur(function(){ $(this).data().validate($(this)); }); // BIND validation on blur
					},
					validate:function(input){
						var test = true;
						var d = $(input).data();
						return jc.form.fireFn(input, test, d.onError, 'Invalid text.', d.onSuccess);
					}
				},
				alpha:{
					init:function(input){
						$(input).data('validate',jc.form.field.types.alpha.validate); // store a pointer to the validation function in the data object
						jc.form.restrictInput.apply(input,'alpha');
						$(input).blur(function(){ $(this).data().validate($(this)); }); // BIND validation on blur
					},
					validate:function(input){
						var d = $(input).data();
						return jc.form.fireFn(input, true, d.onError, '', d.onSuccess);
					}
				},
				password:{
					init:function(input){
						$(input).data('validate',jc.form.field.types.password.validate); // store a pointer to the validation function in the data object
						$(input).blur(function(){ $(this).data().validate($(this)); }); // BIND validation on blur
					},
					validate:function(input){
						var test = ($(input).val().indexOf(' ') == -1); // no spaces (simple validation)
						var d = $(input).data();
						return jc.form.fireFn(input, test, d.onError, 'Your password cannot contain any spaces.', d.onSuccess);
					}
				},
				date:{
					init:function(input){
						$(input).datepicker();
						$(input).data('validate',jc.form.field.types.date.validate); // store a pointer to the validation function in the data object
						//$(input).blur(function(){ $(this).data().validate($(this)); }); // BIND validation on blur
					},
					validate:function(input){
						var test = true; // no validation
						var d = $(input).data();
						return jc.form.fireFn(input, test, d.onError, '', d.onSuccess);
					}
				},
				checkbox:{
					init:function(input){
						$(input).data('validate',jc.form.field.types.checkbox.validate); // store a pointer to the validation function in the data object
						$(input).click(function(){ $(this).data().validate($(this)); }); // BIND validation on blur
					},
					validate:function(input){
						var test = true; // no test
						var d = $(input).data();
						return jc.form.fireFn(input, test, d.onError, '', d.onSuccess);
					}
				},
				dollar:{
					init:function(input){
						$(input).data('validate',jc.form.field.types.dollar.validate); // store a pointer to the validation function in the data object
						$(input).before('<span class="fieldPrefix">$&nbsp;</span>');
						jc.form.restrictInput.apply(input,'dollar');
						$(input).click(function(){ $(this).data().validate($(this)); }); // BIND validation on blur
					},
					validate:function(input){
						var test = true; // no test
						var d = $(input).data();
						return jc.form.fireFn(input, test, d.onError, '', d.onSuccess);
					}
				},
				float:{
					init:function(input){
						$(input).data('validate',jc.form.field.types.float.validate); // store a pointer to the validation function in the data object
						$(input).attr('maxlength','10');
						jc.form.restrictInput.apply(input,'numeric');
						$(input).click(function(){ $(this).data().validate($(this)); }); // BIND validation on blur
					},
					validate:function(input){
						var test = true; // no test
						var d = $(input).data();
						return jc.form.fireFn(input, test, d.onError, '', d.onSuccess);
					}
				},
				integer:{
					init:function(input){
						$(input).data('validate',jc.form.field.types.integer.validate); // store a pointer to the validation function in the data object
						$(input).attr('maxlength','10');
						jc.form.restrictInput.apply(input,'integer');
						$(input).blur(function(){ $(this).data().validate($(this)); }); // BIND validation on blur
					},
					validate:function(input){
						var d = $(input).data();
						return jc.form.fireFn(input, true, d.onError, '', d.onSuccess);
					}
				},
				integer5:{
					init:function(input){
						$(input).data('validate',jc.form.field.types.integer.validate); // store a pointer to the validation function in the data object
						$(input).attr('maxlength','5');
						jc.form.restrictInput.apply(input,'integer');
						$(input).blur(function(){ $(this).data().validate($(this)); }); // BIND validation on blur
					}
				},
				integer3:{
					init:function(input){
						$(input).data('validate',jc.form.field.types.integer.validate); // store a pointer to the validation function in the data object
						$(input).attr('maxlength','3');
						jc.form.restrictInput.apply(input,'integer');
						$(input).blur(function(){ $(this).data().validate($(this)); }); // BIND validation on blur
					}
				},
				percent:{
					init:function(input){
						$(input).data('validate',jc.form.field.types.percent.validate); // store a pointer to the validation function in the data object
						$(input).after('<span class="fieldSuffix">&nbsp;%</span>');
						$(input).attr('maxlength','6');
						jc.form.restrictInput.apply(input,'numeric');
						$(input).click(function(){ $(this).data().validate($(this)); }); // BIND validation on blur
					},
					validate:function(input){
						var test = true; // no test
						var d = $(input).data();
						return jc.form.fireFn(input, test, d.onError, '', d.onSuccess);
					}
				},
				creditCard:{
					init:function(input){
						$(input).data('validate',jc.form.field.types.creditCard.validate); // store a pointer to the validation function in the data object
						$(input).attr('maxlength','16');
						jc.form.restrictInput.apply(input,'integer');
						$(input).blur(function(){ $(this).data().validate($(this)); }); // BIND validation on blur
					},
					validate:function(input){
						var test = $(input).val().length >= 14; // credit cards are aleast 14 digits long
						var d = $(input).data();
						return jc.form.fireFn(input, test, d.onError, 'Invalid card number.', d.onSuccess);
					}
				},
				pczip:{
					init:function(input){
						$(input).data('validate',jc.form.field.types.pczip.validate); // store a pointer to the validation function in the data object
						$(input).attr('maxlength','12');
						jc.form.restrictInput.apply(input,'noSpace');
						$(input).blur(function(){ $(this).data().validate($(this)); }); // BIND validation on blur
					},
					validate:function(input){
						var test = $(input).val().length >= 5; // postal codes and zips need to be atleast 5 chars long
						var d = $(input).data();
						return jc.form.fireFn(input, test, d.onError, 'Invalid entry.', d.onSuccess);
					}
				}
			}
		}		
	},
	fancybox:{
		init:function(){
			if (typeof $.fancybox != 'undefined') {
				$(".jc-youtube").click(function() {
					$.fancybox({
							'padding'		: 0,
							'autoScale'		: false,
							'overlayColor'	: '#000',
							'overlayOpacity': 0.8,
							'transitionIn'	: 'none',
							'transitionOut'	: 'none',
							'title'			: this.title,
							'width'			: 680,
							'height'		: 495,
							'href'			: this.href.replace(new RegExp("watch\\?v=", "i"), 'v/'),
							'type'			: 'swf',
							'swf'			: {
							'wmode'			: 'transparent',
							'allowfullscreen'	: 'true'
							}
						});				
					return false;
				});	
				$(".jc-vimeo").click(function() {
					$.fancybox({
						'padding'       : 0,
						'autoScale'     : false,
						'overlayColor'	: '#000',
						'overlayOpacity': 0.8,
						'transitionIn'  : 'none',
						'transitionOut' : 'none',
						'title'         : this.title,
						'width'         : 680,
						'height'        : 495,
						'href'          : this.href.replace(new RegExp("([0-9])","i"),'moogaloop.swf?clip_id=$1'),
						'type'          : 'swf'
					});
					return false;
				});
			}
		}	
	}
};
