// Kick jQuery Plugins - Full Script

// Display Error
(function(jQuery){
	jQuery.fieldError = function(options) {
		
		var defaults = {  
		};
		
		var options = jQuery.extend(defaults, options);
		
		if(!options.errMessage) {
			switch (options.errID) {
				case 1 :
					options.errMessage = "This field must be between "+options.errLen+" charcters long.";
					break;
				case 2 :
					options.errMessage = "This is a required field and cannot be left blank.";
					break;
				case 3:
					options.errMessage = "You must select an option.";
					break;
				case 4:
					options.errMessage = "You must select between "+options.errMin+" and "+options.errMax;
					break;
				case 5:
					options.errMessage = "These fields do not match.";
					break;
				case 6:
					options.errMessage = "This field must only contain a number.";
					break;
				case 7:
					options.errMessage = "Please enter a valid email address.";
					break;
				case 8:
					options.errMessage = "Invalid file type. Please check the file you're uploading and try again.";
					break;																	
			}
			
			if ( options.errMessage && options.label && !options.errField) {
				options.errMessage = '[' + options.label + '] ' + options.errMessage;
			}
			
		}
		
		if (options.errField) {
			jQuery(options.errField).html(options.errMessage).slideDown().delay(2500).slideUp();
		} else {
			alert(options.errMessage);
		}
	
	}

})(jQuery);

// Field Error

(function(jQuery){
	
	jQuery.fn.fieldError = function(options) {
		
		var defaults = {  
		   highlight:'#FFCCCC',
		   time:400,
		   repeat:3,
		   flash:true
		};
		  
		var options = jQuery.extend(defaults, options);
		
		jQuery.fieldError(options);
		
			return this.each(function() {
				el = jQuery(this);
				
				if(!options.original) { options.original=el.css('backgroundColor'); }
				
				if(options.flash) {
					
					for(i=0;i<options.repeat;i++) {
						el.animate({backgroundColor:options.highlight},options.time).animate({backgroundColor:options.original},options.time);
					}
					
					if(options.fieldMatch) {
						for(i=0;i<options.repeat;i++) {
							jQuery(options.fieldMatch).animate({backgroundColor:options.highlight},options.time).animate({backgroundColor:options.original},options.time);
						}
					}
					
				}
				
			});
					
		
	}
	

})(jQuery);

// Validate field
(function(jQuery){
		
	jQuery.fn.validate = function(options) {
		
		var defaults = {  
		   required:true,
		   maxLen:9999,
		   minLen:1
		};
		  
		var options = jQuery.extend(defaults, options);
		
		var result = 0;
		
		this.each(function() {
			el = jQuery(this);
			if ( jQuery('label[for="' + el.attr('id') + '"]').size() > 0 ) {
				options.label = jQuery.trim( jQuery('label[for="' + el.attr('id') + '"]').html().replace(/<.*?>/g,'').replace(':','').replace('*','') );
			}
			
			if (options.type=='currency' || options.type=='number') {
				el.val( el.val().replace(/[^\d\.-]/g,'') );
			}
				
			if(options.required==true && el.val()==""){
				options.errID=2;
				el.fieldError(options);
				return result += 1;
			}

			if( options.required==true && ( el.val().length < options.minLen || el.val().length > options.maxLen ) ) {
				options.errID=1;
				options.errLen=options.minLen+" and "+options.maxLen;
				el.fieldError(options);
				return result += 1;
			}
			
			if(options.fieldMatch) {
				if(el.val()!=jQuery(options.fieldMatch).val()) {
					options.errID=5;
					el.fieldError(options);
					return result += 1;
				}
			}
			
			if ( options.type && ( options.required == true || el.val() != "" ) ) {
			
				if ( options.type == 'currency' || options.type == 'number') {
					if(isNaN(el.val())) {
						options.errID=6;
						el.fieldError(options);
						return result += 1;
					}
				} else if ( options.type == 'email' ) {
					if (!el.val().match(/^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/)) {
						options.errID=7;
						el.fieldError(options);
						return result += 1;
					}
				} else if ( options.type == 'file' ) {
					var ext = el.val().split('.').pop().toLowerCase();
					if(jQuery.inArray(ext, options.file_types) == -1) {
						options.errID=8;
						el.fieldError(options);
						return result += 1;
					}
				}
				
			}
			
		}); 
			
			if(result>0) {
				return false;
			} else {
				return true;
			}
			
		}
	
})(jQuery);

// Validate group of fields
(function(jQuery){
		
	jQuery.fn.validateGroup = function(options) {
		
		var defaults = {
			minChecked:1,
			maxChecked:99999
		};
		  
	var options = jQuery.extend(defaults, options);
	
	var result = 0;
	
	this.each(function() {
	
		el = jQuery(this);
			
		if(el.attr('checked')) {
			return result += 1;
		}
		
	}); 
		
		if(result >= options.minChecked && result <= options.maxChecked) {
			return true;
		} else {
			jQuery.fieldError({
				errField:options.errField,
				errMessage:options.errMessage,
				errID:4,
				errMin:options.minChecked,
				errMax:options.maxChecked
			});
			return false;
		}
		
	}
	
})(jQuery);

// Validate email fields
(function(jQuery){
		
	jQuery.fn.validateEmail = function(options) {
		
		var defaults = {
			required:true
		};
		  
		var options = jQuery.extend(defaults, options);
		
		var result = 0;
		
		this.each(function() {
		
			//Check if the field is blank
			if(options.required==true && jQuery(this).val()==""){
				jQuery(this).fieldError({errID:2,errField:options.errField, errMessage:options.errMessage,fieldMatch:options.fieldMatch});
				return result += 1;
			}
			
			//Check if the fields match
			if(options.fieldMatch) {
				if(jQuery(this).val()!=jQuery(options.fieldMatch).val()) {
					jQuery(this).fieldError({errID:5,errField:options.errField,errMessage:options.errMessage,fieldMatch:options.fieldMatch});
					return result += 1;
				}
			}
			
			//Check if the email address is valid and does not exist
			
		}); 
		
		if(result>0) {
			return false;
		} else {
			return true;
		}
		
	}
	
})(jQuery);

// Text switcher - do not use this function. Add a placeholder attribute to the input field instead.
(function(jQuery){
		
	jQuery.fn.textSwitch = function(options) {
		
		var defaults = {
			text: "Search..."
		};
		  
		var options = jQuery.extend(defaults, options);
		
		var result = 0;
		
		return this.each(function() {
		
			el = jQuery(this);
						
			el.bind({
				"blur": function(){
					el = jQuery(this);
					if(!el.val()) {
						el.val(options.text);
						el.addClass('placeholder')
					}
				},
				"focus": function(){
					el = jQuery(this);
					el.removeClass('placeholder');
					if(el.val()==options.text) {
						el.val('');
					}
				}
			}).blur();
			
			el.parents('form').submit(function(){
				if( el.val() == options.text ) return false;
			})
		
		}); 
		
	}
	
})(jQuery);

jQuery.extend(jQuery.support, { placeholder: !!('placeholder' in document.createElement('input')) });

// Applies placeholder function for browsers that don't currently support it.
jQuery(function(){
	jQuery('[placeholder]').each(function() {
		el = jQuery(this);
		if(jQuery.support.placeholder) return;
		el.bind({
			"blur": function(){
				el = jQuery(this);
				if(!el.val()) {
					el.val( el.attr('placeholder') );
					el.addClass('placeholder')
				}
			},
			"focus": function(){
				el = jQuery(this);
				el.removeClass('placeholder');
				if( el.val() == el.attr('placeholder') ) el.val('');
			}
		}).blur();		
	});
	jQuery('form').bind('submit',function(){
		placeholders = jQuery(this).find('[placeholder]');
		placeholders.each(function(){
			el = jQuery(this); 
			if( el.val() == el.attr('placeholder') ) el.val(''); 
		});
	});	
});


(function(jQuery){
		
	jQuery.fn.kickFade = function(options) {
		
		var defaults = {
			delay:6000,
			duration:2000,
			paused:false,
			current:0,
			fadeFirst:false,
			fade:"crossfade",
			pauseonhover:true,
			debug:false
		};
		  
		var options = jQuery.extend(defaults, options);
		
		this.each(function() {
			
			options.els = jQuery(this).children();
			if( options.els.size() <= 1 ) return;
			options.els.not(":first-child").hide();
			if(options.fadeFirst) {			
				options.els.eq(0).attr('src',options.els.eq(0).attr('src')+'&rand='+Math.random());
				options.els.eq(0).hide().load(function(){
					jQuery(this).fadeTo(options.duration,1,function(){
						jQuery.kickFade.autoChange(options);
					});
				});
			} else {
				jQuery.kickFade.autoChange(options);
			}
			if(options.pauseonhover) {
				jQuery(this).hover(
					function() {
						options.paused = true;
						jQuery.kickFade.autoChange(options);
					},
					function() {
						options.paused = false;
						jQuery.kickFade.autoChange(options);
					}
				);
			}
		
		});
		
	}
	
	jQuery.kickFade = {
		
	autoChange: function(options){
		if(options.els.length>0) {
			if(options.timer) window.clearTimeout(options.timer);
			if(!options.paused) {
				options.timer = window.setTimeout(
					function() {
						if(options.fade == "crossfade") {
							options.els.eq(options.current).fadeTo(options.duration,0);
							options.current++;
							if(options.current>=options.els.length) options.current=0;
							options.els.eq(options.current).fadeTo(options.duration,1,function(){
								jQuery.kickFade.autoChange(options);
							});
						} else if (options.fade == "inout") {
							options.els.eq(options.current).fadeTo(options.duration,0,function(){
								options.current++;
								if(options.current>=options.els.length) options.current=0;
								options.els.eq(options.current).fadeTo(options.duration,1,function(){
									jQuery.kickFade.autoChange(options);	
								});
							});
						}
					},
					options.delay
				);
			}
		}
	}
		
}
		
})(jQuery);



(function(jQuery){
		
	jQuery.fn.kickScroll = function(options) {
		
		var defaults = {
			delay:6000,
			duration:2000,
			fadeOutDuration:400,
			paused:false,
			current:0,
			scrollFirst:false,
			scrollDir:"random"
		};
		  
		var options = jQuery.extend(defaults, options);
		
		this.each(function() {
			jQuery(this).css({overflow:'hidden'});
			options.width = jQuery(this).width();
			options.height = jQuery(this).height();			
			
			options.els = jQuery(this).children();
			options.els.not(":first-child").hide();
			if(options.fadeFirst) {
				options.els.eq(0).hide().load(function(){
					jQuery(this).fadeTo(options.duration,1,function(){
						jQuery.kickScroll.autoChange(options);
					});
				});
			} else {
				jQuery.kickScroll.autoChange(options);
			}
			jQuery(this).hover(
				function() {
					options.paused = true;
					jQuery.kickScroll.autoChange(options);
				},
				function() {
					options.paused = false;
					jQuery.kickScroll.autoChange(options);
				}
			);
		
		});
		
	}
	
	jQuery.kickScroll = {
		
	autoChange: function(options){
		if(options.els.length>0) {
			if(options.timer) window.clearTimeout(options.timer);
			if(!options.paused) {
				options.timer = window.setTimeout(
					function() {						
						if(options.scrollDir == "random") {
							var arrTemp = Array("right","left","down","up");
							intTemp = Math.floor(Math.random()*3)
							strDir = arrTemp[intTemp];
							
						} else {
							strDir = options.scrollDir;
						}
						
						options.els.eq(options.current).css({'z-index':'10'})
							options.current++;
							if(options.current>=options.els.length) options.current=0;
							
							switch(strDir) {
							case "right":
								options.els.eq(options.current).css({'z-index':'11',left:'-'+options.width+'px',top:'0px'}).show().animate({left:'0px'},options.duration);
								break;
							case "left":
								options.els.eq(options.current).css({'z-index':'11',left:options.width+'px',top:'0px'}).show().animate({left:'0px'},options.duration);
								break;
							case "down":
								options.els.eq(options.current).css({'z-index':'11',top:'-'+options.height+'px',left:'0px'}).show().animate({top:'0px'},options.duration);
								break;
							case "up":
								options.els.eq(options.current).css({'z-index':'11',top:options.height+'px',left:'0px'}).show().animate({top:'0px'},options.duration);	
								break;
								
							}
							
							jQuery.kickScroll.autoChange(options);
						
					},
					options.delay
				);
			}
		}
	}
		
}
		
})(jQuery);



(function(jQuery){
	
	jQuery.fn.twitterScroll = function(options) {
		var el = jQuery(this);
		
		var defaults = {
			tweetCount:5,
			delay:6000,
			fadeTime:1500,
			slideTime:800
		};
		
		var options = jQuery.extend(defaults, options);
	
		if(!options.user) {
			
			alert("No twitter user set");
			
		} else {
				
			var jsonUrl = 'http://twitter.com/statuses/user_timeline/'+options.user+'.json?&count='+options.tweetCount+'&callback=?';
			var twitterData;
			jQuery.getJSON(jsonUrl, function(twitterData) {
			
				for (var i=0; i<twitterData.length; i++){
					
					var status = twitterData[i].text.replace(/((https?|s?ftp|ssh)\:\/\/[^"\s\<\>]*[^.,;'">\:\s\<\>\)\]\!])/g, function(url) { return '<a href="'+url+'">'+url+'</a>'; }).replace(/\B@([_a-z0-9]+)/ig, function(reply) { return  reply.charAt(0)+'<a href="http://twitter.com/'+reply.substring(1)+'">'+reply.substring(1)+'</a>'; });
					var time = jQuery.twitterScroll.relative_time(twitterData[i].created_at);
					el.append('<div class="tweet"><p class="status">'+status+'</p><p class="time">'+time+'</p></div>');
					
				}
				
			});
		
		}
		
			var scrollTimer = window.setInterval(function(){
					el.children().eq(0).fadeTo(options.fadeTime,0.01,function(){
						jQuery(this).slideUp(options.slideTime,function(){
							jQuery(this).appendTo(el).show().fadeTo(1,1);
							
						});
					});			
			},options.delay);
		
	}
		
	jQuery.twitterScroll = {

		relative_time: function(time_value) {
			var values = time_value.split(" ");
			time_value = values[1] + " " + values[2] + ", " + values[5] + " " + values[3];
			var parsed_date = Date.parse(time_value);
			var relative_to = (arguments.length > 1) ? arguments[1] : new Date();
			var delta = parseInt((relative_to.getTime() - parsed_date) / 1000);
			delta = delta + (relative_to.getTimezoneOffset() * 60);
			
			if (delta < 60) {
				return 'less than a minute ago';
			} else if(delta < 120) {
				return 'about a minute ago';
			} else if(delta < (60*60)) {
				return (parseInt(delta / 60)).toString() + ' minutes ago';
			} else if(delta < (120*60)) {
				return 'about an hour ago';
			} else if(delta < (24*60*60)) {
				return 'about ' + (parseInt(delta / 3600)).toString() + ' hours ago';
			} else if(delta < (48*60*60)) {
				return '1 day ago';
			} else {
				return (parseInt(delta / 86400)).toString() + ' days ago';
			}
		}
	
	}

})(jQuery);

// Fixes IE bug that handles select box sizes incorrectly
jQuery.extend({
	
	ieSelectFix: function(){
		
		if( jQuery.browser.msie && jQuery.browser.version < 8 ) {
			
			jQuery('select').each(function(){
				
					var el = jQuery(this);
					
					if( el.data('ie-fixed') == "true" ) return;
					
					var clone = el.clone().appendTo('body');
					
					var el_new_height = clone.height() + ( ( parseInt(clone.css('border-bottom-width')) + parseInt(clone.css('paddingTop')) + parseInt(clone.css('paddingBottom')) + parseInt(clone.css('border-bottom-width')) ) * 2 );
					
					el.height(el_new_height);
					
					var el_new_width = clone.width() + ( ( parseInt(clone.css('border-left-width')) + parseInt(clone.css('paddingLeft')) + parseInt(clone.css('paddingRight')) + parseInt(clone.css('border-right-width')) ) * 2 );
					
					el.width(el_new_width);
					
					el.data('ie-fixed','true');
					
					clone.remove();
							
			});
			
		}
		
	}
	
});

jQuery(function(){
	
	// Call ie select fix on page load
	jQuery.ieSelectFix();

	// Call ie select fix on ajax success
	jQuery(document).ajaxStop(function(){
		jQuery.ieSelectFix();
	});
	
});

// Form Functionality
jQuery.fn.extend({
	validateForm:function(){
		var result = 0;
		jQuery('input,select' , this).each(function(){
			if(result>0) return;
			
			var el = jQuery(this);
			var type =  el.data('type');
			if( el.data('required') !== false ) el.data('required',true);
			if( el.data('maxlen') == "" ) el.data('maxlen',9999);
			if( el.data('minlen') == "" ) el.data('minlen',1);

			if ( jQuery('label[for="' + el.attr('id') + '"]').size() > 0 ) {
				el.data('label', jQuery.trim( jQuery('label[for="' + el.attr('id') + '"]').html().replace(/<.*?>/g,'').replace(':','').replace('*','') ) );
			}
			
			if ( type == 'currency' || type == 'number' ) {
				el.val( el.val().replace(/[^\d]/g,'') );
			} else if ( type == 'tel' || type == 'telephone' ) {
				el.val( el.val().replace(/[^\d\-\(\)\+]/g,'') );
			}
				
			if( el.data('required')==true && el.val()==""){
				el.fieldError({errID:2,label:el.data('label')});
				return result += 1;
			}

			if( el.data('required')==true && ( el.val().length < el.data('minlen') || el.val().length > el.data('maxlen') ) ) {
				el.fieldError({ errID:1 , errLen: el.data('minlen')+" and "+el.data('maxlen'),label:el.data('label') });
				return result += 1;
			}
			
			if( el.data('fieldmatch') ) {
				if(el.val()!=jQuery( el.data('fieldmatch') ).val()) {
					el.fieldError({errID:5,label:el.data('label')});
					return result += 1;
				}
			}
			
			if ( type && ( el.data('required') == true || el.val() != "" ) ) {
			
				if ( type == 'currency' || type == 'number') {
					if(isNaN(el.val())) {
						el.fieldError({errID:6,label:el.data('label')});
						return result += 1;
					}
				} else if ( type == 'email' ) {
					if (!el.val().match(/^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/)) {
						el.fieldError({errID:7,label:el.data('label')});
						return result += 1;
					}
				} else if ( type == 'file' ) {
					var ext = el.val().split('.').pop().toLowerCase();
					var file_types = el.data('file_types').split(',');
					if(jQuery.inArray(ext, file_types) == -1) {
						el.fieldError({errID:8,label:el.data('label')});
						return result += 1;
					}
				}
				
			}
			
		}); 

		jQuery('textarea' , this).each(function(){
			if(result>0) return;
			
			var el = jQuery(this);
			var type =  el.data('type');
			if( el.data('required') !== false ) el.data('required',true);
			if( el.data('maxlen') == "" ) el.data('maxlen',9999);
			if( el.data('minlen') == "" ) el.data('minlen',1);

			if ( jQuery('label[for="' + el.attr('id') + '"]').size() > 0 ) {
				el.data('label', jQuery.trim( jQuery('label[for="' + el.attr('id') + '"]').html().replace(/<.*?>/g,'').replace(':','').replace('*','') ) );
			}

			if( el.data('required')==true && el.val()==""){
				el.fieldError({errID:2,label:el.data('label')});
				return result += 1;
			}
			if( el.data('required')==true && ( $.trim(el.val().replace(/<\/?[^>]+>/gi, '')).length < el.data('minlen') || $.trim(el.val().replace(/<\/?[^>]+>/gi, '')).length > el.data('maxlen') ) ) {
				el.fieldError({ errID:1 , errLen: el.data('minlen')+" and "+el.data('maxlen'),label:el.data('label') });
				return result += 1;
			}
			
			
		}); 

		return (result>0) ? false : true;

	}
});
	
jQuery(function($){	
	
	// Any element with html5 data tag data-submit="true" will submit the form it sits in.
	$(document).on('click','[data-submit="true"]',function(e){
		e.preventDefault();
		$(this).parents('form').submit();
	});
	
	$('form[data-validate="true"]').live('submit',function(e){
		return ( $(this).parents('.popup').size() == 0 ) ? $(this).validateForm() : false;
	});	
	
});



jQuery.fn.extend({
	
	blink:function(options){
		
		var defaults = {
			speed:400,
			delay:200
		}
		
		var options = jQuery.extend(defaults, options);
		
		return this.each(function(){	
		
			var el = jQuery(this);
			
			el.fadeOut(options.speed).fadeIn(options.speed,function(){
				el.delay(options.delay).blink(options);
			});
			
		});










		
	},
	
	newsTicker:function( options ){
		
		var defaults = {
			speed:90,
			wait:3000
		}
		
		if( !jQuery.isArray( options.news ) ) return;
		
		var options = jQuery.extend(defaults, options);
		
		return this.each(function(){	
		
			var el = jQuery(this);
			
			el.html('<span class="text"></span><span class="blink">_</span>');
			
			jQuery('.blink',el).blink();
			
			var el_text = el.children('.text');
			
			newsType = function( key ){
			
				if ( key >= options.news.length ) key = 0;
				
				if ( options.news[key].link ) {
					if ( !options.news[key].link_title ) options.news[key].link_title = options.news[key].text;
					el_text.html( '<a href="' + options.news[key].link + '" title="' + options.news[key].link_title + '" ></a>' ); 
					el_text_inner = jQuery( 'a' , el_text );
				} else {
					el_text_inner = el_text
				}
									
				newsTyping = function() {
					var currentLength = el_text_inner.html().length;
					if ( currentLength < options.news[key].text.length ){
						el_text_inner.append( options.news[key].text.substr( currentLength , 1 ) );
						var newsTypingTimer = window.setTimeout( function() { newsTyping() } , options.speed);
					} else {
						if ( options.news[key].post_text ) el_text.append( options.news[key].post_text );
						var newsTypeTimer = window.setTimeout( function() { newsType( key+1 ) } , options.wait );
					}
				}
				
				newsTyping();
			 
			}
			
			newsType(0);

		});
		
	}
	
});

// Run the blink plugin on everything with the class "blink".
jQuery(function() {
	jQuery('.blink').blink();
});

jQuery.extend({

	geocode:function(options) {

		if( !jQuery.gecoder ) jQuery.extend({ gecoder: new google.maps.Geocoder() });
		
		if( !options.address ) return;
		
		var defaults = {
			bounds:{
				ne:{lat:'63.23362741232568', lon:'3.515625'},
				sw:{lat:'49.837982453084834', lon:'-11.953125'}
				},
			region:'uk'
		}
	
		var options = jQuery.extend(defaults, options);

		var northEast = new google.maps.LatLng(options.bounds.ne.lat,options.bounds.ne.lon);
		var southWest = new google.maps.LatLng(options.bounds.sw.lat,options.bounds.sw.lon);
		var bounds = new google.maps.LatLngBounds(southWest,northEast);

		jQuery.gecoder.geocode( { 'address': options.address, 'bounds': bounds, 'region' : options.region } , function( results , status ) {
			if( status == google.maps.GeocoderStatus.OK ) {
				if( typeof options.success == 'function' ) options.success( results[0].geometry.location );
			} else {
				if( typeof options.error == 'function' ) options.error();
			}
		});		
		
	},
	
	splitLatLon:function( latlon ){
		var cleanlatlon = (typeof latlon != 'string') ? latlon.toString() : latlon;
		var arrLoc = cleanlatlon.substring(1,cleanlatlon.length-1).split(",");
		arrLoc[0] = $.trim(arrLoc[0]);
		arrLoc[1] = $.trim(arrLoc[1]);
		return arrLoc;
	}
	
});

jQuery.fn.extend({
	
	googleMap: function( options , callback ){
		
		//if ( !window.GBrowserIsCompatible || !GBrowserIsCompatible() ) return this;
		
		if( !jQuery.gecoder ) jQuery.extend({ gecoder: new google.maps.Geocoder() });
		
		var defaults = {
			draggable:true,
			scrollwheel:false,
			zoom:14,
			maptype:'roadmap',
			lat:51.5001524,
			lon:-0.1262362,
			region:'uk',
			panControl: false,			// movement controls ( top left )
			streetViewControl: false,	// street view icon ( top left )
			zoomControl: true,			// zoom options ( top left )
			scaleControl: false,			// street view icon ( bottom left )				
			mapTypeControl: true,		// map/satelite options ( top right )
			overviewMapControl: false,	// a mini map of a larget area ( bottom right )
			disableDoubleClickZoom: false
		};
		
		var options = jQuery.extend(defaults, options);
		
		switch(options.maptype) {
			case "roadmap":
				options.mapTypeId = google.maps.MapTypeId.ROADMAP;
				break;
			case "hybrid":
				options.mapTypeId = google.maps.MapTypeId.HYBRID;
				break;
			case "satellite":
				options.mapTypeId = google.maps.MapTypeId.SATELLITE;
				break;
			case "terrain":
				options.mapTypeId = google.maps.MapTypeId.TERRAIN;
				break;									  
			default:
				options.mapTypeId = google.maps.MapTypeId.ROADMAP;
				break;	
		}

		return this.each(function(){
			
			var el = jQuery(this);
			
			if (el.data('map')) return;
			
			var map = new google.maps.Map( this , options );
			
			el.data( 'map' , map );
		
			if( options.address ) {
				
				jQuery.gecoder.geocode( { 'address': options.address, 'region' : options.region } , function( results , status ) {
					if( status == google.maps.GeocoderStatus.OK ) {
						map.setCenter( results[0].geometry.location );
					} else {
						
					}
				
				});
			
			} else {

				options.center = new google.maps.LatLng( options.lat , options.lon );
				map.setCenter( options.center );
			}
			
			if( options.marker ) el.addMarker( options.marker );
			
			if( options.markers ) {
				for (var i in options.markers) {	
					el.addMarker( options.markers[i] );
				}
			}
				
			el.data('options',options);
			
			if( jQuery.isFunction( callback ) ) callback( this , options );
			
		});
		
		

	},
	
	mapIcon:function( name , image ){
		return this.each(function(){
			el = jQuery(this);
			var map = el.data('map');
			if( typeof map != 'object' ) return;
			if( jQuery.isArray( name ) ) {
				for (var i in name) {	
					el.mapIcon( name[i].name , name[i].image );
				}
				return;
			}
			icons = el.data('custom-icons') ? el.data('custom-icons') : {};
			icons[name] = { image:image };
			el.data('custom-icons',icons)
		});
	},
	
	zoomChange:function( zoom_function ){
		if( typeof zoom_function != "function" ) return;
		return this.each(function(){
			el = jQuery(this);
			var map = el.data('map');
			if( typeof map != 'object' ) return;
			google.maps.event.addListener( map , 'zoom_changed', function() {
				var zoom_level = map.getZoom();
				zoom_function(zoom_level);
			});
		});		
	},
	
	getZoom:function(){
		el = jQuery(this);
		var map = el.data('map');
		return ( typeof map == 'object' ) ? map.getZoom() : null ;		
	},
	
	resizeMap:function(){
		el = jQuery(this);
		var map = el.data('map');
		if ( typeof map == 'object' ) google.maps.event.trigger(map, 'resize');
	},
	
	panToMarker:function( ref , zoom ){
		return this.each(function(){
			el = jQuery(this);
			var map = el.data('map');
			if( typeof map != 'object' ) return;
			var markers = el.data('marker-refs') ;
			var marker = markers[ref];
			var location = marker.getPosition();

			if( jQuery.browser.msie && jQuery.browser.version < 9 ) {
				map.setCenter( location );
			} else {
				map.panTo( location );
			}
			
			if( zoom ) map.setZoom( zoom );
			
		});
	},

	setCenter:function(options){
		return this.each(function(){
			el = $(this);
			var map = el.data('map');
			if( typeof map != 'object' ) return;
			if( options.address ) {
				$.gecoder.geocode( { 'address': options.address, 'region' : options.region } , function( results , status ) {
					if( status == google.maps.GeocoderStatus.OK ) {
						map.setCenter( results[0].geometry.location );
					}
				});
			} else if (options.lat && options.lon) {
				options.center = new google.maps.LatLng( options.lat , options.lon );
				map.setCenter( options.center );
			}
		});
	},

	dragMap:function(callback){
		return this.each(function(){
			el = jQuery(this);
			var map = el.data('map');
			if( typeof map != 'object' ) return;
			google.maps.event.addListener( map , 'drag', function() {
				var center = map.getCenter();
				if( typeof callback == 'function' ) callback(center);
			});			
		});
	},
	
	setZoom:function(zoom){
		return this.each(function(){
			el = jQuery(this);
			var map = el.data('map');
			if( typeof map != 'object' ) return;
			if( zoom ) map.setZoom( zoom );
		});
	},
	
	showInfoWindow:function( ref ){
		return this.each(function(){
			el = jQuery(this);
			var map = el.data('map');
			if( typeof map != 'object' ) return;
			var lastinfowindow = el.data('last-info-window');
			if( lastinfowindow ) lastinfowindow.close();
			var infowindows = el.data('info-window-refs');
			var infowindow = infowindows[ref];
			var markers = el.data('marker-refs') ;
			var marker = markers[ref];
			infowindow.open(map,marker);
			el.data('last-info-window',infowindow)
		});
	},
	
	hideInfoWindow:function( ref ){
		
	},
	
	markerAnimation:function( ref , animation ) {
		return this.each(function(){
			el = jQuery(this);
			var map = el.data('map');
			if( typeof map != 'object' ) return;
			var lastmarker = el.data('last-marker');
			if( lastmarker ) lastmarker.setAnimation(null);
			var markers = el.data('marker-refs') ;
			var marker = markers[ref];
			if( animation == 'bounce' ) {
				marker.setAnimation(google.maps.Animation.BOUNCE);
			} else {
				marker.setAnimation(null);
			}
			el.data('last-marker',marker);
		});	
	},
	
	showGroup:function( group ){
		return this.each(function(){
			
			var el = jQuery(this);
			
			var map = el.data('map');
			if( typeof map != 'object' ) return;
			
			var markergroupname = 'marker-group-' + group;
			var markergroup = ( el.data(markergroupname) );
			
			for( i in markergroup ) {
				if( typeof markergroup[i].setMap == "function" ) markergroup[i].setMap(map);
			}	
			
		});
	},
	
	hideGroup:function( group ){
		return this.each(function(){
			
			var el = jQuery(this);
			
			var map = el.data('map');
			if( typeof map != 'object' ) return;
			
			var markergroupname = 'marker-group-' + group;
			var markergroup = ( el.data(markergroupname) );
			
			for( i in markergroup ) {
				if( typeof markergroup[i].setMap == "function" ) markergroup[i].setMap(null);
			}	
			

		});		
	},
	
	deleteGroup:function( group ){
		return this.each(function(){
			
			var el = jQuery(this);
			
			var map = el.data('map');
			if( typeof map != 'object' ) return;
			
			var markergroupname = 'marker-group-' + group;
			var markergroup = ( el.data(markergroupname) );
			
			for( i in markergroup ) {
				if( typeof markergroup[i].setMap == "function" ) markergroup[i].setMap(null);
			}
			
			el.data(markergroupname,null);			

		});		
	},	
	
	deleteMarker: function( ref ){
		return this.each(function(){
			el = jQuery(this);
			var map = el.data('map');
			if( typeof map != 'object' ) return;
			var markers = el.data('marker-refs') ;
			markers[ref].setMap(null);
			markers[ref] = null;
		});
	},
	
	markerDrag: function( ref , callback ){
		return this.each(function(){
			el = jQuery(this);
			var map = el.data('map');
			if( typeof map != 'object' ) return;
			var markers = el.data('marker-refs') ;
			google.maps.event.addListener(markers[ref], 'dragend', function(pos){
				latlng = pos.latLng.toString();
				if( typeof callback == 'function' ) callback( latlng );
			});	
		});
	},	
	
	moveMarker: function(options){
		var defaults = {
			move_map: true
		};
		var options = jQuery.extend( defaults , options );		
		return this.each(function(){
			el = jQuery(this);
			var map = el.data('map');
			if( typeof map != 'object' ) return;
			var markers = el.data('marker-refs');
			if( options.lat && options.lon ) options.position = new google.maps.LatLng( options.lat , options.lon );	
			if( !options.position ) return;
			markers[options.ref].setPosition( options.position );
			if(options.move_map) map.setCenter( options.position );
		});
	},
	
	addMarker: function( options ){
		
		var defaults = {
			animation: google.maps.Animation.DROP,
			infowindowonclick : true,
			image: null,
			icon: null,
			draggable:false
		};
		
		var options = jQuery.extend( defaults , options );
		
		return this.each(function(){
			
			var el = jQuery(this);
			
			var map = el.data('map');
			if( typeof map != 'object' ) return;
			
			var icons = el.data('custom-icons');
			var markers = el.data('marker-refs') ? el.data('marker-refs') : [];
			var infowindows = el.data('info-window-refs') ? el.data('info-window-refs') : [];
			
			if( options.content && !options.infowindow.content ) options.infowindow.content = options.content;

			if( options.address ) {
				
				jQuery.gecoder.geocode( { 'address': options.address } , function( results , status ) {
					
					if( status == google.maps.GeocoderStatus.OK ) {
						
						if ( !options.image ) options.image = options.icon && icons ? icons[options.icon].image : null ;
					
						var marker = new google.maps.Marker({
							position: results[0].geometry.location,
							map: map,
							title: options.title,
							animation: options.animation,
							icon:options.image,
							cursor:options.cursor,
							draggable:options.draggable
						});
					
						if( !options.ref ) options.ref = Math.random();
						markers[options.ref] = marker;
						el.data( 'marker-refs' , markers );						
						
						if( options.group ) {
							var markergroupname = 'marker-group-'+options.group;
							var markergroup = ( el.data(markergroupname) ) ? el.data(markergroupname) : [];
							markergroup.push(marker);
							el.data(markergroupname,markergroup);
						}
						
						if( options.infowindow ) {
							var infowindow = new google.maps.InfoWindow(options.infowindow);
							
							infowindows[options.ref] = infowindow;
							el.data( 'info-window-refs' , infowindows );
												
							if( options.infowindowonclick ) {
								google.maps.event.addListener( marker , 'click' , function () {
									el.showInfoWindow( options.ref );
									if ( jQuery.isFunction( options.marker_select ) ) options.marker_select();
								});
							}					
							
						}
						
					}
				
				});
			
			} else if( options.lat && options.lon ) {
				
				if ( !options.image ) options.image = options.icon && icons ? icons[options.icon].image : null ;
				
				var marker = new google.maps.Marker({
					position: new google.maps.LatLng( options.lat , options.lon ),
					map: map,
					title: options.title,
					animation: options.animation,
					icon:options.image,
					cursor:options.cursor,
					draggable:options.draggable
				});
				
				if( !options.ref ) options.ref = Math.random();
				markers[options.ref] = marker;
				el.data( 'marker-refs' , markers );
				
				if( options.group ) {
					var markergroupname = 'marker-group-'+options.group;
					var markergroup = ( el.data(markergroupname) ) ? el.data(markergroupname) : [];
					markergroup.push(marker);
					el.data(markergroupname,markergroup);
				}				

				if( options.infowindow ) {
					var infowindow = new google.maps.InfoWindow(options.infowindow);
					
					infowindows[options.ref] = infowindow;
					el.data( 'info-window-refs' , infowindows );
										
					if( options.infowindowonclick ) {
						google.maps.event.addListener( marker , 'click' , function () {
							el.showInfoWindow( options.ref );
							if ( jQuery.isFunction( options.marker_select ) ) options.marker_select();
						});
					}					
					
				}
								
			} else {
			
				return
				
			}
		
		});
	
	}
	
});

jQuery.extend({
	
	popup: function ( options ) {

		var defaults = {
			popupClass: "popup-"+Math.random(),
			opacity:0.9,
			fadeInSpeed:400,
			closeButton:true,
			minWidth:600,
			animation:'slide'
		};
		
		var options = jQuery.extend(defaults, options);
		
		jQuery( 'body' ).append( '<div class="' + options.popupClass + ' popup"></div>' );
		
		jQuery( '.popup' ).append( '<div class="popup_bg" /><div class="popup_vert"><div class="popup_content_outer"><div class="popup_content" /></div></div>' );
		
		if( options.animation == 'fade' && !jQuery.browser.msie ) { $('.popup_content_outer').fadeTo(1,0) }
		
		if( options.closeButton ) jQuery( '.popup_content_outer' ).append( '<div class="popup_close">x</div>');
		
		jQuery( '.popup_bg' ).fadeTo( options.fadeInSpeed , options.opacity , function(){
			
			var in_content_area = false;
			
			jQuery('.popup_content_outer').hover(function(){ in_content_area=true; },function(){ in_content_area=false });
			
			jQuery('.popup').bind( 'click' , function(){ 
				if( !in_content_area ) jQuery.popupClose();
			});
			
			options.type = 'get';
			
			jQuery( '.popup_content_outer' ).fadeIn( function(){
				jQuery.popupAjax(options);
			});
			
		});
		
	},
	
	popupAjax: function( options ) {
		
		var minWidth = options.minWidth;
		
		if( !jQuery.isFunction( options.success ) ) {
			
			options.success = function(data) {
				
				jQuery( '.popup_content' ).fadeOut( 200 , function(){
					
					el = jQuery(this);
					el.html('').show().css( 'visibility' , 'hidden' ).html( data );
					
					jQuery.ieSelectFix();
					
					var maxWidth = jQuery(window).width() - 100;
					var maxHeight = jQuery(window).height() - 100;
					
					if( el.width() < maxWidth && el.width() > minWidth ) {
						var newWidth = el.width();
					} else if ( el.width() > maxWidth ) {
						var newWidth = maxWidth;
					} else {
						var newWidth = minWidth;
					}
					
					if( ( jQuery.browser.msie && jQuery.browser.version < 9 ) || options.animation == 'none' ) {

						jQuery( '.popup_content_outer' ).css({width:newWidth+'px'});
						var newHeight = ( el.height() < maxHeight ) ? el.height() : maxHeight;
						var newMargin = - 20 - ( newHeight / 2 );
						jQuery( '.popup_vert' ).css({marginTop:newMargin+'px'});
						jQuery( '.popup_content_outer' ).css({height:newHeight+'px'});
						el.css( 'visibility' , 'visible' );
					
					} else if ( options.animation == 'fade' ){
						
						jQuery( '.popup_content_outer' ).fadeTo(400,0,function(){
							$(this).css({width:newWidth+'px'});
							var newHeight = ( el.height() < maxHeight ) ? el.height() : maxHeight;
							var newMargin = - 20 - ( newHeight / 2 );
							$( '.popup_vert' ).css({marginTop:newMargin+'px'});
							el.css( 'visibility' , 'visible' );
							$( this )
								.css({height:newHeight+'px'})
								.fadeTo(400,1);
						});
						
					} else {
					
						jQuery( '.popup_content_outer' ).animate({width:newWidth+'px'},function(){
							var newHeight = ( el.height() < maxHeight ) ? el.height() : maxHeight;
							var newMargin = - 20 - ( newHeight / 2 );
							jQuery( '.popup_vert' ).animate({marginTop:newMargin+'px'});
							jQuery( '.popup_content_outer' ).animate({height:newHeight+'px'},function(){
								el.css( 'visibility' , 'visible' );
							});
						});
					
					}
					
					jQuery('form',el).bind( 'submit' , function(e) {
						if( jQuery(this).data('ajax') !== false ) {
							e.preventDefault();
							if( jQuery(this).data('validate') !== true || jQuery(this).validateForm() == true ) {
								jQuery.popupAjax({
									type:jQuery(this).attr('method'),
									url:jQuery(this).attr('action'),
									data: jQuery(this).serialize()
								});
							}
						}
					});
					
					jQuery('a',el).bind('click',function(e){
						// fixes preventDefault and stopPropagation bug for dynamically generated elements
						if(e.target != this) return true;
						if( jQuery(this).data('ajax') !== false ) {
							e.preventDefault();
							if( jQuery(this).data('submit') != true && jQuery(this).attr('href') != "#" ) {
								jQuery.popupAjax({ url:jQuery(this).attr('href') });
							}
						}
					});
										
				});
				
			}
			
		}
		
		jQuery.ajax( options );
		
	},
	
	popupClose:function(){
		jQuery('.popup_content_outer').fadeOut(200,function(){
			jQuery('.popup_bg').fadeOut(400,function(){
				jQuery('.popup').remove();
			});
		});
	}
	
});

jQuery(function(){
	jQuery('.popup_close').live('click',function(){ jQuery.popupClose(); });
});
 
(function($){
	
	$.fn.hovercard = function(options) {
		
		var $window = $(window);
		
		var defaults = {
			background:'#ffffff',
			padding:10,
			x_pos:20,
			y_pos:20,
			shadow_x:'1px',
			shadow_y:'1px',
			shadow_blur:'5px',
			shadow_color:'#888',
			z_index:'999999'
		};
		
		var options = jQuery.extend(defaults, options);
		
		return this.each(function(){
		
			var $this = $(this);
			
			if($this.data('open')) return;
			
			var src = $this.data('hovercard');
			var position = $this.offset();
			var mouseover = true;
			var $hovercard = 
				$('<div class="hovercard" />')
					.css('position','absolute')
					.css('background',options.background)
					.css('padding',options.padding+'px')
					.css('top',( position.top + options.y_pos)+'px' )
					.css('left',(position.left+options.x_pos)+'px')
					.css('box-shadow',options.shadow_x+' '+options.shadow_y+' '+options.shadow_blur+' '+options.shadow_color)
					.css('z-index',options.z_index)
					.appendTo('body');
			$this.data('open',true)

			var closeMe = function(){
				if( mouseover ) return;
				$hovercard.remove();
				$this.unbind('mouseenter',mouseenter);
				$this.unbind('mouseleave',mouseleave);
				$this.data('open',false)
			}
			
			var mouseenter = function() {
				mouseover=true
			}
			
			var mouseleave = function() {
				mouseover=false;
				window.setTimeout( closeMe , 100 )
			}			
			
			$.ajax({
				url:src,
				success:function(data){
					$hovercard.html(data);
					if( $hovercard.offset().top + $hovercard.height() > $window.height() ) $hovercard.css('top',$hovercard.offset().top - $hovercard.height()+'px');
				}
			})
			
			$this.bind({'mouseenter':mouseenter,'mouseleave':mouseleave});
			$hovercard.bind({'mouseenter':mouseenter,'mouseleave':mouseleave});
		
		});
		
	}

})(jQuery);

jQuery.extend({
	
	'redirect':function(url){ window.location = url },
		
	'isInt':function(value) { 
		return ((parseFloat(value) == parseInt(value)) && !isNaN(value));
	}
	
});
