$(document).ready(function(){

	if ( $('#instagram').length ) {
		$('#instagram').flickr().photosSearch({user_id: '98591237@N00', per_page: 5, tags: 'instagram app'})
	}
	
	$('body#support #questions .content').columnize( {columns:2, lastNeverTallest : true} ).removeClass('twocol');
	$('#questions.product .content').columnize( {columns:2} ).removeClass('twocol');
	
	// Product Gallery initialization 
	function initProductGallery() {
		if ( $('#touchcarousel').length ) {
			$("#touchcarousel").touchCarousel({
				pagingNav: true,
				scrollbar: false,
				directionNavAutoHide: false,
				itemsPerMove: 1,
				loopItems: true,
				directionNav: false,
				autoplay: false,
				useWebkit3d: true,
				transitionSpeed: 400,
				itemFallbackWidth:780
			});	
		}	
	}
	initProductGallery();
	
    // Video Player	initialization
    function initVideoPlayer() {
	    if ( $('#videoSelector').length ) {
			$("video").VideoJS();
			$(".videoControl").click(function(e){
				e.preventDefault();
				var href = $(this).attr('href');
				var playerID = $(this).attr('id');
				$('#player').load(href, function() {
					videoJS = VideoJS.setup('video' + playerID, {
						preload: true,
						autoplay: true,
					});
				});
			});
			$("#vidDirectory a.tab").click(function(e){
				e.preventDefault();
				var href = $(this).attr('href');
				if ($(this).hasClass('hidden')) {
					$('#vidDirectory a.tab.active').removeClass('active').addClass('hidden');
					$(this).addClass('active').removeClass('hidden');
					$('#videoListings .listing').hide();
					$('#videoListings .listing#'+ href).fadeIn();
				};
			});
		}
	}
	initVideoPlayer();
	
	// Product FAQ
	function initFAQSelector() {
    	if ( $('#support.slide .faq').length ) {
    		$('a.question').click(function(e){
    			e.preventDefault();
    			var theQuestion = $(this);
    			var theAnswer = $(this).siblings('div.answer');
    			
    			if ($('a.question.active').length) {
					if ( theQuestion.hasClass('active') ) {
						$('div.answer.active').slideUp('slow');
						$('a.question, div.answer').removeClass('active').removeClass('inactive');
						return;
					}
    			}
    			
    			$('a.question').addClass('inactive')
    			if ($('div.answer.active').length) {
    				$('div.answer.active').slideUp('fast', function(){
    					$('a.question.active, div.answer.active').removeClass('active').addClass('inactive') ;
    					theQuestion.addClass('active').removeClass('inactive');
    					theAnswer.slideDown().addClass('active').removeClass('inactive');
    				});
    			} else {
    				theQuestion.addClass('active').removeClass('inactive');
    				theAnswer.slideDown().addClass('active').removeClass('inactive');
    			};
    		});
    	}	
	}
	initFAQSelector();
	
	// Layout on the people page.
	$('.people_member a.who').click(function(e){
		e.preventDefault();

		var sqr = $(this).children('.square').last();
		var sqrpos = sqr.position();
		var sqrclone = sqr.clone().addClass('clone');
		var bio = $(this).parent().children('.bio');
		var spc = $('#people.slide .content')
		var spcwdth = $(spc).width();
		var spchght = $(spc).height();
		
		function animateCloseBio(bio, sqr, destination)
		{
			bio.animate({'top':destination.top, 'left':destination.left}, 'fast', function() {
				bio.hide()
				osqrpos = $('.original').position();
				sqr.animate( {'width':sqr.width() / 2, 'height':sqr.height() / 2, 'left':osqrpos.left, 'top':osqrpos.top}, function() {
					sqr.detach();
				});
				$('.square, .bio').removeClass('inactive active original');
			});
		};
		
		if (sqr.hasClass('active')) {
			animateCloseBio(bio, sqr, sqrpos);
			return;
		} else {
			
			if ( $('.square.active').length ) {
				animateCloseBio($('.bio.active'), $('.square.clone'), $('.square.clone').position());
				return;
			}
		
			$('.square, .bio').removeClass('active');
			sqr.addClass('active').addClass('original');
		}

		if ( $(bio).height() > spchght / 2 ) $(bio).css({'width':$(bio).width() + $(sqr).width()});
		if ( $(bio).height() < sqr.height() ) $(bio).css({'height':$(sqr).height()});

		sqrclone.addClass('active').css({'position':'absolute', 'top':sqrpos.top, 'left':sqrpos.left});
		bio.addClass('active');
		
		sqr.parent().append(sqrclone);	
		
		var sqrX, sqrY, bioX;
		if (sqrpos.top == 0) {
			sqrY = 0;
		} else {
			sqrY = sqrpos.top - sqr.height();
		}
		
		if (sqrpos.left == 0) {
			sqrX = 0;
			bioX = sqr.width() * 2;
		} else {
			sqrX = sqrpos.left - sqr.width();
			if (sqrpos.left > spcwdth / 2) {
				bioX = sqrX - sqr.width() * 2;
			} else {
				bioX = sqrX + sqr.width() * 2;
			}
		}
		sqrclone.animate({'width':sqr.width() * 2, 'height':sqr.height() * 2, 'top':sqrY, 'left':sqrX}, function() {
			bio.css({'top':sqrY, 'left':sqrX})
				.show()
				.animate({'left':bioX});
		});
	});

	// Front Page product family interactions

	var segs = window.location.pathname.split('/');
	var last_seg = segs[segs.length-1];
	$('#home.slide #top #background').addClass(last_seg);

	var activeFam = $('#familyHorizontal #icons li.active');
	var href = $(activeFam).children('a').attr('href');		
	var famHref = '/site/family_detail/' + href;

	$('.productFamily .content').load(famHref, function(){
		$('.productFamily .content #' + href).show(700);
	});


	$("#familyHorizontal #icons li a").click(function(e) {
		e.preventDefault();
		var familyObj = $(this).parent();

		if ( $(activeFam).attr('id') == $(familyObj).attr('id') ) return;

		var href = $(this).attr('href');
		var famHref = '/site/family_detail/' + href;
		var id = $(familyObj).attr('id');
			


		var backgnd = $('#home.slide #top #background').hide().removeClass().addClass(href).show();

		$('.productFamily .content').children().hide();

		if ( $('.productFamily .content #' + href).length ) {
			$('.productFamily .content #' + href).show(700);
		} else {
			
			$.get(famHref, function(data) {
				$('.productFamily .content').append(data);
			}).complete(function() { $('.productFamily .content #' + href).show(700); });
		}

		activeFam = familyObj;
	});

    // Update Slide area from Horizontal Navigation. 
    $("#horizontalNavigation li.navButtonContainer a").click(function(e){
    	e.preventDefault();
    	var elem = $(this).parent();
    	var href = $(this).attr('href');
   		var contentID = $(elem).attr('id');
   		var slidehref = "/" + segs[1] + "/" + segs[2] + "/slide/" + contentID;

    	$("#horizontalNavigation li a div.button").removeClass("active");
    	$("#horizontalNavigation #" + contentID + " a div").addClass("active");
    	
		$('#slide').height( $("#slide .slide.active").height() );
    	if ( $("#slide #" + contentID + ".slide .content").length ) {
    		// If the slide is already loaded just display it. 
			$("#slide .slide").hide().removeClass('active');
	    	displaySlide();
	    } else {
	    	// Otherwise we need to load it. 
	    	$("#slide .slide").fadeOut("fast").removeClass('active');
			$.get(slidehref, function(data) {
				$('#slide #' + contentID).append(data);
			}).complete(function() { 
				displaySlide();
				if (contentID == 'overview') initProductGallery();
				if (contentID == 'videos') initVideoPlayer();
				if (contentID == 'support') initFAQSelector();
			});
	    }
	    
	    function displaySlide() {
	    	$('#slide #' + contentID).fadeIn("slow", function() {
		    	var slideHeight = $("#slide .slide.active").height();
		    	$('#slide').animate({height:slideHeight});
	    	}).addClass('active'); 
	    }
	    
	    
		history.replaceState({"id": contentID}, "", href);
		if (contentID == "video") {
			$("video").VideoJS();
		}
    });
    

	// Search field interactions
	$('input.searchfield').each(function(){
		$(this).prev().addClass("placeholder");
		$(this).addClass("placeholder");
		
		if ($(this).val() != '') $(this).prev().hide();
	});
	$('input.searchfield').focusin(function(){
		/* $(this).prev().fadeOut(90); */
		if ($(this).val() == '') $(this).prev().fadeTo(85, .5);
	});		
	
	$('input.searchfield').focusout(function(){
		if ($(this).val() == '') $(this).prev().fadeTo(85, 1);	
	});		

	$('input.searchfield').keypress(function(){
		$(this).prev().hide();
	});		

	// Stuff images on the blog into lightboxes.
	$("#blog #entry img, #blog.entry img").each(function(i){
		var url = $(this).attr("src");
		var tag = "<a rel='lightbox' class='lightbox' href='" + url + "'>";
		var parentTag = $(this).parent().get(0).tagName;
		if (parentTag != "A") {
			$(this).wrap(tag);
		};
	});
   
    //Controls the carousel, but first finds if it exists
    if($("#carousel").length > 0)
    {
        $("#carousel").jCarouselLite({
            btnNext: "#next a",
            btnPrev: "#previous a",
            circular: true,
            visible: 4,
            scroll: 1,
            speed: 500
        });
    }
    
    //Pretty photo is the image lightbox for the website
    if($(".lightbox").length > 0)
    {
        $(".lightbox").prettyPhoto({
            animationSpeed: 'fast', /* fast/slow/normal */
			opacity: 0.75, /* Value betwee 0 and 1 */
			showTitle: false, /* true/false */
			allowresize: true, /* true/false */
			hideflash: false, /* Hides all the flash object on a page, set to TRUE if flash appears over prettyPhoto */
			modal: false, /* If set to true, only the close button will close the window */
			social_tools: false,
			overlay_gallery: false,
        });
    }

    $(".feature a.name").each(function(){
        $(this).click(function(e){
            e.preventDefault();
            var elem = $(this)
            $(this).parents("tr").next("tr").find(".featuredescription").slideToggle(function(){
                if($(elem).hasClass("up"))
                {
                    $(elem).removeClass("up");
                }
                else 
                {
                    $(elem).addClass("up");
                }
            });

        });
    });
    $("#blog .filter ul").hide();
    $("#blog .filter h2 a").click(function(e){
        e.preventDefault();
        var elem = $(this)
        $(this).parents("h2").next("ul").slideToggle(function(){
	        if($(elem).hasClass("active"))
	        {
	            $(elem).removeClass("active");
	        }
	        else 
	        {
	            $(elem).addClass("active");
	        }
        });
    });
     

    //Controls the slide downs, to add simply create a new anchor element in the template and
    //add the elements to this array
    var elems = [$("#beta_link"), $("#product_link"), $("#standard_link"), $("#pro_link"), $("#download_link") ];
    $(elems).each(function(e){
        $(this).click(function(e){
            scrollWin($(this).attr("href"), e);
            console.log(e);
        });
    });
    
    function scrollWin(destination, event){
        event.preventDefault();
        $('html, body').animate({
            scrollTop: $(destination).parents("div").offset().top
        }, 1000);
    }
});

$(window).load(function() {
// Waits for all elements to finish loading, doesn't fire when coming from cache.

});


(function($){
// Small jquery plugin that will search for a string and wrap it in a span containing the specified class.
$.fn.spanwrap = function (str, className)
{
    var regex = new RegExp(str, "i");
    return this.each(function ()
    {
        this.innerHTML = this.innerHTML.replace(regex, "<span class=\"" + className + "\">" + str + "</span>");
    });
}; //end plugin
})( jQuery ); // confine scope

(function($){
// Handy Jquery plugin for css animations: https://gist.github.com/435054
var rupper = /([A-Z])/g; 

// ----------
// Function: stopCssAnimation
// Stops an animation in its tracks!
$.fn.stopCssAnimation = function(){   
  this.each(function(){
    // When you remove the CSS Transition properties
    // it doesn't just end the animation where it was,
    // instead it jumps the animation to the end state.
    // Thus, to stop an animation, you first have to get
    // its current computed values, remove the transition
    // properties, and then finally set the elements
    // values appropriatly.
    
    // Get the computed values of the animated properties
    var $el = $(this);
    var props = $el.data("cssAnimatedProps");
    var cStyle = window.getComputedStyle(this, null);
    var cssValues = {};     
    for(var prop in props){
      prop = prop.replace( rupper, "-$1" ).toLowerCase();
      cssValues[prop] = cStyle.getPropertyValue(prop);
    }
    
    // Remove the CSS Transition CSS
    $el.css({
      '-moz-transition-property': 'none',  
      '-moz-transition-duration': '',  
      '-moz-transition-timing-function': '',
      '-webkit-transition-property': 'none',  
      '-webkit-transition-duration': '',  
      '-webkit-transition-timing-function': ''    
    });
    
    // Set the saved computed properties
    for( var prop in cssValues ){
      $el.css(prop, cssValues[prop]);
    }
    
    // Cancel any onComplete function
    $el.data("cssAnimatedProps", null);
    var timeoutId = $el.data("cssTimeoutId");
    if( timeoutId != null ) {
      clearTimeout(timeoutId);
      $el.data("cssTimeoutId", null);
    }
  });
};

// ----------
// Function: animateWithCSS
// Uses CSS transitions to animate the element. 
// 
// Parameters: 
//   Takes the same properties as jQuery's animate function.
//
//   The only difference is that the easing paramater can now be:
//   bounce, swing, linear, ease-in, ease-out, cubic-bezier, or
//   manually defined as cubic-bezier(x1,y1,x2,y2);
$.fn.animateWithCss = function(props, speed, easing, callback) {
  var optall = jQuery.speed(speed, easing, callback);  
  
	if ( jQuery.isEmptyObject( props ) ) {
		return this.each( optall.complete );
	}
  
  var 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;
  
  // The latest versions of Firefox do not animate from a non-explicitly set
  // css properties. So for each element to be animated, go through and
  // explicitly define 'em.
  this.each(function(){
    $(this).data("cssAnimatedProps", props);
    var cStyle = window.getComputedStyle(this, null);      
    for(var prop in props){
      prop = prop.replace( rupper, "-$1" ).toLowerCase();
      $(this).css(prop, cStyle.getPropertyValue(prop));
    }    
  });
  
  this.css({
    '-moz-transition-property': 'all', // TODO: just animate the properties we're changing  
    '-moz-transition-duration': optall.duration + 'ms',  
    '-moz-transition-timing-function': optall.easing,
    '-webkit-transition-property': 'all', // TODO: just animate the properties we're changing  
    '-webkit-transition-duration': optall.duration + 'ms',  
    '-webkit-transition-timing-function': optall.easing,
  });
  
  this.css(props);

  var self = this;
  var timeoutId = setTimeout(function() {    
    self.css({
      '-moz-transition-property': 'none',  
      '-moz-transition-duration': '',  
      '-moz-transition-timing-function': '',
      '-webkit-transition-property': 'none',  
      '-webkit-transition-duration': '',  
      '-webkit-transition-timing-function': ''
    });
    
    self.data("cssAnimatedProps", null); 
    self.data("cssTimeoutId", null);        

    if(jQuery.isFunction(optall.complete))
      optall.complete.apply(self);
  }, optall.duration);
  this.data( "cssTimeoutId", timeoutId );
  return this;
}

})(jQuery);

// version 1.5.0
// http://welcome.totheinter.net/columnizer-jquery-plugin/
// created by: Adam Wulf @adamwulf, adam.wulf@gmail.com

(function($){

 $.fn.columnize = function(options) {


	var defaults = {
		// default width of columns
		width: 400,
		// optional # of columns instead of width
		columns : false,
		// true to build columns once regardless of window resize
		// false to rebuild when content box changes bounds
		buildOnce : false,
		// an object with options if the text should overflow
		// it's container if it can't fit within a specified height
		overflow : false,
		// this function is called after content is columnized
		doneFunc : function(){},
		// if the content should be columnized into a 
		// container node other than it's own node
		target : false,
		// re-columnizing when images reload might make things
		// run slow. so flip this to true if it's causing delays
		ignoreImageLoading : true,
		// should columns float left or right
		columnFloat : "left",
		// ensure the last column is never the tallest column
		lastNeverTallest : false,
		// (int) the minimum number of characters to jump when splitting
		// text nodes. smaller numbers will result in higher accuracy
		// column widths, but will take slightly longer
		accuracy : false
	};
	var options = $.extend(defaults, options);
	
	if(typeof(options.width) == "string"){
		options.width = parseInt(options.width);
		if(isNaN(options.width)){
			options.width = defaults.width;
		}
	}

    return this.each(function() {
	    var $inBox = options.target ? $(options.target) : $(this);
		var maxHeight = $(this).height();
		var $cache = $('<div></div>'); // this is where we'll put the real content
		var lastWidth = 0;
		var columnizing = false;
		
		var adjustment = 0;
		
		$cache.append($(this).contents().clone(true));
	    
	    // images loading after dom load
	    // can screw up the column heights,
	    // so recolumnize after images load
	    if(!options.ignoreImageLoading && !options.target){
	    	if(!$inBox.data("imageLoaded")){
		    	$inBox.data("imageLoaded", true);
		    	if($(this).find("img").length > 0){
		    		// only bother if there are
		    		// actually images...
			    	var func = function($inBox,$cache){ return function(){
				    	if(!$inBox.data("firstImageLoaded")){
				    		$inBox.data("firstImageLoaded", "true");
					    	$inBox.empty().append($cache.children().clone(true));
					    	$inBox.columnize(options);
				    	}
			    	}}($(this), $cache);
				    $(this).find("img").one("load", func);
				    $(this).find("img").one("abort", func);
				    return;
		    	}
	    	}
	    }
	    
		$inBox.empty();
		
		columnizeIt();
		
		if(!options.buildOnce){
			$(window).resize(function() {
				if(!options.buildOnce && $.browser.msie){
					if($inBox.data("timeout")){
						clearTimeout($inBox.data("timeout"));
					}
					$inBox.data("timeout", setTimeout(columnizeIt, 200));
				}else if(!options.buildOnce){
					columnizeIt();
				}else{
					// don't rebuild
				}
			});
		}
		
		/**
		 * return a node that has a height
		 * less than or equal to height
		 *
		 * @param putInHere, a dom element
		 * @$pullOutHere, a jQuery element
		 */
		function columnize($putInHere, $pullOutHere, $parentColumn, height){
			while($parentColumn.height() < height &&
				  $pullOutHere[0].childNodes.length){
				$putInHere.append($pullOutHere[0].childNodes[0]);
			}
			if($putInHere[0].childNodes.length == 0) return;
			
			// now we're too tall, undo the last one
			var kids = $putInHere[0].childNodes;
			var lastKid = kids[kids.length-1];
			$putInHere[0].removeChild(lastKid);
			var $item = $(lastKid);
			
			
			if($item[0].nodeType == 3){
				// it's a text node, split it up
				var oText = $item[0].nodeValue;
				var counter2 = options.width / 18;
				if(options.accuracy)
				counter2 = options.accuracy;
				var columnText;
				var latestTextNode = null;
				while($parentColumn.height() < height && oText.length){
					if (oText.indexOf(' ', counter2) != '-1') {
						columnText = oText.substring(0, oText.indexOf(' ', counter2));
					} else {
						columnText = oText;
					}
					latestTextNode = document.createTextNode(columnText);
					$putInHere.append(latestTextNode);
					
					if(oText.length > counter2){
						oText = oText.substring(oText.indexOf(' ', counter2));
					}else{
						oText = "";
					}
				}
				if($parentColumn.height() >= height && latestTextNode != null){
					// too tall :(
					$putInHere[0].removeChild(latestTextNode);
					oText = latestTextNode.nodeValue + oText;
				}
				if(oText.length){
					$item[0].nodeValue = oText;
				}else{
					return false; // we ate the whole text node, move on to the next node
				}
			}
			
			if($pullOutHere.children().length){
				$pullOutHere.prepend($item);
			}else{
				$pullOutHere.append($item);
			}
			
			return $item[0].nodeType == 3;
		}
		
		function split($putInHere, $pullOutHere, $parentColumn, height){
			if($pullOutHere.children().length){
				$cloneMe = $pullOutHere.children(":first");
				$clone = $cloneMe.clone(true);
				if($clone.prop("nodeType") == 1 && !$clone.hasClass("dontend")){ 
					$putInHere.append($clone);
					if($clone.is("img") && $parentColumn.height() < height + 20){
						$cloneMe.remove();
					}else if(!$cloneMe.hasClass("dontsplit") && $parentColumn.height() < height + 20){
						$cloneMe.remove();
					}else if($clone.is("img") || $cloneMe.hasClass("dontsplit")){
						$clone.remove();
					}else{
						$clone.empty();
						if(!columnize($clone, $cloneMe, $parentColumn, height)){
							if($cloneMe.children().length){
								split($clone, $cloneMe, $parentColumn, height);
							}
						}
						if($clone.get(0).childNodes.length == 0){
							// it was split, but nothing is in it :(
							$clone.remove();
						}
					}
				}
			}
		}
		
		
		function singleColumnizeIt() {
			if ($inBox.data("columnized") && $inBox.children().length == 1) {
				return;
			}
			$inBox.data("columnized", true);
			$inBox.data("columnizing", true);
			
			$inBox.empty();
			$inBox.append($("<div class='first last column' style='width:100%; float: " + options.columnFloat + ";'></div>")); //"
			$col = $inBox.children().eq($inBox.children().length-1);
			$destroyable = $cache.clone(true);
			if(options.overflow){
				targetHeight = options.overflow.height;
				columnize($col, $destroyable, $col, targetHeight);
				// make sure that the last item in the column isn't a "dontend"
				if(!$destroyable.contents().find(":first-child").hasClass("dontend")){
					split($col, $destroyable, $col, targetHeight);
				}
				
				while(checkDontEndColumn($col.children(":last").length && $col.children(":last").get(0))){
					var $lastKid = $col.children(":last");
					$lastKid.remove();
					$destroyable.prepend($lastKid);
				}

				var html = "";
				var div = document.createElement('DIV');
				while($destroyable[0].childNodes.length > 0){
					var kid = $destroyable[0].childNodes[0];
					for(var i=0;i<kid.attributes.length;i++){
						if(kid.attributes[i].nodeName.indexOf("jQuery") == 0){
							kid.removeAttribute(kid.attributes[i].nodeName);
						}
					}
					div.innerHTML = "";
					div.appendChild($destroyable[0].childNodes[0]);
					html += div.innerHTML;
				}
				var overflow = $(options.overflow.id)[0];
				overflow.innerHTML = html;

			}else{
				$col.append($destroyable);
			}
			$inBox.data("columnizing", false);
			
			if(options.overflow){
				options.overflow.doneFunc();
			}
			
		}
		
		function checkDontEndColumn(dom){
			if(dom.nodeType != 1) return false;
			if($(dom).hasClass("dontend")) return true;
			if(dom.childNodes.length == 0) return false;
			return checkDontEndColumn(dom.childNodes[dom.childNodes.length-1]);
		}
		
		function columnizeIt() {
			if(lastWidth == $inBox.width()) return;
			lastWidth = $inBox.width();
			
			var numCols = Math.round($inBox.width() / options.width);
			if(options.columns) numCols = options.columns;
//			if ($inBox.data("columnized") && numCols == $inBox.children().length) {
//				return;
//			}
			if(numCols <= 1){
				return singleColumnizeIt();
			}
			if($inBox.data("columnizing")) return;
			$inBox.data("columnized", true);
			$inBox.data("columnizing", true);
			
			$inBox.empty();
			$inBox.append($("<div style='width:" + (Math.floor(100 / numCols))+ "%; float: " + options.columnFloat + ";'></div>")); //"
			$col = $inBox.children(":last");
			$col.append($cache.clone());
			maxHeight = $col.height();
			$inBox.empty();
			
			var targetHeight = maxHeight / numCols;
			var firstTime = true;
			var maxLoops = 3;
			var scrollHorizontally = false;
			if(options.overflow){
				maxLoops = 1;
				targetHeight = options.overflow.height;
			}else if(options.height && options.width){
				maxLoops = 1;
				targetHeight = options.height;
				scrollHorizontally = true;
			}
			
			for(var loopCount=0;loopCount<maxLoops;loopCount++){
				$inBox.empty();
				var $destroyable;
				try{
					$destroyable = $cache.clone(true);
				}catch(e){
					// jquery in ie6 can't clone with true
					$destroyable = $cache.clone();
				}
				$destroyable.css("visibility", "hidden");
				// create the columns
				for (var i = 0; i < numCols; i++) {
					/* create column */
					var className = (i == 0) ? "first column" : "column";
					var className = (i == numCols - 1) ? ("last " + className) : className;
					$inBox.append($("<div class='" + className + "' style='width:" + (Math.floor(100 / numCols))+ "%; float: " + options.columnFloat + ";'></div>")); //"
				}
				
				// fill all but the last column (unless overflowing)
				var i = 0;
				while(i < numCols - (options.overflow ? 0 : 1) || scrollHorizontally && $destroyable.contents().length){
					if($inBox.children().length <= i){
						// we ran out of columns, make another
						$inBox.append($("<div class='" + className + "' style='width:" + (Math.floor(100 / numCols))+ "%; float: " + options.columnFloat + ";'></div>")); //"
					}
					var $col = $inBox.children().eq(i);
					columnize($col, $destroyable, $col, targetHeight);
					// make sure that the last item in the column isn't a "dontend"
					if(!$destroyable.contents().find(":first-child").hasClass("dontend")){
						split($col, $destroyable, $col, targetHeight);
					}else{
//						alert("not splitting a dontend");
					}
					
					while(checkDontEndColumn($col.children(":last").length && $col.children(":last").get(0))){
						var $lastKid = $col.children(":last");
						$lastKid.remove();
						$destroyable.prepend($lastKid);
					}
					i++;
				}
				if(options.overflow && !scrollHorizontally){
					var IE6 = false /*@cc_on || @_jscript_version < 5.7 @*/;
					var IE7 = (document.all) && (navigator.appVersion.indexOf("MSIE 7.") != -1);
					if(IE6 || IE7){
						var html = "";
						var div = document.createElement('DIV');
						while($destroyable[0].childNodes.length > 0){
							var kid = $destroyable[0].childNodes[0];
							for(var i=0;i<kid.attributes.length;i++){
								if(kid.attributes[i].nodeName.indexOf("jQuery") == 0){
									kid.removeAttribute(kid.attributes[i].nodeName);
								}
							}
							div.innerHTML = "";
							div.appendChild($destroyable[0].childNodes[0]);
							html += div.innerHTML;
						}
						var overflow = $(options.overflow.id)[0];
						overflow.innerHTML = html;
					}else{
						$(options.overflow.id).empty().append($destroyable.contents().clone(true));
					}
				}else if(!scrollHorizontally){
					// the last column in the series
					$col = $inBox.children().eq($inBox.children().length-1);
					while($destroyable.contents().length) $col.append($destroyable.contents(":first"));
					var afterH = $col.height();
					var diff = afterH - targetHeight;
					var totalH = 0;
					var min = 10000000;
					var max = 0;
					var lastIsMax = false;
					$inBox.children().each(function($inBox){ return function($item){
						var h = $inBox.children().eq($item).height();
						lastIsMax = false;
						totalH += h;
						if(h > max) {
							max = h;
							lastIsMax = true;
						}
						if(h < min) min = h;
					}}($inBox));

					var avgH = totalH / numCols;
					if(options.lastNeverTallest && lastIsMax){
						// the last column is the tallest
						// so allow columns to be taller
						// and retry
						targetHeight = targetHeight + 30;
						if(loopCount == maxLoops-1) maxLoops++;
					}else if(max - min > 30){
						// too much variation, try again
						targetHeight = avgH + 30;
					}else if(Math.abs(avgH-targetHeight) > 20){
						// too much variation, try again
						targetHeight = avgH;
					}else {
						// solid, we're done
						loopCount = maxLoops;
					}
				}else{
					// it's scrolling horizontally, fix the width/classes of the columns
					$inBox.children().each(function(i){
						$col = $inBox.children().eq(i);
						$col.width(options.width + "px");
						if(i==0){
							$col.addClass("first");
						}else if(i==$inBox.children().length-1){
							$col.addClass("last");
						}else{
							$col.removeClass("first");
							$col.removeClass("last");
						}
					});
					$inBox.width($inBox.children().length * options.width + "px");
				}
				$inBox.append($("<br style='clear:both;'>"));
			}
			$inBox.find('.column').find(':first.removeiffirst').remove();
			$inBox.find('.column').find(':last.removeiflast').remove();
			$inBox.data("columnizing", false);

			if(options.overflow){
				options.overflow.doneFunc();
			}
			options.doneFunc();
		}
    });
 };
})(jQuery);

/*****************************************
 * Flickr API (in jQuery)
 * version: 1.0 (02/23/2009)
 * written for jQuery 1.3.2
 * by Ryan Heath (http://rpheath.com)
 *****************************************/
(function($) {
  // core extensions
  $.extend({
    // determines if an object is empty
    // $.isEmpty({})             // => true
    // $.isEmpty({user: 'rph'})  // => false
    isEmpty: function(obj) {
      for (var i in obj) { return false }
      return true
    }
  })
  
  // base flickr object
  $.flickr = {
    // the actual request url
    // (constructs extra params as they come in)
    url: function(method, params) {
      return 'http://api.flickr.com/services/rest/?method=' + method + '&format=json' +
        '&api_key=' + $.flickr.settings.api_key + ($.isEmpty(params) ? '' : '&' + $.param(params)) + '&jsoncallback=?'
    },
    // translate plugin image sizes to flickr sizes
    translate: function(size) {
      switch(size) {
        case 'sq': return '_s' // square
        case 't' : return '_t' // thumbnail
        case 's' : return '_m' // small
        case 'm' : return ''   // medium
        default  : return ''   // medium
      }
    },
    // determines what to do with the links
    linkTag: function(text, photo, href) {
      if (href === undefined) href = ['http://www.flickr.com/photos', photo.owner, photo.id].join('/')      
      return '<a href="' + href + '" title="' + photo.title + '">' + text + '</a>'
    }
  }
  
  // helper methods for thumbnails
  $.flickr.thumbnail = {
    src: function(photo, size) {
      if (size === undefined) size = $.flickr.translate($.flickr.settings.thumbnail_size)
      return 'http://farm' + photo.farm + '.static.flickr.com/' + photo.server + 
        '/' + photo.id + '_' + photo.secret + size + '.jpg'
    },
    imageTag: function(image) {
      return '<img src="' + image.src + '" alt="' + image.alt + '" />'
    }
  }
  
  // accepts a series of photos and constructs
  // the thumbnails that link back to Flickr
  $.flickr.thumbnail.process = function(photos) {
    var thumbnails = $.map(photos.photo, function(photo) {
      var image = new Image(), html = '', href = undefined

      image.src = $.flickr.thumbnail.src(photo)
      image.alt = photo.title

      var size = $.flickr.settings.link_to_size
      if (size != undefined && size.match(/sq|t|s|m|o/)) 
        href = $.flickr.thumbnail.src(photo, $.flickr.translate(size))
      
      html = $.flickr.linkTag($.flickr.thumbnail.imageTag(image), photo, href)
        
      return [html]
    }).join("\n")
    
    return $('<div class="flickr"></div>').append(thumbnails)
  }
  
  // handles requesting and thumbnailing photos
  $.flickr.photos = function(method, options) {
    var options = $.extend($.flickr.settings, options || {}),
        elements = $.flickr.self, photos
    
    return elements.each(function() {
      $.getJSON($.flickr.url(method, options), function(data) {
        photos = (data.photos === undefined ? data.photoset : data.photos)
        elements.append($.flickr.thumbnail.process(photos))
      })
    })
  }
  
  // namespace to hold available API methods
  // note: options available to each method match that of Flickr's docs
  $.flickr.methods = {
    // http://www.flickr.com/services/api/flickr.photos.getRecent.html
    photosGetRecent: function(options) {
      $.flickr.photos('flickr.photos.getRecent', options)
    },
    // http://www.flickr.com/services/api/flickr.photos.getContactsPublicPhotos.html
    photosGetContactsPublicPhotos: function(options) {
      $.flickr.photos('flickr.photos.getContactsPublicPhotos', options)
    },
    // http://www.flickr.com/services/api/flickr.photos.search.html
    photosSearch: function(options) {
      $.flickr.photos('flickr.photos.search', options)
    },
    // http://www.flickr.com/services/api/flickr.photosets.getPhotos.html
    photosetsGetPhotos: function(options) {
      $.flickr.photos('flickr.photosets.getPhotos', options)
    }
  }
  
  // the plugin
  $.fn.flickr = function(options) {
    $.flickr.self = $(this)
    
    // base configuration
    $.flickr.settings = $.extend({
      api_key: '37e576f92830de7d70ab4141ed243daf',
      thumbnail_size: 'm'
    }, options || {})
    
    return $.flickr.methods
  }
})(jQuery);


// Misc helper functions

function currentApp()
{
	var urlsegs = window.location.pathname.split('/');
	return urlsegs[2]
};



