/* Author: Rob Edwards */

jQuery(document).ready(function($){

// Masonry

/*************************************************
**	jQuery Masonry version 1.3.2
**	Copyright David DeSandro, licensed MIT
**	http://desandro.com/resources/jquery-masonry
**************************************************/

;(function($){	

  /*!
   * smartresize: debounced resize event for jQuery
   * http://github.com/lrbabe/jquery-smartresize
   *
   * Copyright (c) 2009 Louis-Remi Babe
   * Licensed under the GPL license.
   * http://docs.jquery.com/License
   *
   */
  var event = $.event,
	  resizeTimeout;

  event.special.smartresize = {
	setup: function() {
	  $(this).bind( "resize", event.special.smartresize.handler );
	},
	teardown: function() {
	  $(this).unbind( "resize", event.special.smartresize.handler );
	},
	handler: function( event, execAsap ) {
	  // Save the context
	  var context = this,
		  args = arguments;

	  // set correct event type
	  event.type = "smartresize";

	  if (resizeTimeout) { clearTimeout(resizeTimeout); }
	  resizeTimeout = setTimeout(function() {
		jQuery.event.handle.apply( context, args );
	  }, execAsap === "execAsap"? 0 : 100);
	}
  };

  $.fn.smartresize = function( fn ) {
	return fn ? this.bind( "smartresize", fn ) : this.trigger( "smartresize", ["execAsap"] );
  };

  // masonry code begin
  $.fn.masonry = function(options, callback) { 

	// all my sweet methods
	var msnry = {
	  getBricks : function($wall, props, opts) {
		var hasItemSelector = (opts.itemSelector === undefined);
		if ( opts.appendedContent === undefined ) {
		  // if not appendedContent
		  props.$bricks = hasItemSelector ?
				$wall.children() :
				$wall.find(opts.itemSelector);
		} else {
		 //	 if appendedContent...
		 props.$bricks = hasItemSelector ?
				opts.appendedContent : 
				opts.appendedContent.filter( opts.itemSelector );
		}
	  },
	  
	  placeBrick : function($brick, setCount, setY, props, opts) {
			// get the minimum Y value from the columns...
		var minimumY = Math.min.apply(Math, setY),
			setHeight = minimumY + $brick.outerHeight(true),
			i = setY.length,
			shortCol = i,
			setSpan = props.colCount + 1 - i;
		// Which column has the minY value, closest to the left
		while (i--) {
		  if ( setY[i] == minimumY ) {
			shortCol = i;
		  }
		}
			
		var position = {
		  left: props.colW * shortCol + props.posLeft,
		  top: minimumY
		};
			
		// position the brick
		$brick.applyStyle(position, $.extend(true,{},opts.animationOptions) );

		// apply setHeight to necessary columns
		for ( i=0; i < setSpan; i++ ) {
		  props.colY[ shortCol + i ] = setHeight;
		}
	  },
	  
	  setup : function($wall, opts, props) {
		msnry.getBricks($wall, props, opts);

		if ( props.masoned ) {
		  props.previousData = $wall.data('masonry');
		}

		if ( opts.columnWidth === undefined) {
		  props.colW = props.masoned ?
			  props.previousData.colW :
			  props.$bricks.outerWidth(true);
		} else {
		  props.colW = opts.columnWidth;
		}

		props.colCount = Math.floor( $wall.width() / props.colW ) ;
		props.colCount = Math.max( props.colCount, 1 );
	  },
	  
	  arrange : function($wall, opts, props) {
		var i;

		if ( !props.masoned || opts.appendedContent !== undefined ) {
		  // just the new bricks
		  props.$bricks.css( 'position', 'absolute' );
		}

		// if masonry hasn't been called before
		if ( !props.masoned ) { 
		  $wall.css( 'position', 'relative' );

		  // get top left position of where the bricks should be
		  var $cursor = $( document.createElement('div') );
		  $wall.prepend( $cursor );
		  props.posTop =  Math.round( $cursor.position().top );
		  props.posLeft = Math.round( $cursor.position().left );
		  $cursor.remove();
		} else {
		  props.posTop =  props.previousData.posTop;
		  props.posLeft = props.previousData.posLeft;
		}
		
		// set up column Y array
		if ( props.masoned && opts.appendedContent !== undefined ) {
		  // if appendedContent is set, use colY from last call
		  props.colY = props.previousData.colY;

		  /*
		  *	 in the case that the wall is not resizeable,
		  *	 but the colCount has changed from the previous time
		  *	 masonry has been called
		  */
		  for ( i = props.previousData.colCount; i < props.colCount; i++) {
			props.colY[i] = props.posTop;
		  }

		} else {
		  // start new colY array, with starting values set to posTop
		  props.colY = [];
		  i = props.colCount;
		  while (i--) {
			props.colY.push(props.posTop);
		  }
		}

		// are we animating the rearrangement?
		// use plugin-ish syntax for css or animate
		$.fn.applyStyle = ( props.masoned && opts.animate ) ? $.fn.animate : $.fn.css;


		// layout logic
		if ( opts.singleMode ) {
		  props.$bricks.each(function(){
			var $brick = $(this);
			msnry.placeBrick($brick, props.colCount, props.colY, props, opts);
		  });	   
		} else {
		  props.$bricks.each(function() {
			var $brick = $(this),
				//how many columns does this brick span
				colSpan = Math.ceil( $brick.outerWidth(true) / props.colW);
			colSpan = Math.min( colSpan, props.colCount );

			if ( colSpan === 1 ) {
			  // if brick spans only one column, just like singleMode
			  msnry.placeBrick($brick, props.colCount, props.colY, props, opts);
			} else {
			  // brick spans more than one column

			  //how many different places could this brick fit horizontally
			  var groupCount = props.colCount + 1 - colSpan,
				  groupY = [];

			  // for each group potential horizontal position
			  for ( i=0; i < groupCount; i++ ) {
				// make an array of colY values for that one group
				var groupColY = props.colY.slice(i, i+colSpan);
				// and get the max value of the array
				groupY[i] = Math.max.apply(Math, groupColY);
			  }

			  msnry.placeBrick($brick, groupCount, groupY, props, opts);
			}
		  }); //	/props.bricks.each(function() {
		}  //	  /layout logic

		// set the height of the wall to the tallest column
		props.wallH = Math.max.apply(Math, props.colY);
		var wallCSS = { height: props.wallH - props.posTop };
		$wall.applyStyle( wallCSS, $.extend(true,[],opts.animationOptions) );

		// add masoned class first time around
		if ( !props.masoned ) { 
		  // wait 1 millisec for quell transitions
		  setTimeout(function(){
			$wall.addClass('masoned'); 
		  }, 1);
		}

		// provide props.bricks as context for the callback
		callback.call( props.$bricks );

		// set all data so we can retrieve it for appended appendedContent
		//	  or anyone else's crazy jquery fun
		$wall.data('masonry', props );
		
	  }, // /msnry.arrange
	  
	  resize : function($wall, opts, props) {
		props.masoned = !!$wall.data('masonry');
		var prevColCount = $wall.data('masonry').colCount;
		msnry.setup($wall, opts, props);
		if ( props.colCount != prevColCount ) {
		  msnry.arrange($wall, opts, props);
		}
	  }
	};


	/*
	*  let's begin
	*  IN A WORLD...
	*/
	return this.each(function() {  

	  var $wall = $(this),
		  props = {};

	  // checks if masonry has been called before on this object
	  props.masoned = !!$wall.data('masonry');
	
	  var previousOptions = props.masoned ? $wall.data('masonry').options : {},
		  opts =  $.extend(
					{},
					$.fn.masonry.defaults,
					previousOptions,
					options
				  ),
		  resizeOn = previousOptions.resizeable;

	  // should we save these options for next time?
	  props.options = opts.saveOptions ? opts : previousOptions;

	  //picked up from Paul Irish
	  callback = callback || function(){};

	  msnry.getBricks($wall, props, opts);

	  // if brickParent is empty, do nothing, go back home and eat chips
	  if ( !props.$bricks.length ) { 
		return this; 
	  }

	  // call masonry layout
	  msnry.setup($wall, opts, props);
	  msnry.arrange($wall, opts, props);
	
	  // binding window resizing
	  if ( !resizeOn && opts.resizeable ) {
		$(window).bind('smartresize.masonry', function() { msnry.resize($wall, opts, props); } );
	  }
	  if ( resizeOn && !opts.resizeable ) { 
		$(window).unbind('smartresize.masonry'); 
	  }
	   

	});	   //	 /return this.each(function()
  };	  //	/$.fn.masonry = function(options)


  // Default plugin options
  $.fn.masonry.defaults = {
	singleMode: false,
	columnWidth: undefined,
	itemSelector: undefined,
	appendedContent: undefined,
	saveOptions: true,
	resizeable: true,
	animate: false,
	animationOptions: {}
  };

})(jQuery);


/*
 * Viewport - jQuery selectors for finding elements in viewport
 *
 * Copyright (c) 2008-2009 Mika Tuupola
 *
 * Licensed under the MIT license:
 *	 http://www.opensource.org/licenses/mit-license.php
 *
 * Project home:
 *	http://www.appelsiini.net/projects/viewport
 *
 */

/*
 * Viewport - jQuery selectors for finding elements in viewport
 *
 * Copyright (c) 2008-2009 Mika Tuupola
 *
 * Licensed under the MIT license:
 *   http://www.opensource.org/licenses/mit-license.php
 *
 * Project home:
 *  http://www.appelsiini.net/projects/viewport
 *
 */
(function($) {

    $.belowthefold = function(element, settings) {
        var fold = $(window).height() + $(window).scrollTop();
        return fold <= $(element).offset().top - settings.threshold;
    };

    $.abovethetop = function(element, settings) {
        var top = $(window).scrollTop();
        return top >= $(element).offset().top + $(element).height() - settings.threshold;
    };

    $.rightofscreen = function(element, settings) {
        var fold = $(window).width() + $(window).scrollLeft();
        return fold <= $(element).offset().left - settings.threshold;
    };

    $.leftofscreen = function(element, settings) {
        var left = $(window).scrollLeft();
        return left >= $(element).offset().left + $(element).width() - settings.threshold;
    };

    $.inviewport = function(element, settings) {
        return !$.rightofscreen(element, settings) && !$.leftofscreen(element, settings) && !$.belowthefold(element, settings) && !$.abovethetop(element, settings);
    };

    $.extend($.expr[':'], {
        "below-the-fold": function(a, i, m) {
            return $.belowthefold(a, {threshold : 0});
        },
        "above-the-top": function(a, i, m) {
            return $.abovethetop(a, {threshold : 0});
        },
        "left-of-screen": function(a, i, m) {
            return $.leftofscreen(a, {threshold : 0});
        },
        "right-of-screen": function(a, i, m) {
            return $.rightofscreen(a, {threshold : 0});
        },
        "in-viewport": function(a, i, m) {
            return $.inviewport(a, {threshold : 0});
        }
    });


})(jQuery);

/**
 * jQuery.ScrollTo - Easy element scrolling using jQuery.
 * Copyright (c) 2007-2009 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com
 * Dual licensed under MIT and GPL.
 * Date: 5/25/2009
 * @author Ariel Flesler
 * @version 1.4.2
 *
 * http://flesler.blogspot.com/2007/10/jqueryscrollto.html
 */
; (function(d) {
    var k = d.scrollTo = function(a, i, e) {
        d(window).scrollTo(a, i, e)
    };
    k.defaults = {
        axis: 'xy',
        duration: parseFloat(d.fn.jquery) >= 1.3 ? 0: 1
    };
    k.window = function(a) {
        return d(window)._scrollable()
    };
    d.fn._scrollable = function() {
        return this.map(function() {
            var a = this,
            i = !a.nodeName || d.inArray(a.nodeName.toLowerCase(), ['iframe', '#document', 'html', 'body']) != -1;
            if (!i) return a;
            var e = (a.contentWindow || a).document || a.ownerDocument || a;
            return d.browser.safari || e.compatMode == 'BackCompat' ? e.body: e.documentElement
        })
    };
    d.fn.scrollTo = function(n, j, b) {
        if (typeof j == 'object') {
            b = j;
            j = 0
        }
        if (typeof b == 'function') b = {
            onAfter: b
        };
        if (n == 'max') n = 9e9;
        b = d.extend({},
        k.defaults, b);
        j = j || b.speed || b.duration;
        b.queue = b.queue && b.axis.length > 1;
        if (b.queue) j /= 2;
        b.offset = p(b.offset);
        b.over = p(b.over);
        return this._scrollable().each(function() {
            var q = this,
            r = d(q),
            f = n,
            s,
            g = {},
            u = r.is('html,body');
            switch (typeof f) {
            case 'number':
            case 'string':
                if (/^([+-]=)?\d+(\.\d+)?(px|%)?$/.test(f)) {
                    f = p(f);
                    break
                }
                f = d(f, this);
            case 'object':
                if (f.is || f.style) s = (f = d(f)).offset()
            }
            d.each(b.axis.split(''),
            function(a, i) {
                var e = i == 'x' ? 'Left': 'Top',
                h = e.toLowerCase(),
                c = 'scroll' + e,
                l = q[c],
                m = k.max(q, i);
                if (s) {
                    g[c] = s[h] + (u ? 0: l - r.offset()[h]);
                    if (b.margin) {
                        g[c] -= parseInt(f.css('margin' + e)) || 0;
                        g[c] -= parseInt(f.css('border' + e + 'Width')) || 0
                    }
                    g[c] += b.offset[h] || 0;
                    if (b.over[h]) g[c] += f[i == 'x' ? 'width': 'height']() * b.over[h]
                } else {
                    var o = f[h];
                    g[c] = o.slice && o.slice( - 1) == '%' ? parseFloat(o) / 100 * m: o
                }
                if (/^\d+$/.test(g[c])) g[c] = g[c] <= 0 ? 0: Math.min(g[c], m);
                if (!a && b.queue) {
                    if (l != g[c]) t(b.onAfterFirst);
                    delete g[c]
                }
            });
            t(b.onAfter);
            function t(a) {
                r.animate(g, j, b.easing, a &&
                function() {
                    a.call(this, n, b)
                })
            }
        }).end()
    };
    k.max = function(a, i) {
        var e = i == 'x' ? 'Width': 'Height',
        h = 'scroll' + e;
        if (!d(a).is('html,body')) return a[h] - d(a)[e.toLowerCase()]();
        var c = 'client' + e,
        l = a.ownerDocument.documentElement,
        m = a.ownerDocument.body;
        return Math.max(l[h], m[h]) - Math.min(l[c], m[c])
    };
    function p(a) {
        return typeof a == 'object' ? a: {
            top: a,
            left: a
        }
    }
})(jQuery);

// Masonry Options
var
	speed = 500,	 // animation speed
	$wall = $('.portfolio_gallery').find('ul')
	$wall.masonry({
		columnWidth:311, 
		itemSelector: 'li:not(.invis)',
		animate: true,
		animationOptions: {
		duration: 1000,
		queue: false }
	});
	
	// Change background of nav when manual scrolled
	$(window).scroll(function () {
		var inview = '#' + $('#content > section > .section-wrap > .main:in-viewport:first').parent().parent().attr('id'),
			$link = $('#primary_nav a').filter('[hash=' + inview + ']');
			$linkhome = $('#primary_nav .home a').filter('[hash=' + inview + ']');
			$linkportfolio = $('#primary_nav .portfolio a').filter('[hash=' + inview + ']');
			$linkprofile = $('#primary_nav a.profile').filter('[hash=' + inview + ']');
			
		if ($link.length && !$link.is('.active')) {
			$('#primary_nav a.active').removeClass('active');
			$('#primary_nav a.goto').not(".active, .animating").css('backgroundPosition', '0px 0px');
			$link.addClass('active');
			$linkhome.css('backgroundPosition', '0px -164px');
			$linkportfolio.css('backgroundPosition', '0px -56px');
			$linkprofile.css('backgroundPosition', '0px -52px');
			$('#primary_nav li a').each(function(){
				$(this).removeClass('animating');
			});
	  }
	});

	// Scroll to anchor, on hrefs with .goto on them
	$('a.goto[href*=#], a.blog').click(function() {
		// Add active & Background position animation
		$('#primary_nav li a.goto').each(function(){
			$(this).removeClass('active');
			$(this).stop().animate({backgroundPosition: '0px 0px'}, 400, function(){
				$(this).removeClass( 'animating' );
			})
			.addClass('animating');
		});
		$('.folio-item').remove();
		
		$(this).addClass('active');
		// Use element height, and double, then minus 2px
		height = $(this).height() * (-1) -2;  
		$(this).stop().animate({'backgroundPosition':'(0 ' + height + ')'}, {duration:400});

		if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'')
		&& location.hostname == this.hostname) {
			var $target = $(this.hash);
			$target = $target.length && $target
			|| $('[name=' + this.hash.slice(1) +']');
			if ($target.length) {
			var targetOffset = $target.offset().top - 0;
			$('html,body')
			.stop().animate({scrollTop: targetOffset}, 2300);
		   return false;
		  }
		}
	});

	// Slow it down for portfolio gallery so scrollbar doesn't go whacky
	$('a.folio-goto[href*=#]').click(function() {
		if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'')
		&& location.hostname == this.hostname) {
			var $target = $(this.hash);
			$target = $target.length && $target
			|| $('[name=' + this.hash.slice(1) +']');
			if ($target.length) {
			var targetOffset = $target.offset().top - 0;
			$('html,body')
			.stop().animate({scrollTop: targetOffset}, 500);
		   return false;
		  }
		}
	});

// Misc 

$("#home .gallery ul li:nth-child(3n)").addClass('last');

$('.filtering-nav a').click(function(){
	var colorClass = '.' + $(this).attr('title');
	$('.filtering-nav a.active').removeClass('active');
	$(this).addClass('active');

	if(colorClass=='.all') {
	// show all hidden boxes
	$wall.children('.invis')
	  .toggleClass('invis').fadeIn(speed);
  } else {	
	// hide visible boxes 
	$wall.children().not(colorClass).not('.invis')
	  .toggleClass('invis').fadeOut(speed);
	// show hidden boxes
	$wall.children(colorClass+'.invis')
	  .toggleClass('invis').fadeIn(speed);
  }
  $wall.masonry();
  return false;
});
$('.filtering-nav a').click(function(){
	$('.folio-item').slideUp("slow");
});

// Portfolio Image Hover Switch ( appends -roll )
$(function() {
	$(".portfolio_gallery ul li a:not(.active)").hover(function() { 
		var src = $(this).children("img").attr("src").match(/[^\.]+/) + "-roll.jpg";
		$(this).children("img").attr("src", src);
	},
	function() {
		var src = $(this).children("img").attr("src").replace("-roll", "");
		$(this).children("img").attr("src", src);
	});
});

// $(function() {
// 	$("#profile .portrait").hover(function() { 
// 		var src = $(this).children("img").attr("src").match(/[^\.]+/) + "-roll.png";
// 		$(this).children("img").attr("src", src);
// 	},
// 	function() {
// 		var src = $(this).children("img").attr("src").replace("-roll", "");
// 		$(this).children("img").attr("src", src);
// 	});
// });

$('.portfolio_gallery ul li a, .latest-work ul li a').click(function(e) {
	$(this).addClass('active');
	
	// Stop previous slideshow so pager doesn't go mental
	$('.proj-slideshow').cycle('stop');
	// 
	e.preventDefault();
	var loadURL = "portfolio/index.html";
	var folioItem = $(this).attr('title');
	$("#project_content").load(loadURL + ' #'+folioItem, function(){
		$.ajax({
			url: 'js/jquery.cycle.all.js',
			dataType: 'script',
			success: function() {
				$('.proj-slideshow').cycle({
					fx: 'fade',
						timeout: '4000',
						speedIn: 1500,
						speedOut: 2000,
						next: '.proj-slideshow',
						pager: '.pager',
						pause: 1
					});
				$('.proj-slideshow a').click(function(e){
					e.preventDefault();
				});
		 	}
		});
	});
});

});

