/* 
*	Image grid
*/

(function($) {
  $.fn.gridder = function(options) {
    options = $.extend({
		slotWidth: 300,		// Slot width
		imageWidth: 400,	// Portrait width
		defaultImage: '',	// Used to fill up empty slots at the end
		keys: false,		// Up and down keystrokes, set 'true' to enable
		forcePixels: false	// false: .unit width in %, true .unit width in px
    }, options);

	var imageSet = []	// All portrait images
	var gridSet = []	// New order
	var slots = 0;		// Number of slots in width
	var gridHeight = 0;
	var grid = this;
	
	var initialRun = true;
	var gridSource = '';
	var	currentScrollY = 0;
	
	init();

	function mobile() {
		if ((navigator.userAgent.indexOf('iPhone') != -1) || (navigator.userAgent.indexOf('iPad') != -1)) {
			return true;
		} else {
			return false;
		}
	}

	function getImageProportion(imgsrc) {
			imgsrc = imgsrc.split('/');
			filename = imgsrc[imgsrc.length-1];
			imgType = filename.split('_')[1];
			
			if (imgType == 'l') {
				// Landscape
				return options.imageWidth*2;
			} else if (imgType == 'p') {
				// Portrait
				return options.imageWidth;
			} else {
				return false;
			}
	}
	
	
	// Calcs columns
	function calcSlots() {
		return Math.floor($(window).width()/options.slotWidth);
	}
	
	var winWidth = $(window).width(),
	winHeight = $(window).height();

	// Window resize | checks if there is room for another column
	function reinit() {
		$('.grid').html(gridSource);
		buildGrid();
		preloading(0,1);
	}
	
	// Window resize | checks if there is room for another column
	function resize() {
		newHeight = $('.unit:first').height()*$('.first').length;
		if (newHeight > 0)
			$('#main-content').height($('.unit:first').height()*$('.first').length);
		
		if ( calcSlots() != slots) {
			buildGrid();
		}
	}
	
	function init() {
		gridSource = $('.grid').html();
		
		// Resize window handler
		$(window).resize(function() {
		
			var winNewWidth = $(window).width(),
			winNewHeight = $(window).height();

			if(winWidth!=winNewWidth || winHeight!=winNewHeight) {
				initialRun = false;

				if(this.resizeTO) clearTimeout(this.resizeTO);
				this.resizeTO = setTimeout(function() {
					reinit();
				}, 500);
			}

			winWidth = winNewWidth;
			winHeight = winNewHeight;
		});
		
		if (mobile())
			$('html').addClass('mobile');
		
		if (!mobile())
			$('.collection-nav .arrows-icon').show();
		
		// Fixes
		$('html').css('overflow-y','scroll');
		if(mobile()) $('.grid').css('overflow','hidden');
		$('.footer').css('clear','both');
		
		// Plus hover
		if ($('.unit .plus-hover').length > 0) {
			$('.unit').live({
				mouseenter:
				   function()
				   {
						$(this).find('.plus-hover').show();
				   },
				mouseleave:
				   function()
				   {
						$(this).find('.plus-hover').hide();
				   }
			   });
		};
		
		if( $('body > .footer').length > 0 ) {
			footer = $('.footer');
			$('.footer').remove();
			$(footer).appendTo('#main-content');
		}
		
		$('.grid noscript').remove();
		
		// Read original data to json	
		grid.find('.unit').each(function(i){	
			imgSrc= $(this).find('img').attr('rel');
					
			if (mobile()) {
				imgSrc= imgSrc.replace('t_p','mt_p');
				imgSrc= imgSrc.replace('t_l','mt_l');
			}
			
			$(this).find('img').attr('rel',imgSrc);
			
			// Identify Portrait or Landscape
			imgWidth = getImageProportion(imgSrc);
			imageSet.push({
				'div':$(this).find('img').css('width','100%').closest('.unit').html(),
				'width':imgWidth,
				'displayed': false,
				'imgSrc': imgSrc
			});

			// When last item.. (IE7 fix)
			if( i+1 == $('.grid .unit').length) {
				buildGrid();
				
				$('.placeholder').css({'opacity':0});
				
			}
		});

		preloading(0,1);

		// Set keystrokes if true
		if (options.keys)
			setKeys();

	}
	
	
	function buildGrid() {
		var perc = 0;					// Column width in percentage
		var findPortrait = false;		// Replacing empty slot for portrait
		var slotCounter = 0;			// Counts slots per row
		var unit = '';					// HTML .unit
		var outputSet = [];				// Image set
		
		var slots = calcSlots();		// Number of slots
		
		initialRun = true;
		outputSet = getImageSet();
		perc = 100 / slots;
		imageWidth = options.imageWidth;
		
		// Empty grid
		$(grid).find('.unit').remove();
		
		gridSet = [];
		
		for ( i=0; i<outputSet.length; i++ ) {
			findPortrait = false;
			emptyFiller = false;
			
			x = i;
			
			// Finding a portrait to fill up empty slot
			if ( slots-slotCounter == 1 && outputSet[i].width > imageWidth ) {
				
				findPortrait = false;				
				for (j=i;j<outputSet.length;j++) {
					
					if(outputSet[j].width == imageWidth && findPortrait == false   && !outputSet[j].displayed  ) {

						// Sets variables to skip image
						findPortrait = true;						
						x = j;
						outputSet[j].displayed = true;
						i--;
					}
				}
				
				if (!findPortrait)
					emptyFiller = true;
			}
			
			
			if (emptyFiller) {
				fillEmptySlot();
				slotCounter = 0;
			}
			
	   
			// Set width
			outputSet[x].width == imageWidth ? slotSpan = 1 : slotSpan = 2;
			
			// Use pixels or percentages
			slotWidth = getSlotWidth(slots,slotSpan);
			
			// DOM object
			unit = $('<div/>').
					addClass('unit').
					html(outputSet[x].div).
					//css('width',100/slots*slotSpan+'%').
					css('width',slotWidth).
					data({
						'width':outputSet[x].width,
						'displayed':outputSet[x].displayed,
						'placeholder':false
					});

			// Each first item gets 'first' class
			if ( slotCounter == 0 )
				unit.addClass('first');
			
			// Extra class
			unit.addClass('span-'+slotSpan);
			
			// Adding to DOM, skips replacement portrait
			if ( !outputSet[x].displayed || findPortrait ) {

				if ( outputSet[x].width == imageWidth ) {
					slotCounter++;
				} else {
					slotCounter = slotCounter+2;
				}
				
				gridSet.push(outputSet[x].imgSrc);
				
				// OUTPUT!
				$(grid).append(unit);
			}
				
			// Grid build finished
			if ( i == outputSet.length-1 && mobile()) {
				var pWidth = $('.span-1:first').width();
				var ratio = pWidth / imageWidth * 100;
				var pHeight = 541 / 100 * ratio;								// Hard coded 541
				gridHeight = Math.round($('.first').length*pHeight);
				$('.grid').css({'display':'block','height':gridHeight});
			}

			// New row, reset slotcounter
			if ( slots == slotCounter ) {
				slotCounter = 0;
			};

		}
		
		if (slotCounter > 0 && options.defaultImage != '') {
			fillEmptySlots(slotCounter,slots);
		}
	
		
	} // end plugin
	
	// Preloading
	function preloading(index,firstCount) {
		// Set img loads
		
		var randomnumber=Math.floor(Math.random()*10000001); /* takes care of IE caching problem */
		var imgSrc = $('.grid .unit:eq('+index+') img').attr('rel')+'?'+randomnumber;
		
		var imageObj = new Image();
		$(imageObj).attr("src", imgSrc).load(function(response) {
		
			// Places image to screen
			$('.mobile .grid .unit:eq('+index+') img').
				addClass('translateZ');
				
			$('.grid .unit:eq('+index+')').
				find('img').
				css({opacity:0}).
				attr('src',imgSrc).
				animate({opacity:1},500).
				parent().
				css({'background-image':'none'});
			
			if ( $('.grid .unit:eq('+index+')').hasClass('first')) {
				//resetTouchScroll(($('.grid .unit:eq('+index+')').height() * firstCount)+ ($('.footer').height()));
				firstCount++;
			}

			// Fix for ipad
			if(mobile()) {
				//$('.grid .unit:eq(0) img').attr('src',gridSet[0]);
				//$('.grid .unit:eq(1) img').attr('src',gridSet[1]);
				//$('.grid .unit:eq(2) img').attr('src',gridSet[2]);
				
				$('.grid').css({'display':'block','height':gridHeight});
				$('.mobile div#main-content').touchScroll('update');
			}
		
			// First run (handler if build is still running while resizing window)
			if (initialRun==true) {
				
				if(index<$('.grid .unit').length-1) {
					
					// On to the next one
					index++;

					preloading(index, firstCount);
				} else {
					// Finish preloading
					$('.grid .placeholder img').attr('rel', $('.grid .placeholder img').attr('src'));
					$('.grid .placeholder').animate({opacity:1},1000);

					for (i=0;i<imageSet.length;i++) {
						imageSet[i].div = imageSet[i].div.replace('rel','src')
					}

					if(mobile()) {
						mobileLayout();
					}

					$('#main-content').height($('.unit:first').height()*$('.first').length);
					
					// Resize window handler
					$(window).unbind('resize');
					if (navigator.appName != 'Microsoft Internet Explorer') {
						$(window).bind('resize', function(){
							resize();						
						});				
					}
				}
			} else {
				$('.grid').html('');
			}
			
		}); 
	}
	

	
	// Resets image set
	function getImageSet() {
		for ( i=0; i<imageSet.length; i++ ) {
			imageSet[i].displayed = false;
		}
		
		return imageSet;
	}
	
	function getSlotWidth(slots,slotSpan) {
		
		// Use pixels or percentages
		if ( options.forcePixels && navigator.appName != 'Microsoft Internet Explorer' ) {
			perc = 100/slots;
			unitWidth = Math.floor($(window).width()/100*perc);
			slotWidth = unitWidth * slotSpan;
		} else {
			unitWidth = 100/slots;
			slotWidth = Math.floor(unitWidth * slotSpan) + '%';
			$('.nav li:first a').html(slotWidth);
		}
			
		return slotWidth;
	}
	
	// Fill empty slot
	function fillEmptySlot() {
		var slotWidth = getSlotWidth(calcSlots(),1);
		unit = $('<div/>').
				addClass('unit span-1 placeholder-filler').
				html('<img rel="'+options.defaultImage+'" alt="" style="width:100%;"/>').
				css('width',slotWidth).
				data('placeholder',true);

		$(grid).append(unit);
	}
	
	// Fill empty slots
	function fillEmptySlots(slotCounter,slots) {
		var slotWidth = getSlotWidth(calcSlots(),1);
		for( i=slotCounter;i<slots;i++) {
			unit = $('<div/>').
					addClass('unit span-1 placeholder').
					html('<img rel="'+options.defaultImage+'" alt="" style="width:100%;"/>').
					css('width',slotWidth).
					data('placeholder',true);

			$(grid).append(unit);
		}
		
		// When already loaded and resized
		if($('.unit:first img').attr('src')) {
			$('.placeholder img').attr('src',$('.placeholder img').attr('rel'));
		}
	}

	var keyAnimating = false;
	
	// Attach keystrokes
	function setKeys() {
		$(document).keydown(function(e) {

		  switch(e.keyCode) { 
			 case 38:
				e.preventDefault();
				keyNavigate('up');
			 break;
			 case 40:
				e.preventDefault();
				keyNavigate('down');
			 break;
		  }
		  return false;
		});
	   
	   // Opera fix
		document.onkeypress = function(e) {
			  switch(e.keyCode) { 
				 case 38:
					e.preventDefault();
					keyNavigate('up');
				 break;
				 case 40:
					e.preventDefault();
					//keyNavigate('down');
				 break;
			  }
			
		};

	}
	
	// Handle keystrokes
	function keyNavigate(direction) {
		
		// Safari seems to have a keydown bug when still animating
		if(!keyAnimating || (BrowserDetect.OS=='Mac' && BrowserDetect.browser=='Safari') ) { 

			keyAnimating = true;
			
			var unitHeight = $('.grid .unit').height();
			var currentTop = $(window).scrollTop();
			var newTop = 0;

			if ( direction == 'up' ) {
			  checkPos = currentTop/unitHeight;
			  pos = Math.floor(currentTop/unitHeight);

			  // Checking imageport
			  if(checkPos > pos) {
				newTop = (pos) * unitHeight;
			  } else {
				newTop = (pos-1) * unitHeight;
			  }

			} else if ( direction == 'down' ) {
			   pos = Math.floor(currentTop/unitHeight);
			   newTop = (pos+1) * unitHeight;
			}
			
			$('html, body').stop().animate({
				scrollTop: newTop
			}, {
				'duration':500,
				'easing':'easeOutQuint',
				'queue':false,
				'complete':function() {
					keyAnimating = false;
				}
			});
			
			
		}
		
	}
	
	// Fixes layout for mobile
	function mobileLayout() {
		$('.grid').height($('.grid .first:eq(0)').height()*$('.grid .first').length);

		containerHeight = ($('.grid .first:eq(0)').height()*$('.grid .first').length) + ($('.footer').height());
		resetTouchScroll(containerHeight);
	}
	
  }
  
})(jQuery);

var BrowserDetect = {
	init: function () {
		this.browser = this.searchString(this.dataBrowser) || "An unknown browser";
		this.version = this.searchVersion(navigator.userAgent)
			|| this.searchVersion(navigator.appVersion)
			|| "an unknown version";
		this.OS = this.searchString(this.dataOS) || "an unknown OS";
	},
	searchString: function (data) {
		for (var i=0;i<data.length;i++)	{
			var dataString = data[i].string;
			var dataProp = data[i].prop;
			this.versionSearchString = data[i].versionSearch || data[i].identity;
			if (dataString) {
				if (dataString.indexOf(data[i].subString) != -1)
					return data[i].identity;
			}
			else if (dataProp)
				return data[i].identity;
		}
	},
	searchVersion: function (dataString) {
		var index = dataString.indexOf(this.versionSearchString);
		if (index == -1) return;
		return parseFloat(dataString.substring(index+this.versionSearchString.length+1));
	},
	dataBrowser: [
		{
			string: navigator.userAgent,
			subString: "Chrome",
			identity: "Chrome"
		},
		{ 	string: navigator.userAgent,
			subString: "OmniWeb",
			versionSearch: "OmniWeb/",
			identity: "OmniWeb"
		},
		{
			string: navigator.vendor,
			subString: "Apple",
			identity: "Safari",
			versionSearch: "Version"
		},
		{
			prop: window.opera,
			identity: "Opera"
		},
		{
			string: navigator.vendor,
			subString: "iCab",
			identity: "iCab"
		},
		{
			string: navigator.vendor,
			subString: "KDE",
			identity: "Konqueror"
		},
		{
			string: navigator.userAgent,
			subString: "Firefox",
			identity: "Firefox"
		},
		{
			string: navigator.vendor,
			subString: "Camino",
			identity: "Camino"
		},
		{		// for newer Netscapes (6+)
			string: navigator.userAgent,
			subString: "Netscape",
			identity: "Netscape"
		},
		{
			string: navigator.userAgent,
			subString: "MSIE",
			identity: "Explorer",
			versionSearch: "MSIE"
		},
		{
			string: navigator.userAgent,
			subString: "Gecko",
			identity: "Mozilla",
			versionSearch: "rv"
		},
		{ 		// for older Netscapes (4-)
			string: navigator.userAgent,
			subString: "Mozilla",
			identity: "Netscape",
			versionSearch: "Mozilla"
		}
	],
	dataOS : [
		{
			string: navigator.platform,
			subString: "Win",
			identity: "Windows"
		},
		{
			string: navigator.platform,
			subString: "Mac",
			identity: "Mac"
		},
		{
			   string: navigator.userAgent,
			   subString: "iPhone",
			   identity: "iPhone/iPod"
	    },
		{
			string: navigator.platform,
			subString: "Linux",
			identity: "Linux"
		}
	]

};
BrowserDetect.init();
