// shim layer with setTimeout fallback
window.requestAnimationFrame = (function(){
  return  window.requestAnimationFrame       || 
          window.webkitRequestAnimationFrame || 
          window.mozRequestAnimationFrame    || 
          window.oRequestAnimationFrame      || 
          window.msRequestAnimationFrame     || 
          function(/* function */ callback, /* DOMElement */ element){
            window.setTimeout(callback, 1000 / 60);
          };
})();

function roundNumber(num, dec) {
	var result = Math.round(num*Math.pow(10,dec))/Math.pow(10,dec);
	return result;
}

(function($) {
	
	// Global API references and cached selectors.
	var scrollPaneApi,
		mainNav = $('#joe > nav > ul'),
		mainNavLi = mainNav.find('li'),
		swiss = $('#swiss'),
		pageHolder = $('#page-holder'),
		flush = $('.flush'),
		portfolio = $('#portfolio');
		
	function innit_tho() {
		
		if(Modernizr.canvas) {
		swiss.swissLines(); // Canvas-based background.
		}
		
		pageControl(); // AJAX pages using HTML5 History.

		portfolio.find('li a').live('pseudo', function() {
			$(this).pseudoPseudo();
		})//.trigger('pseudo');
		
		// Keep listening...
		pageHolder.delegate('#portfolio', 'portfolio', function(e, myName, myValue) {
			$(this).portfolio();
		});
		// portfolio.trigger('portfolio');
			
		// Ooo, flashy!		
		mainNav.animateMenu();
		flush.delay(800).flushIn(); 
		
		// Validate the forms.
		$('.validation-form').validate();
	
	}

	/** Flush in!  **/
	
	$.fn.flushIn = function() {
		
		return this.each(function() {
			var self = $(this);
			var currentBottom = parseInt(self.css('bottom'));
			self.css({bottom: (self.find('> *').eq(0).outerHeight() + currentBottom) *-1})
			.animate({bottom: currentBottom, opacity: 1}, {duration: 1000, easing: 'easeOutQuad'});
		});
			
	};
	
	/** Animate menu **/
	
	$.fn.animateMenu = function() {
		
		return this.each(function() {
			var self = $(this);
			self.height(self.height());
			var liHeight = self.find('li').eq(0).outerHeight(); 
			self.find('li').each(function(i) {
				$(this).css({position: 'relative', top: (liHeight*(i+1)) * -1});
				$(this).delay(200*i).animate({top: 0, opacity: 1}, {duration: 500, easing: 'easeOutQuad'});
			});
		});
		
	};
	
	$(window).resize(function() {
		if(scrollPaneApi) {
			scrollPaneApi.reinitialise();
		}
	});
	
	
	/** Page control **/
	
	function pageControl() {
		
		var anchors = mainNav.find('a').not('[rel="external"]'),
			firstCurrentIndex = 0,
			cachedContent = null;
		
		anchors.each(function() {
			if($(this).parent('li').hasClass('current')) {
				firstCurrentIndex = $(this).parent('li').index();
				cachedContent = pageHolder.html();
				return false;
			}
		});
		
		anchors.click(function(e) {
		
			e.preventDefault();
			var self = $(this);
							
			var hiddenLeft = ($('.outer', pageHolder).outerWidth() + parseInt(pageHolder.css('marginLeft'))) * -1;
			
			$('.outer', pageHolder).animate({
				left: hiddenLeft,
				opacity: 0
			}, {
				duration: 300,
				easing: 'easeInOutCubic',
				complete: function() {
				
					function loadPage() {
						
						portfolio = $('#portfolio'); // Update selector cache
						
						if(portfolio.length) {
							portfolio.trigger('portfolio');
							portfolio.find('li a').trigger('pseudo');
						}	
						
						if(typeof History.pushState != 'undefined') {
							History.pushState({page: self.closest('li').index()}, self.attr('title'), self.attr('href'));
						}
						
						$('.outer', pageHolder).css({left: hiddenLeft, opacity: 0}).animate({
							left: 0,
							opacity: 1
						}, {
							duration: 1000,
							easing: 'easeInOutCubic',
							complete: function() {
								if(!portfolio.length) {
									var el = $('.main.scroll', pageHolder).jScrollPane();
									var drag = $('.jspDrag', pageHolder);
									drag.hide();
									drag.fadeIn(500);
									if(el) {
										scrollPaneApi = el.data('jsp');
									}
								}
							}
						});
						
					}
				
					if(cachedContent) {
						
						loadPage();
						cachedContent = null;
					} else {
						pageHolder.load(self.attr('href') + '?nocache=' + Math.random() + ' .main', function() {
							loadPage();
						});
					}	
						
					mainNavLi.removeClass('current').removeClass('before-current');
					self.parent('li').addClass('current').prevAll('li').addClass('before-current');	
					
				}
			});
			
					
		});
		
		if($('body').hasClass('bio-body')) {
		mainNavLi.eq(firstCurrentIndex).find('a').trigger('click');
		}
	}
		
	/**
	 * Insert some dummy ::before, ::after pseudo elements.
	 * I guess that means they're pseudo-pseudo elements...
	 * ... Anyhow, I'm using them before webkit doesn't like transitions on pseudos.
	 */
	
	$.fn.pseudoPseudo = function() {
		$(this).prepend('<span class="before"></span>')
		       .append('<span class="after"></span>');
	};
	
	/**
	 * Need to get the portfolio up and running...
	 */
	 
	$.fn.portfolio = function() {

		var self = $(this),
			ul = self.find('ul'),
			offset = ul.position().top,
			liHeight = ul.find('li').eq(0).outerHeight(true),
			current = null;
	
		self.find('.credits').click(function() {
			window.location = $(this).data('url');
			return false;
		});

		self.find('li').click(function(e) {	
			
			if($(this).parent().is(':animated')) {
				return true;
			}
			
			ul.find('.focus').removeClass('focus');
			
			if($(this).is('.current')) {
				$(this).find('a').addClass('focus');
				return true;
			}
			
			if(!$(this).hasClass('.current')) {
				e.preventDefault();
			}
			
			
			
			
			ul.find('li').removeClass('current');
			
			
			var lastIndex = $('li.current').index();
			lastIndex = lastIndex || 0;
			
			var current = ul.find('li').eq($(this).index());

			self.find('ul').animate({
				top: (current.position().top * -1) + (offset)
			}, {
				duration: 1000,
				easing: 'easeInOutCubic',
				complete: function() {
					
					current.addClass('current');
					$(this).addClass('current');
					
				}		
			});
			
		}).eq(0).trigger('click');
		
		self.find('.down').click(function() {
			var next = self.find('li.current + li');
			next = (next.length) ? next : self.find('li:first');
			next.trigger('click');
		});
		
		$(document).keydown(function(e) {
			
			if(e.keyCode == '38') {
				e.preventDefault();
				// Up
				var next = self.find('li.current').prev('li');
				if(next.length) {
					next.trigger('click');
				}
			}
			else if(e.keyCode == '40') {
				e.preventDefault();
				// Down
				var next = self.find('li.current + li');
				next = (next.length) ? next : self.find('li:first');
				next.trigger('click');
			}
		});
	
	};
	
	$.fn.swissLines = function() {
		
		var canvas = $(this);
			
		var strokes = [
			{
				currentStroke: 1000,
				minStroke: 1000,
				maxStroke: 1050,
				moveX: -250,
				moveY: -150,
				lineToX: 1280,
				color: 'rgba(255, 255, 255, 0.6)',
				axis: 'y'
			}, {
				currentStroke: 1000,
				minStroke: 1000,
				maxStroke: 1250,
				moveX: 1280,
				moveY: -150,
				lineToX: 0,
				color: 'rgba(255, 255, 255, 0.1)',
				axis: 'x'
			}
		];
		
			
		function render() {
			
			var context = canvas[0].getContext('2d');
		
			context.clearRect(0,0,canvas[0].width,canvas[0].height);	
			
			$.each(strokes, function(k,v) {
				
				if(v.currentStroke) {
					
					context.save();
					context.strokeStyle = v.color;
					context.beginPath();
					context.moveTo(v.moveX, v.moveY);
					context.lineTo(v.lineToX, v.currentStroke);
					context.stroke();
					context.closePath();
				
				}
				
			});
		
		}
			
		$(window).mousemove(function(e) {	
		
			$.each(strokes, function(k, v) {	
				var perc = 0;
				if(v.axis == 'y') {
					perc = roundNumber(e.clientY / $('body').height(), 2);
				} else if(v.axis == 'x') {
					perc = roundNumber(e.clientX / $('body').width(), 2);
				}
				v.currentStroke = parseInt(((v.maxStroke-v.minStroke) * -perc) + v.minStroke);	
			});
		});

	 	(function animloop() {
		   render();
		   requestAnimationFrame(animloop, canvas[0]);
		 })();
		
	};
	
	innit_tho();
	
})(this.jQuery);

