// 
//  jquery.gallery.js
//  walkleyfoundation
//  
//  Created by justin.morris on 2009-06-12.
//  Copyright 2009 justin.morris. All rights reserved.
// 

var autoplay_timer = null;

;(function($) {
	
	var imageRegExp = /\.(jpg|gif|png|bmp|jpeg)(.*)?$/i;
	var images = {};
	var loaded_images = { full:{}, thumb:{} };
	var pointer = 0;
	var num_images = null;
	var busy = false;
	var autoplay_active = false;
	
	$.fn.gallery = function(settings) {
		info('Starting gallery...');
		// build main options before element iteration
		var opts = $.extend({}, $.fn.gallery.defaults, settings);
		$this = $(this);
		
		// get an array of all the feature images and thumbnails
		
		// iterate and reformat each matched element
		return this.each(function() {
			// build element specific options
			var opts = $.extend({}, $.fn.gallery.defaults, settings);
			busy = true;
			
			// Build our gallery object
			images = $.fn.gallery._get_images();
			
			// Setup the gallery and the loader...
			$('.gallery .nojs', $this).remove();
			$('.gallery .loading', $this).show();
			
			// Setup the scollers with the correct number of items...(thumbs and main images)
			var textToInsert = '';
			for (var i=0; i < images.full.length; i++) {
				textToInsert  += '<li></li>';
			};
			// Important to empty() first here...
			$('.gallery .scroller, .gallery .thumbnail-slider', $this).empty().append(textToInsert);
			$('.gallery .scroller', $this).width((num_images * 540) + 'px');
			$('.gallery .thumbnail-slider', $this).width((num_images * 83) + 'px');
			
			// Set up the autoplayer behaviour...
			$('.gallery-controls .auto-player').click(function(){
				if( autoplay_active ){
					$.fn.gallery._autoplay_stop(opts);
				}else{
					$.fn.gallery._autoplay_start(opts);
				};
				return false;
			});
			
			$('a.view-full').click(function(){
				$('.scroller li:eq('+pointer+') a', $this).click();
				info($('.scroller li:eq('+pointer+') a', $this));
				return false;
			});
			
			$.fn.gallery.preload('thumb', 0, images.thumb.length, function(){
				info(images);
			});
			
			// Preload the images required at the start...
			$.fn.gallery.preload('full', 0, 2, function(){
				info('preload full callback');
				// Fadeout the loader...
				$('.gallery .loading', $this).fadeOut(400, function(){
					$('.gallery .scroller', $this).fadeIn(250);
					$.fn.gallery._setup_navigation(opts);
					$.fn.gallery._update_progress();
					$('.scroller-container', $this).append();
					$('.gallery .gallery-controls', $this).fadeIn(450);
					busy = false;
					
					if( opts.autoplay_on ){
						$.fn.gallery._autoplay_start(opts);
					};
				});
			});
			
		});
	};
	
	$.fn.gallery.render_preloaded_images = function(type, images) {
		$(images).each(function(i){
			if ( type == 'full' ){
				if( images[i].image.height < 529 ){
					$(images[i].image).css({
						'top':'50%',
						'marginTop' : '-' + (images[i].image.height / 2) + 'px'
					});
				}
				if ( images[i].image.width < 540 ){
					$(images[i].image).css({
						'left':'50%',
						'marginLeft' : '-' + (images[i].image.width / 2) + 'px'
					});
				}
				var scroller_index = $('.gallery .scroller li:eq('+images[i].index+')', $this);
				var text_to_insert = $('<a href="'+images[i].orig+'"></a>').append($(images[i].image));
				scroller_index.append(text_to_insert);
				scroller_index.append('<p class="caption">'+images[i].caption+'</p>');
				build_fancybox();
			}else{
				var scroller_index = $('.gallery .thumbnail-slider li:eq('+images[i].index+')', $this);
				// var text_to_insert = $('<a href="'+images[i].orig+'" title="'+images[i].caption+'"></a>').append($(images[i].image));
				var text_to_insert = $('<a href="'+images[i].orig+'"></a>').append($(images[i].image));
				scroller_index.append( text_to_insert );
			}
		});
		return;
	}
		
	/*
	/	Preload from and array of images between indexes "start" and "end"
	*/
	$.fn.gallery.preload = function(type, start, end, callback){
		info('preloading "'+type+'" images ['+start+':'+end+']');
		
		var load_counter = 0;
		var preloaded = new Array();
		
		for(var i=start; i < end; i++){
			// Check if this image is already loaded...
			if( (i in loaded_images[type]) ){
				info('image '+i+' already loaded. skipping');
				if( callback ){ callback(); }
				continue;
			}else{
				var img = new Image();
				$(img).load(function(){
					$(this).loaded = true;
					// If the number of loaded images equals the range then this load is done!
					load_counter++;
					if ( load_counter == (end - start) ){
						info('preloading "'+type+'" complete!');
						$.fn.gallery.render_preloaded_images(type, preloaded);
						if( callback ){
							callback();
						}
					}
				}).attr("title", $(images[type][i]).attr('title')).attr("src", $(images[type][i]).html());
				
				// contains refs to the loaded images...
				preloaded.push({
					'index': i,
					'caption': $(images['meta'][i]).html(),
					'image': img,
					'orig': $(images[type][i]).attr('href')
				});
				
				// Update object to reflect newly loaded image...
				loaded_images[type][i] = true;	
			};
		}
	}
	
	$.fn.gallery._get_images = function(){
		var images = {
			full: $('.data .images a.gallery-orig', $this),
			thumb: $('.data .thumbs a', $this),
			meta: $('.data .images .meta', $this)
		};
		$('.data', $this).remove(); // Clean up...
		num_images = images.full.length;
		info('number of images: ' + num_images)
		info(images);
		return images;
	};
	
	$.fn.gallery._update_progress = function() {
		
		info('_update_progress');
		
		$('.position', $this).fadeOut(150).html( 'image ' + (pointer+1) + ' / ' + num_images ).fadeIn(150);
		
		// Handle pointer extremes - ie: first and last...
		if( pointer == 0 ){
			$('.navigation .prev').addClass('disabled').fadeTo(200, 0.4);
		}else{
			$('.navigation .prev').removeClass('disabled').fadeTo(200, 1.0);
		}
		if( pointer == (num_images-1) ){
			$('.navigation .next').addClass('disabled').fadeTo(200, 0.4);
		}else{
			$('.navigation .next').removeClass('disabled').fadeTo(200, 1.0);
		}
		
		return;
	}
	
	$.fn.gallery._handle_navigation = function() {
		var next_pointer = pointer + 1;
		
		// Add active class to thumbnail nav...
		$('.gallery .thumbnail-slider a.active', $this).removeClass('active');
		$('.gallery .thumbnail-slider li:eq('+pointer+') a', $this).addClass('active');
		
		// Tell the preloader to go get the next image!
		if( next_pointer < num_images ){
			$.fn.gallery.preload('full', next_pointer, next_pointer+1);
		}
		return;
	}
	
	$.fn.gallery._jump_to_image = function(opts, image_id, callback) {
		var image_id = image_id.split("-");
		if( image_id.length == 2 ){
			
			var index = parseInt(image_id[1]);
			info('jumping to image: '+index);
			
			if( index <=  num_images ){
				$.fn.gallery.preload('full', index, index+1, function(){
					pointer = index;
					var offset = $.fn.gallery._get_index_offset(pointer);
					$.fn.gallery._animate_slider(opts, offset, function(){
						$.fn.gallery._handle_navigation();
						if( callback ){ callback(); };
						return true;
					});
				});
			}
		}
		return false;
	}
	
	$.fn.gallery._get_index_offset = function(index) {
		return -(index * $('.scroller li', $this).width());
	}
	
	$.fn.gallery._get_next_offset = function() {
		return $('.scroller', $this).position().left - $('.scroller li', $this).width();
	}
	
	$.fn.gallery._get_prev_offset = function() {
		return $('.scroller', $this).position().left + $('.scroller li', $this).width();
	}
	
	$.fn.gallery._animate_slider = function(opts, offset, callback) {
		busy = true;
		$.fn.gallery._update_progress();
		$('.scroller', $this).animate({ 'left':offset }, opts.scroller_speed, function(){
			if( callback ){
				callback();
			}
			busy = false;
		});
		return;
	}
	
	$.fn.gallery._setup_navigation = function(opts) {
		// Handle navigating through the gallery...
		$('.navigation a', $this).click(function(){
			var animation_offset = 0;
			
			if( ! busy ){
				// Sanity check...
				if( $(this).hasClass('next') ){
					// Next
					if ( pointer != (num_images-1) ) {
						animation_offset = $.fn.gallery._get_next_offset();
						pointer++;
					}else{
						return false;
					};
				}else if( $(this).hasClass('prev') ){
					// Previous
					if ( pointer != 0 ) {
						animation_offset = $.fn.gallery._get_prev_offset();
						pointer--;
					}else{
						return false;
					};
				}
				// Animate the scroller
				$.fn.gallery._animate_slider(opts, animation_offset, function(){
					$.fn.gallery._handle_navigation();
				});
				info('pointer is now: '+pointer);
			}
			return false;
		});
		
		$('.thumbnails').click(function(){
			if( $('.thumbnail-pane:animated').length == 0 ){
				$('.thumbnail-pane').slideToggle(250);
			}
			return false;
		});
		
		$('.thumbnail-slider a').click(function(){
			if( ! $(this).hasClass('active') ){
				var self = $(this); // Reference to 'this'
				$.fn.gallery._loadify(self);
				$.fn.gallery._jump_to_image(opts, self.attr('href'), function(){
					$.fn.gallery._loadify(self);
				});	
			}
			return false;
		});
		
		$('.thumb-navigation a').click(function(){
			if( $('.thumbnail-slider:animated', $this).length == 0 ){
				var currentOffset = $('.thumbnail-slider', $this).position().left;
				var sliderWidth = $('.thumbnail-slider', $this).width();
				var stepWidth = $('.thumbnail-slider img', $this).width() + 8;
				var maxNegativeOffset = -(sliderWidth - 490);
				
				if( $(this).hasClass('next') ){
					var offset = currentOffset - stepWidth;
				}else{
					if (currentOffset != 0){
						var offset = currentOffset + stepWidth;
					}else{
						offset = 0;
					}
				}
				
				if ( offset >= maxNegativeOffset )
					$('.thumbnail-slider', $this).animate({ 'left': offset }, 200);
			};
			return false;
		});
		
	}
	
	$.fn.gallery._autoplay_start = function(opts) {
		$('.auto-player', $this).addClass('active');
		$('.navigation', $this).fadeOut(150);
		autoplay_active = true;
		autoplay_timer = setTimeout(function(){ $.fn.gallery._autoplay(opts) }, opts.autoplay_speed);
	}
	
	$.fn.gallery._autoplay_stop = function() {
		$('.auto-player', $this).removeClass('active');
		$('.navigation', $this).fadeIn(150);
		autoplay_active = false;
		clearTimeout(autoplay_timer);
	}	
	
	$.fn.gallery._autoplay = function(opts){
		if( pointer != (num_images-1) ){
			var offset = $.fn.gallery._get_next_offset();
			$.fn.gallery._animate_slider(opts, offset, function(){
				$.fn.gallery._handle_navigation();
			});
			autoplay_timer = setTimeout(function(){ $.fn.gallery._autoplay(opts) }, opts.autoplay_speed);
			pointer++;
		}else{
			$.fn.gallery._autoplay_stop();
		}
	};
	
	$.fn.gallery._loadify = function(target){
		if( $('div.loader', target).length == 0 ){
			var loader = $('<div class="loader"></div>').css({
				'position': 'absolute',
				'top': '50%',
				'left': '50%',
				'height': 20,
				'width': 20,
				'marginTop': -10,
				'marginLeft': -10
			}).hide();
			target.append(loader);
			loader.fadeIn(200, function(){
				return;
			});
		}else{
			$('div.loader', target).fadeOut(200, function(){
				$(this).remove();
				return;
			});
		};
	};
	
	// private function for debugging
	function info(message) {
		return;
		if (window.console && window.console.log)
		window.console.log(message);
	};
	function error(message) {
		return;
		if (window.console && window.console.error)
		window.console.error(message);
	};
	
	// plugin defaults
	$.fn.gallery.defaults = {
		scroller_speed: 250,
		autoplay_on: false,
		autoplay_speed: 5000
	};
	
})(jQuery);


$(function(){
	$('#gallerywrapper').gallery();
});