/**
 * The Gallery class
 * 
 * @author Karl Shea	kshea@matharts.com
 */
Gallery = function(args){
	var defaults = {
		fullImageId: '#gallery-image',
		pagerId: '#gallery-image-pager',
		thumbScrollId: '#gallery-scroll',
		scrollNavId: '#gallery-scroll-nav',
		
		captionClass: '.gallery-text',
		imageCaptionClass: '.image-caption',
		
		scrollUpClass: '.up',
		scrollDownClass: '.down',
		
		captionScrollUpClass: '.gallery-image-caption-up',
		captionScrollDownClass: '.gallery-image-caption-down',
		captionViewportClass: '.gallery-image-caption-viewport',
		
		fadeSpeed: 300,
		scrollTimeout: 20,
		scrollStep: 5,
		
		thumbsPerScreen: 5
	};
	
	$.extend(defaults, args);
	
	this._CONFIG = defaults;
	
	this._CURRENT_VIEWPORT_INDEX = 0;
	this._CURRENT_THUMB_INDEX = 0;
	this._CURRENT_PHOTO_INDEX = 0;
};

$.extend(Gallery.prototype, {
	
	/**
	 * Initialize the Gallery
	 */
	init: function() {
		this._setupThumbEvents();
		
		// Scroll the viewport to the top and find the thumb groups
		var viewport = $(this._CONFIG.thumbScrollId);
		var thumbs = $('li img', viewport);
		var position = $(thumbs[0]).offset();
		
		viewport.scrollTop(position['top'] + (viewport.scrollTop() - viewport.offset()['top']));
		
		// Load the first thumb group
		this._loadImageGroup(thumbs[0]);
	},

	/**
	 * Activate an image index
	 * 
	 * @param {Object} imageIndex
	 */
	activateImage: function(imageIndex) {
		var viewport = $(this._CONFIG.thumbScrollId);
		var caption = $(this._CONFIG.captionClass);
		var fullImage = $(this._CONFIG.fullImageId + ' img')[0];
		var imageGroups = $('li ul', viewport);
		
		var animateElements = $(this._CONFIG.fullImageId + ' img, ' + this._CONFIG.captionClass);
		
		this._CURRENT_PHOTO_INDEX = imageIndex;
		
		var newImage = $($('li > a', imageGroups[this._CURRENT_THUMB_INDEX])[this._CURRENT_PHOTO_INDEX]);
		var newCaption = $(this._CONFIG.imageCaptionClass, newImage.parent());
		
		(function(me) {
			// Fade out the main image
			$(animateElements).animate({
				opacity: 0
			}, {
				queue: false,
				duration: me._CONFIG.fadeSpeed,
				complete: function() {
					
					// Load a temp image to make sure things work right
					var newImageCached = new Image();
					
					// Set up load function that will be triggered when setting src below
					$(newImageCached).load(function() {
						// Set the full image to the link href
						fullImage.src = newImageCached.src;
						
						// Set the caption text
						caption.html(newCaption.length > 0 ? newCaption.html() : '');
						
						// Setup the caption scrolling events
						$(me._CONFIG.captionClass + ' ' + me._CONFIG.captionScrollUpClass).mousehold(me._CONFIG.scrollTimeout, function() {
							var viewport = $(me._CONFIG.captionClass + ' ' + me._CONFIG.captionViewportClass); 
							viewport.scrollTop(viewport.scrollTop() - me._CONFIG.scrollStep);
						});
						$(me._CONFIG.captionClass + ' ' + me._CONFIG.captionScrollDownClass).mousehold(me._CONFIG.scrollTimeout, function() {
							var viewport = $(me._CONFIG.captionClass + ' ' + me._CONFIG.captionViewportClass);
							viewport.scrollTop(viewport.scrollTop() + me._CONFIG.scrollStep);
						});
						
						// Fade the main image back in
						$(animateElements).animate({
							opacity: 1
						}, {
							queue: false,
							duration: me._CONFIG.fadeSpeed
						});
					});
					
					// Set the new image source to the href to begin loading the image
					newImageCached.src = newImage.attr('href');
				}
			});
		})(this);
		
		// Set the active class on the active list item
		var photoLinks = $('li', this._CONFIG.pagerId);
		photoLinks.removeClass('active');
		$(photoLinks[this._CURRENT_PHOTO_INDEX]).addClass('active');
	},
	
	/**
	 * Roll the image index
	 */
	rollImage: function() {
		var viewport = $(this._CONFIG.thumbScrollId);
		var imageGroups = $('li ul', viewport);
		var images = $('a', imageGroups[this._CURRENT_THUMB_INDEX]);
		
		this.activateImage((this._CURRENT_PHOTO_INDEX < images.length - 1) ? 
			this._CURRENT_PHOTO_INDEX + 1 : 0);
	},
	
	/**
	 * Setup the thumb events
	 */
	_setupThumbEvents: function() {
		(function(me) {
			// Handle a thumbnail click
			$(me._CONFIG.thumbScrollId + ' img').click(function(){ me._loadImageGroup(this) });
			
			// Handle scrolling the viewport
			$(me._CONFIG.scrollNavId + ' ' + me._CONFIG.scrollUpClass + ' a').click(function() { me._scrollThumbs('up'); });
			$(me._CONFIG.scrollNavId + ' ' + me._CONFIG.scrollDownClass + ' a').click(function() { me._scrollThumbs('down'); });
		})(this);
	},
	
	/**
	 * Loads in an image group
	 * 
	 * @param {Object} thumb
	 */
	_loadImageGroup: function(thumb) {
		var groupImages = $('li > a', $(thumb).parent());
		var pagerList = $('ul', this._CONFIG.pagerId);
		
		this._CURRENT_THUMB_INDEX = $(thumb).parent().parent().children().index($(thumb).parent());
		
		// Setup pager
		pagerList.empty();
		(function(me) {
			groupImages.each(function(i) {
				// Construct the item and link
				var item = $('<li/>');
				
				var link = $('<a href="javascript:void(0)"></a>');
				link.click(function() {
					me.activateImage(i);
				});
				link.html(i + 1);
				
				item.append(link);
				pagerList.append(item);
			});
		})(this);
		
		// Add next item
		var nextItem = $('<li/>');
		nextItem.addClass('no-image');
		
		var nextLink = $('<a href="javascript:void(0)"></a>');
		(function(me){
			nextLink.click(function() {
				me.rollImage();
			});
		})(this);
		nextLink.html('Next');
		nextItem.append(nextLink);
		pagerList.append(nextItem);
		
		// Activate the first item
		this.activateImage(0);
	},
	
	/**
	 * Scroll the thumbs viewport
	 * 
	 * @param {Object} direction
	 */
	_scrollThumbs: function(direction) {
		var viewport = $(this._CONFIG.thumbScrollId);
		var thumbs = $('li img', viewport);
		
		if(direction == 'up') {
			if(this._CURRENT_VIEWPORT_INDEX > 0)
				this._CURRENT_VIEWPORT_INDEX--;
		}
		else {
			if(this._CURRENT_VIEWPORT_INDEX < thumbs.length - this._CONFIG.thumbsPerScreen)
				this._CURRENT_VIEWPORT_INDEX++;
		}
		
		var focusItem = thumbs[this._CURRENT_VIEWPORT_INDEX];
		var position = $(focusItem).offset();
		
		viewport.stop();
		viewport.animate({
			scrollTop: position['top'] + (viewport.scrollTop() - viewport.offset()['top'])
		}, {
			duration: this._CONFIG.fadeSpeed,
			queue: false
		});
	}
});