/*
	
	ISITE Design Global Javascript Functions 2011
	
*/

/*globals $,jQuery,window,setTimeout,document,pageTracker,_gaq,google,tabmaps */

// jquery no conflict. use $j or jQuery outside of ready function
var $j = jQuery.noConflict(); 

// jQuery document ready
jQuery(function ($) {
	
	// Drupal inserts no-js
	$('html').toggleClass('no-js js');
	
	// Pull the label, set as default value and hide it
	$('.sign-up input').inputSetter();

	// agency tidbits scroller
	if ($("#agencytidbits").length > 0) {
		blobToScroll.init($("#agencytidbits p"), "…");
	}
	
	// tabs
	$('.ix-tabs').IX_tabs(0, tabCallback);
	
	// makes a horizontal single frame carousel (i.e., perpetual) scroller.
	$('.filmstrip').IX_filmstrip();
	
	$(".column.network.last ul, #primary ul.links, .statistics ul").find("li:first").addClass('first');
	$("footer ul, .statistics ul").find("li:last").addClass('last');
	
	$("#secondary aside a, .sort-by a").click(function () {
		$(this).toggleClass("active");
	});	
	
	// Work: Caption Sliding (Partially Hidden to Visible)  
	$('.project.caption').hover(function () {  
		$(".cover", this).stop().animate({top: '0'}, {queue: false, duration: 200});  
		$(".cover h3", this).stop().animate({marginTop: '12px'}, {queue: false, duration: 200});  // bump for better alignment
		$(".cover p, .cover .actions", this).stop().fadeIn(200, function () {
			jQuery(this).css('opacity', 1);
		});
	}, function () {  
		$(".cover", this).stop().animate({top: '189px'}, {queue: false, duration: 200});
		$(".cover h3", this).stop().animate({marginTop: '0'}, {queue: false, duration: 200}); 
		$(".cover p, .cover .actions", this).stop().fadeOut(200, function () {
			jQuery(this).css('opacity', 0);
		});
	});
	// decor for bottom border
	jQuery('body.page-work li.project').append('<span class="decor"></span>');
	// bind overlay
	$j('a.gallery').IX_overlayGallery();

	// we still open new windows
	$('a[href^=http://]').not('[href*=' + window.location.host + ']').attr('target', '_blank');
	
	// initialize homepage rotator
	if (typeof rotatorcontent !== "undefined") {
		$('.rotator').IX_rotator(rotatorcontent);
	}

	// validate insight signup
	jQuery.validator.addMethod("notEqualTo", function (value, element, param) {
		return $(element).val() !== $(element).prev("label").text();
	}, "error");	
	
	if ($("#insightsignup").length > 0) {
		$("#insightsignup").validate({
			rules: {
					email: { required: true, email: true, notEqualTo: true },
					firstname: { required: true, notEqualTo: true },
					lastname: { required: true, notEqualTo: true }
				},
				messages: {
					email: "Please enter a valid email address",
					firstname: "Please enter your first name",
					lastname: "Please enter your last name"
				},
				errorPlacement: function (label, element) {
					var after = element.next().is("span.required") ? element.next() : element;
					label.insertAfter(after);
				},
				submitHandler: function (form) {
					$("#insightsignup label.error").remove();
					$("#insightsignup fieldset").append('<p class="loading">Submitting request</p>');
					$.ajax({
						type: "POST",
						url: $(form).attr("action"),
						data: "ajax=true&email=" + $("#email").val() + "&firstname=" + $("#firstname").val() + "&lastname=" + $("#lastname").val() + "&company=" + $("#company").val(),
						success: function () {
							var addr = $("#email").val();
							$("#insightemailfeed").remove();
							$("#insightsignup").replaceWith('<p id="insightsuccess"><strong>Success!</strong> ' + addr + ' has been subscribed.</p>');
							_gaq.push(['_trackPageview', '/insight-blog/thank-you']);							
						},
						error: function () {
							$("p.loading").remove();
							var addr = $("#email").val();
							$("#insightsignup fieldset").append('<p class="error">Sorry. ' + addr + ' could not be subscribed.</p>');
						}
					});
				}
			});
	}
	
	// This code is used with the TEDx Portland sign up form isitedesign.com/ted
	// It is the same as the insight code above except it does not ping Google analytics for insight numbers
	if ($("#tedsignup").length > 0) {
		$("#tedsignup").validate({
			rules: {
					email: { required: true, email: true, notEqualTo: true },
					firstname: { required: true, notEqualTo: true },
					lastname: { required: true, notEqualTo: true }
				},
				messages: {
					email: "Please enter a valid email address",
					firstname: "Please enter your first name",
					lastname: "Please enter your last name"
				},
				errorPlacement: function (label, element) {
					var after = element.next().is("span.required") ? element.next() : element;
					label.insertAfter(after);
				},
				submitHandler: function (form) {
					$("#tedsignup label.error").remove();
					$("#tedsignup fieldset").append('<p class="loading">Submitting request</p>');
					$.ajax({
						type: "POST",
						url: $(form).attr("action"),
						data: "ajax=true&email=" + $("#email").val() + "&firstname=" + $("#firstname").val() + "&lastname=" + $("#lastname").val() + "&company=" + $("#company").val(),
						success: function () {
							var addr = $("#email").val();
							$("#tedemailfeed").remove();
							$("#tedsignup").replaceWith('<p id="tedsuccess"><strong>Success!</strong> ' + addr + ' has been subscribed.</p>');
							
						},
						error: function () {
							$("p.loading").remove();
							var addr = $("#email").val();
							$("#tedsignup fieldset").append('<p class="error">Sorry. ' + addr + ' could not be subscribed.</p>');
						}
					});
				}
			});
	}
	
	
	
	// insight GA tracking
	if ($(".section-insight-blog").length && $(".taxonomy").length) {
		$(".taxonomy .links a[rel=tag]").each(function () {
			_gaq.push(['_trackEvent', 'Insight Articles', jQuery(this).text()]);	
		});		
	}	
	
	// help for variant default font sizes vs abs pos elements
	jQuery('.front #secondary').css('margin-top', function () {
		return (jQuery('.front aside.content-wrapper').height() - 98) + 'px';
	});
	
});// document ready


// application logic

// jQuery plugins
//take blob of text, divide to li's and build scroller
var blobToScroll = {
	$obj: {},
	splitted: [],
	$that: {},
	init: function (el, string) {
		blobToScroll.$obj = el || $("body");
		blobToScroll.splitted = blobToScroll.$obj.html().split(string);
		blobToScroll.build();
	},
	build: function () {
		$j.scroller = $j("<ul></ul>");
		$j.each(blobToScroll.splitted, function () {
			$j.scroller.append("<li>" + $j.trim(this) + "</li>");
		});
		blobToScroll.$obj.replaceWith($j.scroller);
		var maxheight = 0;
		$j.scroller.find("li").each(function () {
			maxheight = $j(this).height() > maxheight ? $j(this).height() : maxheight;
		});
		$j.scroller.css({ height: maxheight + "px", overflow: "hidden" });
		$j.scroller.find("li:not(:first)").hide();
		setTimeout(function () {
			blobToScroll.scroller($j.scroller);
		}, 4000);
	},
	scroller: function ($obj) {
		var $next = $obj.find("li:visible").next().length > 0 ? $obj.find("li:visible").next() : $obj.find("li:first");
		$obj.find("li:visible").fadeOut("fast", function () {
			$next.fadeIn("fast", function () {
				blobToScroll.$that = $j(this);
				setTimeout(function () {
					blobToScroll.scroller(blobToScroll.$that.parent());
				}, 4000);
			});
		});		
	}
};

// makes a horizontal single frame carousel (i.e., perpetual) scroller.
// http://jqueryfordesigners.com/jquery-infinite-carousel/
(function ($) {
	$.fn.IX_filmstrip = function () {
		
		// utility to repeat a string specified number of times.
		function repeat(str, num) {
			return new Array( num + 1 ).join(str);
		}

		return this.each(function () {
		
			// initialize styles
			jQuery(this).addClass('IX_filmstrip');
			
			var	$filmstrip = jQuery(this),
				$wrapper = $('> ul', this).wrap('<div class="viewport"></div>').parents('.viewport'),
			    $slider = $wrapper.find('> ul'),
			    $items = $slider.find('> li'),
			    $single = $items.filter(':first').addClass('current'),

				$prev = jQuery('<span class="prev">prev</span>'),
				$next = jQuery('<span class="next">next</span>'),
				$pager = jQuery('<div class="pager"><span class="current">1</span> of <span class="total-slides"></span></div>'),
				
				singleWidth = $single.outerWidth(true), 
			    visible = Math.ceil($wrapper.innerWidth() / singleWidth), // note: doesn't include padding or border
			    currentPage = 1,
			    pages = Math.ceil($items.length / visible);
			
			// skip the controls if we don't need them
			if(pages === 1) {
				return true;
			}
			
			// setup framework
			$pager.find('.total-slides').text($items.length);
			jQuery('.filmstrip-utility', $filmstrip).or($filmstrip).prepend($pager).append($next).append($prev);

			// Pad so that 'visible' number will always be seen, otherwise create empty items
			if (($items.length % visible) !== 0) {
			    $slider.append(repeat('<li class="empty" />', visible - ($items.length % visible)));
			    $items = $slider.find('> li');
			}

			// Top and tail the list with 'visible' number of items, top has the last section, and tail has the first
			$items.filter(':first').before($items.slice(- visible).clone().addClass('cloned'));
			$items.filter(':last').after($items.slice(0, visible).clone().addClass('cloned'));
			$items = $slider.find('> li'); // reselect
						
			// reset width to hold additional items
			$slider.width(singleWidth * $items.length);
			
			// Set the left position to the first 'real' item
			$wrapper.scrollLeft(singleWidth * visible);
	       
			// paging function
			function gotoPage(page) {
			    var dir = page < currentPage ? -1 : 1,
			        n = Math.abs(currentPage - page),
			        left = singleWidth * dir * visible * n;
								
				// show page number in pager
				$pager.find('.current').text(page > pages ? 1 : page === 0 ? pages : page);	
					
			    $wrapper.filter(':not(:animated)').animate({
			        scrollLeft : '+=' + left
			    }, 500, function () {
					// secretly reset position to beginning or end of list depending on page
			        if (page === 0) {
			            $wrapper.scrollLeft(singleWidth * visible * pages);
			            page = pages;
			        } else if (page > pages) {
			            $wrapper.scrollLeft(singleWidth * visible);
			            page = 1;
			        }
			        currentPage = page;
			    });                

			    return false;
			}

			// Bind to the forward and back buttons
			$prev.click(function () {
			    return gotoPage(currentPage - 1);                
			});

			$next.click(function () {
			    return gotoPage(currentPage + 1);
			});

			// create a public interface to move to a specific page
			$filmstrip.bind('goto', function (event, page) {
				gotoPage(page);
			});
						
			// attach bonus actions
			if ($filmstrip.is('.gallery')) {
											
				$items.find('a').click(function () {
					
					// bail if already displayed
					if (jQuery(this).parent().is('.current')) {
						return false;
					}
					
					var $this = jQuery(this),
						src = $this.attr('href'),
						title = $this.attr('title'),
						container = jQuery('#filmstrip-img'),
						color = jQuery('#filmstrip-title').css('color'),
						img = new Image();
						
					// set new current item
					$this.parent().addClass('current').siblings().removeClass('current');
					
					// fade out the old
					jQuery('#filmstrip-img img:visible').fadeOut(function () {
						jQuery(this).remove();
					});
					jQuery('#filmstrip-title').animate({ 'opacity' : 0 },function(){
						jQuery(this).text(title);
					});
					
					// load the image, insert, present
					jQuery(img).load(function () {						
						jQuery(this).css('display', 'none');
						jQuery(this).appendTo('#filmstrip-img').fadeIn();
						jQuery('#filmstrip-title').animate({ 'opacity' : 1 });
					}).error(function () {						
						jQuery('#filmstrip-img').html('<h3>Image could not be loaded</h3>');
					}).attr('src', src);
					
					return false;
					
				});
			}					
			
	   });  
	};
	
})(jQuery);

/**
 * IX_overlayGallery
 *
 * create a filmstrip-like gallery over a lightbox-like overlay
 * based on IX rotator plugin.
 *
 */
(function ($) { 

	// plugin
	$.fn.IX_overlayGallery = function (options) {

		// things to build, stores reused elements
		var tpl = $.extend({}, {
			overlay : $('<div id="IX_of-overlay"></div>'),
			slideshow : $('<div id="IX_of"></div>'),
			viewport : $('<div id="IX_of-viewport"></div>'),
			utility : $('<div class="filmstrip-utility"></div>'),
			previous : $('<span class="prev">prev</span>'),
			next : $('<span class="next">next</span>'),
			pager : $('<ul class="pager"></ul>'),
			close : $('<span id="IX_of-close">Close</span>')
		}),
		// things to help and store state
			win = {
				h : $(window).height(),
				w : $(window).width(), 
				l : $(window).scrollLeft(),
				t : $(window).scrollTop()
			}, 
			obj = {}, // store current slide data and html
			status = false, // gallery visibility status
			cache = {}, // cache previously viewed items to prevent secondary request
			ipad = navigator.userAgent.match(/iPad/i) != null; // dirty sniff TODO: feature detect

		// move things along, run once
		if (this.length) {
			init();
		}

		// apply to all gallery items
		return this.each(function () {

			var $this = $(this);

			$this.bind("click", function (e) {
				e.preventDefault();

				if (status !== true) { // prevent double clicks from double invoke

					status = true;

					// test for already viewed
					// cache once viewed
					var store = $(this).attr('href').split('/').pop();			
					if (typeof cache[store] !== 'undefined') {
						trigger(cache[store]);
					} else {
						$.get(this.href, function (data) {
							trigger(data);
							cache[store] = data;
						});
					}

					// size and display overlay
					tpl.overlay.height($(document).height()).width(parseInt($(document).width()) + 50 + 'px').show();
					$('body').addClass('of-on loading');

					// tracking
					obj.client = $(this).parents('.project-caption').find('h3').text();
					_gaq.push(['_trackEvent', 'Our_Work', obj.client, '1']);	

				}

			});	

			// launch incoming projects		
			if (window.location.hash) {
				jQuery('ul.projects a.button[href="' + window.location.hash.replace('#', '') + '"]').click();
			}		

		}); // return each


		function init(opts) {

			// assemble the lightbox components and append to the body.
			tpl.overlay.hide();

			var ut = tpl.utility.append(tpl.previous).append(tpl.pager).append(tpl.next),
				vp = tpl.viewport.append(ut),
				ss = tpl.slideshow.hide().append(tpl.viewport).addClass('IX_overlayFilmstrip').width($(document).width());
			
			// set up pager events
			tpl.previous.bind('click', { dir : -1 }, move);
			tpl.next.bind('click', { dir : 1 }, move);

			$('body').append(tpl.overlay).append(tpl.slideshow);

			// window bindings for keys and resize events
			$(document).keydown(function (e) {

				if (status === true) {

					switch (e.which) {
					case 37: //left
					case 38: //up
						move({ data : { dir : -1 }}); // obj to match the event obj sent by jquery on clicks of prev/next buttons
						break;
					case 39: //right
					case 40: //down
						move({ data : { dir : 1 }});
						break;
					case 27: //escape
						close();
						break;
					case 49: //1
						$('ul.pager li:eq(0)').click();		
						break;
					case 50: //2
						$('ul.pager li:eq(1)').click();		
						break;
					case 51: //3
						$('ul.pager li:eq(2)').click();		
						break;
					case 52: //4
						$('ul.pager li:eq(3)').click();		
						break;
					case 53: //5
						$('ul.pager li:eq(4)').click();		
						break;
					}		
					return $.inArray(e.keyCode, [37, 38, 39, 40, 27, 49, 50, 51, 52, 53]) === -1;
				} else {
					return true;
				}
			});
			
			$(window).resize(function () {

				if (status === true && typeof obj !== 'undefined') {
				
					// set height for dynamic resize
					setSlidesDimension();

					// resize and center slides
					calculateSlides();
				}

			});	// check for and set up touch events

			// ipad swipe
			if(document.ontouchstart !== undefined) {
				tpl.viewport.swipe({
					swipeLeft : function() {
						if(status) {
							move({ data : { dir : 1 }})
						}
					},
					swipeRight : function() {
						if(status) {
							move({ data : { dir : -1 }})
						}
					}				   
				});
			}
			
		} // init

		function trigger(content) {

			var $c = $(content);								

			obj.$strip = $c.find('> ul');
			obj.$items = obj.$strip.find('> li');
			obj.$single = obj.$items.filter(':first').addClass('current');
			obj.singleWidth = obj.$single.outerWidth(true); // need to wait until visible to calculate?

			$('#IX_of-viewport').prepend($c);

			// set height for dynamic resize
			setSlidesDimension();

			// insert close button
			tpl.close.bind('click', close).insertBefore(obj.$strip);

			// size filmstrip
			// push of screen with visible display in order to be able to gather dimensions
			tpl.slideshow.css('left', '-9999em').show(); // height/width in css
			obj.current = 0;
			calculateSlides();

			//bind functionality and add numbered nav list
			obj.$items.each(function (i) {
				var pageLink = $('<li>' + (i + 1) + '</li>');
				if (i + 1 === 1) { 
					pageLink.addClass('on');
					tpl.previous.addClass('off');
				}
				pageLink.bind('click', function () {
					var current = $('.on', tpl.pager);
					moveTo((-1 * (i * obj.slideWidth)), (Math.abs(i - (current.text() - 1)) * 500));
					current.removeClass('on');
					tpl.previous.removeClass('off');
					tpl.next.removeClass('off');
					$(this).addClass('on');					
					(i + 1 === 1) ? tpl.previous.addClass('off') : false;
					(i + 1 === obj.$items.length) ? tpl.next.addClass('off') : false;

					obj.current = $(this).index();

					// track slide view for GA
					_gaq.push(['_trackEvent', 'Our_Work', obj.client, $(this).text()]);	
				});
				tpl.pager.append(pageLink);
			});

			// Everthing is built and all behaviors are bound.  now we reveal the filmstrip.
			tpl.slideshow.css({ 'display': 'none', 'left': 0 }).fadeIn('slow', function () {
				open();
			});

		} // trigger

		function open() {
			$('body').removeClass('loading');
		} // open

		function close() {

			// clean up
			tpl.slideshow.hide();
			tpl.pager.empty();
			tpl.viewport.find('.filmstrip').remove();
			tpl.overlay.hide();
			$('body').removeClass('of-on');
			status = false;

		} // close

		function moveTo(pos, dur) {
			
			obj.$strip[ipad ? 'animateWithCss' : 'animate']({ left: pos }, dur, 'linear');
			//obj.$strip.animate({ left: pos }, dur);
			
		} // scrollTo		

		function move(e) {

			var current = $('.on', tpl.pager),
				child = e.data.dir === 1 ? ":last-child" : ":first-child",
				action = e.data.dir === 1 ? 'next' : 'prev';

			if (!current.is(child)) {
				current[action]('li').click();
			}
			return false;

		} // move

		function setSlidesDimension($obj) {
			if (typeof obj.$items !== 'undefined') {
				obj.$items.height(($(window).height() * 0.65) + 'px');
			}
		} // setSlidesDimension

		function calculateSlides() {
			
			if (typeof obj.$single !== 'undefined') {
				// calculate based on set dimensions from viewable window
				obj.slideMargin = parseInt(obj.$single.css('marginRight'), 10); // margin set in CSS for each li
				obj.slideWidth = ((obj.$single.height() / 580) * 730) + obj.slideMargin; // width of each slide based on percent of calculated height and content fixed width //(comps.slides.width() + parseInt(comps.slides.css('marginRight'), 10)),
				obj.stripWidth = (obj.slideWidth * obj.$items.length) + 20; // width of the whole thing with some bonus pixels for safety
				obj.stripMargin = ($('#IX_of-viewport').width() - obj.slideWidth) / 2; // left margin keeps scaled images centered in viewport			

				// set
				obj.$items.css('width', (obj.slideWidth - obj.slideMargin) + 'px');												
				obj.$strip.css({
					'width': obj.stripWidth + 'px',
					'marginLeft': obj.stripMargin + 'px',
					'left': obj.slideWidth * -obj.current
				});
			}

		} // caclulateSlides

	};

}(jQuery));


// IX_rotator plugin for homepage
// wrap it up with jQuery passed in as $ for name collision safety
(function ($) {

	// plugin definition
	$.fn.IX_rotator = function (content, options) {

		// if the content didn't get created or isn't an object, bail now before errors get tossed
		if (content === undefined || typeof content !== "object") {
			return this;
		}

		// build main options before element iteration
		// extends exposed defaults property
		// options might include transition effects or speeds or ???
		var opts = $.extend({}, $.fn.IX_rotator.defaults, options),

			// vaaarrrrrs	
			$this   = $(this),          // the rotator container
			$ul     = $('<ul />').addClass(opts.className || "rotator"), // the new rotator container
			current	= opts.show || 1,   // current displayed rotatee
			total   = content.length;   // total number of rotatee
						
		// loop over content object and build out each rotatee	
		for (var j = 0; j < total; j++) {
											
			if(typeof content[j] === 'object') { // defense against trailing comma in rotatorcontent in ie
				
				var rotatee = $.fn.IX_rotator.tmpl.replace(/<%=image%>/g, content[j].image.replace(/\s/g, "%20"))
												.replace(/<%=title%>/g, content[j].title)
												.replace(/<%=content%>/g, content[j].content),
					links = "";			

				// for items that could have more than one, loop to create
				// this example uses multiple links placed into the btn template
				$.each(content[j].links, function (i) {
					if (content[j].links[i].url !== null) {
						links += $.fn.IX_rotator.btn.replace(/<%=url%>/g, content[j].links[i].url)
													.replace(/<%=text%>/g, content[j].links[i].text);														 
					}
				});
				$(rotatee).find('.nav-rotator').append(links).end().appendTo($ul);
			
			}

		}				
		
		// make the nav and counter		
		$ul.append($.fn.IX_rotator.nav);

		// hide all but the default rotatee
		$('li.rotator-item:not(:eq(' + (current - 1) + '))', $ul).hide();

		// dump in the new html structure
		$this.html($ul);
		
		// add pager dots
		for (var i = 0; i < total; i++) {
			if(typeof content[i] === 'object') { // defense against trailing comma in rotatorcontent in ie
				var on = (i === 0) ? 'on' : '';
				$('span.pages').append('<span class="dots ' + on + '"></span>');
			}
		}		

		// the cycler
		var cycle = function (e, i) {
			// set current depending on what nav item was pressed			
			current = $(e.target).parents('.arrow-previous').length ? current += -1 : current += 1;
			// loop to beginning or end if previous setting resulted in non-existent rotatee
			current = current < 0 ? total - 1 : current === total ? 0 : current;
			
			var c = '';
			if (i == null) {
				c = current - 1;
			} else {
				c = i;
				current = (i + 2 > total) ? 0 : i + 1;
			}

			$('li.rotator-item:visible', $this).fadeOut(1000);
			$('li.rotator-item', $this).eq(current - 1).fadeIn(1000);
			$('.dots.on').removeClass('on');
			$('.dots', $this).eq(current - 1).addClass('on');
		};

		// start the auto rotating
		if($.fn.IX_rotator.defaults.auto) {
			var speed = $.fn.IX_rotator.autospeed || 7000;
			$.fn.IX_rotator.rotate = setInterval(function () {
				$this.trigger('rotate');
			}, speed);
		}

		// image preloading
		for (var i = 0, length = content.length; i < length; i++) {
			if(typeof content[i] === 'object') { // defense against trailing comma in rotatorcontent in ie
				$('<img>').attr("src", content[i].image.replace(/\s/g, "%20"));
			}
		}	

		// return and iterate
		return this.each(function () {
			$('a.btn-arrow', this).live('click', function (e) {
				clearInterval($.fn.IX_rotator.rotate);
				cycle(e);
				return false;
			});
			$(this).bind('rotate', function (e) {
				cycle(e);
				return false;
			});
			$('.dots').each(function (i) {
				$(this).click(function (e) {
					if(!$(this).is('.on')) {
						clearInterval($.fn.IX_rotator.rotate);
						cycle(e, i);
					}
				});				
			});
		});

	}; // end plugin definition

	// exposed functions

	// default options
	$.fn.IX_rotator.defaults = {	
		transition : "fade",
		speed : 100,
		auto : true,
		autospeed : 7000	
	};

	// base html templates
	// better to base of html?
	$.fn.IX_rotator.tmpl = '<li class="rotator-item" style="background-image:url(<%=image%>);"><div class="wrapper"><h1><%=title%></h1><div class="content"><p><%=content%></p></div><div class="nav-rotator"></div></div></li>';
	$.fn.IX_rotator.btn  = '<a class="button gallery" href="<%=url%>"><%=text%></a>';
	$.fn.IX_rotator.nav  = '<li class="nav-rotate"><ul><li class="arrow-previous"><a class="btn-arrow ir" href="#">Previous</a></li><li class="arrow-next"><a class="btn-arrow ir" href="#">Next</a></li></ul><span class="pages"></span></li>';

})(jQuery);


// pull label and insert as field. clear with click
// optional lower param if == 1, string toLowerCase
jQuery.fn.inputSetter = function (lower) {	
	return this.each(function () {
		var $input = jQuery(this),
			$label = jQuery("label[for='" + $input.attr("id") + "']"),
			labeltext = lower && lower === 1 ? $label.text().toLowerCase() : $label.text();
		$label.hide();	
		$input.val(labeltext);		
		$input.focus(function () {
				if (this.value === labeltext) {
					this.value = "";
				}
			}).blur(function () {
				if (!this.value.length) {
					this.value = labeltext;
				}
			});
	});
};

// generic tab builder
jQuery.fn.IX_tabs = function (tab, callback) {	
	return this.each(function () {
		var $container = jQuery(this), 
			$tabs = jQuery("a", this),
			panes = [];

		$tabs.each(function () {
			var $this = jQuery(this),
				pane = $this.attr('href'); // using the href to make the collection of panes
				
			if (pane.indexOf("#") !== 0) {
				return true;
			}
			panes.push(pane);

			$this.bind("click", function () {
				jQuery(panes.join(",")).hide();
				$container.find('.active').removeClass('active');
				$this.parent("li").addClass("active");
				jQuery(pane).show();
				if (typeof callback !== 'undefined') {
					callback($tabs, tab, jQuery(pane));
				}
				return false;
			});
		});
		
		var urltab = window.location.hash,
			show = urltab !== "" || jQuery('a.default', $container).length ? urltab !== "" ? $tabs.index(jQuery('a[href=' + urltab + ']')) : $tabs.index(jQuery('a.default')) : tab || 0;
		$tabs.eq(show).length ? $tabs.eq(show).click() : $tabs.eq(0).click();
	});
};
// google maps doesn't like being hid onload
var tabCallback = function (tabs, tab, obj) {
	if (typeof tabmaps !== 'undefined') {
		var og = window.location.hash !== '' ? jQuery(window.location.hash) : jQuery(tabs.eq(tab).attr('href'));
		if (!obj.is('.set') && obj.index('.tab-content') !== og.index('.tab-content')) {
			var map = obj.attr('id');
			google.maps.event.trigger(tabmaps[map], 'resize');
			tabmaps[map].setCenter(new google.maps.LatLng(tabmaps[map].lat, tabmaps[map].lng));
		}
	}
	obj.addClass('set');	
};

// or utility
jQuery.fn.or = function(s) {
	return jQuery(this).length ? jQuery(this) : jQuery(s);
};

/*
 * jSwipe - jQuery Plugin
 * http://plugins.jquery.com/project/swipe
 * http://www.ryanscherf.com/demos/swipe/
 *
 * Copyright (c) 2009 Ryan Scherf (www.ryanscherf.com)
 * Licensed under the MIT license
 *
 * $Date: 2009-07-14 (Tue, 14 Jul 2009) $
 * $version: 0.1.2
 * 
 * This jQuery plugin will only run on devices running Mobile Safari
 * on iPhone or iPod Touch devices running iPhone OS 2.0 or later. 
 * http://developer.apple.com/iphone/library/documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html#//apple_ref/doc/uid/TP40006511-SW5
 */
(function($) {
	$.fn.swipe = function(options) {
		
		// Default thresholds & swipe functions
		var defaults = {
			threshold: {
				x: 14,
				y: 32
			},
			swipeLeft: function() { },
			swipeRight: function() { }
		};
		
		var options = $.extend(defaults, options);
		
		if (!this) return false;
		
		return this.each(function() {
			
			var me = $(this);
			
			// Private variables for each element
			var originalCoord = { x: 0, y: 0 }
			var finalCoord = { x: 0, y: 0 }
			
			// Screen touched, store the original coordinate
			function touchStart(event) {
				//console.log('Starting swipe gesture...')
				originalCoord.x = event.targetTouches[0].pageX
				originalCoord.y = event.targetTouches[0].pageY
			}
			
			// Store coordinates as finger is swiping
			function touchMove(event) {
			    event.preventDefault();
				finalCoord.x = event.targetTouches[0].pageX // Updated X,Y coordinates
				finalCoord.y = event.targetTouches[0].pageY
			}
			
			// Done Swiping
			// Swipe should only be on X axis, ignore if swipe on Y axis
			// Calculate if the swipe was left or right
			function touchEnd(event) {
				//console.log('Ending swipe gesture...')
				var changeY = originalCoord.y - finalCoord.y
				if(changeY < defaults.threshold.y && changeY > (defaults.threshold.y*-1)) {
					changeX = originalCoord.x - finalCoord.x
					
					if(changeX > defaults.threshold.x) {
						defaults.swipeLeft()
					}
					if(changeX < (defaults.threshold.x*-1)) {
						defaults.swipeRight()
					}
				}
			}
			
			// Swipe was started
			function touchStart(event) {
				//console.log('Starting swipe gesture...')
				originalCoord.x = event.targetTouches[0].pageX
				originalCoord.y = event.targetTouches[0].pageY

				finalCoord.x = originalCoord.x
				finalCoord.y = originalCoord.y
			}
			
			// Swipe was canceled
			function touchCancel(event) { 
				//console.log('Canceling swipe gesture...')
			}
			
			// Add gestures to all swipable areas
			this.addEventListener("touchstart", touchStart, false);
			this.addEventListener("touchmove", touchMove, false);
			this.addEventListener("touchend", touchEnd, false);
			this.addEventListener("touchcancel", touchCancel, false);
				
		});
	};
})(jQuery);
(function($){

// ----------
// Function: animateWithCSS
// Uses CSS transitions to animate the element. 
// based on http://www.azarask.in/blog/post/animation-css-transitions-jquery-easy/
$.fn.animateWithCss = function(props, speed, easing, callback) {
	var optall = jQuery.speed(speed, easing, callback),
		easings = {
			bounce: 'cubic-bezier(0.0, 0.35, .5, 1.3)', 
			linear: 'linear',
			swing: 'ease-in-out'
		};

	optall.easing = optall.easing || "swing";
	optall.easing = easings[optall.easing] ? easings[optall.easing] : optall.easing;

	this.css({
		'-webkit-transition': '-webkit-transform ' + optall.duration + 'ms linear',
		'-webkit-transform' : 'translate3d(' + props.left + 'px, 0, 0)'
	});
	return this;
}

})(jQuery);
// etc

// prevent IE6 flicker
try {
	document.execCommand('BackgroundImageCache', false, true);
} catch (e) {}
