/* 
	jQuery Gallery:
		A rotating gallery for Marlboro College
	Author 
	Elliot Anders <elliot@marlboro.edu>
*/
(function($) {
	var defaults = {
		'visibleSlides' : 4, 
		'speed': 500,				// in milliseconds
		'interval': 4000,			// in milliseconds
		'class': 'gallery',
		'height': '400px',
		'width': '300px', // make this wide enough to display the visibleSlides plus the arrows (or wider)
		'pauseHover': false,
		'autoRotate': false,
		'opacity': 0.5,
		'next': 'images/next.gif', // url of image for next arrow
		'prev': 'images/prev.gif' // url of image for previous arrow
	};
	
	$.fn.gallery = function(options) {
		this.each(function($element) {
			$(this).wrap('<div />');
			var $gallery = $(this).parent();
			_setOptions($gallery);
			_init($gallery);
			_start($gallery);
		});
		
		function _setOptions($gallery) {
			options = $.extend({}, defaults, $gallery.data('gallery:options'), options);
      $gallery.data('gallery:options', options);
		};
		
		function _init($gallery) {
			// wrap the entire list with a div to facilitate placement and sizing
			$gallery.addClass($gallery.data('gallery:options')['class']);
			// some tracking variables
			$gallery.data('gallery:selected', 0).data('gallery:firstVisible', 0).data('gallery:intervalID', 0).data('gallery:last', '');
			// hide all of the images and text temporarily
			$('.panel-content', $gallery).hide();
			// show the first one
			$('.panel-content:first', $gallery).show();
			
			_size($gallery);
			_assignNumbers($gallery);
			_buildFilmstrip($gallery);
			_updateVisible($gallery);
			_updateArrows($gallery);
			_enablePause($gallery);
		};
		
		function _size($gallery) {
			$gallery.css('width', $gallery.data('gallery:options')['width']).css('height', $gallery.data('gallery:options')['height']).css('overflow', 'hidden');
		};
		
		function _assignNumbers($gallery) {
			$('li>img', $gallery).each(function(index) {
				// assign ids to the thumbnails and note they are thumbnails while we're at it.
				$(this).attr('id', 'g-' + index).addClass('thumb'); 
				// assign matching classes to the li
				$($('li',$gallery)[index]).addClass('g-' + index); 
			});
		};
		
		function _buildFilmstrip($gallery) {
  		$gallery.append('<div class="filmstrip" />');
			var $film = $('.filmstrip', $gallery);
			// Gather all thumbnails - defined by being the child image in an li
			$film.append($('li>img', $gallery));
			// add in some arrows
			$film.append('<img class="arrow next" />');
			$('.next', $gallery).attr('src', $gallery.data('gallery:options')['next']);
			$film.prepend('<img class="arrow prev" />');
			$('.prev', $gallery).attr('src',$gallery.data('gallery:options')['prev']);
			$('.arrow', $film).css('opacity', $gallery.data('gallery:options')['opacity']).hide();
			// bind all thumbnails to a function for hover
			$('.thumb', $film).hover(function() {
				$(this).data('opacity', $(this).css('opacity'));
				$(this).css('opacity', 1);
			},
			function() {
				$(this).css('opacity', $(this).data('opacity'));
			});
			// bind all thumbnails to a function for clicking
			$('.thumb', $film).bind('click', $gallery, _select);
			// bind hover functions to the arrows
			$('.arrow', $film).hover(function() {
				$(this).css('opacity', 1);
			},
			function() {
				$(this).css('opacity', $gallery.data('gallery:options')['opacity']);
			});
			// bind clicks to the arrows
			$('.arrow', $film).bind('click', $gallery, _arrowClick);
		};
		
		function _select(event) {
			var $gallery = event.data;
			if($(this).attr('id').split('-')[1] == $gallery.data('gallery:selected')) {
				return;
			}
			$gallery.data('gallery:last', $gallery.data('gallery:selected'));
			$gallery.data('gallery:selected', parseInt($(this).attr('id').split('-')[1]));
			
			_updateVisible($gallery);		
		};
		
		 function _updateVisible($gallery) {
			$('.thumb', $gallery).each(function(index, element) {
				// hide any thumbnails we shouldn't see initially
				if(index >= $gallery.data('gallery:options')['visibleSlides'] + $gallery.data('gallery:selected')) {
					$(element).hide();
				}
				// set the opacity of any thumbnails not currently selected
				if(index != $gallery.data('gallery:selected')) {
					$(element).css('opacity', $gallery.data('gallery:options')['opacity']);
				}
				else {
					$(element).css('opacity', 1).show().data('opacity', 1);
				}
			});
			// animate the content change
			$($('.panel-content', $gallery)[$gallery.data('gallery:selected')]).fadeIn($gallery.data('gallery:options')['speed']);
			
			$($('.panel-content', $gallery)[$gallery.data('gallery:last')]).fadeOut($gallery.data('gallery:options')['speed']);
			
		};	
		
		function _updateArrows($gallery) {
			if($('.thumb', $gallery).length < $gallery.data('gallery:options')['visibleSlides']) {
				return;
			}
			// if the first visible item + the visibleSlides is < total length show a right arrow
			if($gallery.data('gallery:firstVisible') + $gallery.data('gallery:options')['visibleSlides'] < $('.thumb', $gallery).length) {
				$('.next', $gallery).show();
			}
			else {
				$('.next', $gallery).hide();
			}
			if($gallery.data('gallery:firstVisible') > 0) {
				$('.prev', $gallery).show();
			}
			else {
				$('.prev', $gallery).hide();
			}
		};
		
		function _moveFrame($gallery, how) {
			switch(how) {
				case 'next':	
					// check if we can move a full page 
					if($gallery.data('gallery:firstVisible') + (2 * $gallery.data('gallery:options')['visibleSlides']) > $('.thumb', $gallery).length) {
						// we don't have enough to move a full frame
						$('.thumb', $gallery).each(function(index,element) {
							if(index < $gallery.data('gallery:firstVisible') + $gallery.data('gallery:options')['visibleSlides']) {
								$(element).hide();	
							}
							else {
								$(element).show();
							}
						});
						$gallery.data('gallery:firstVisible', $gallery.data('gallery:firstVisible') + $gallery.data('gallery:options')['visibleSlides']);
					}
					else {
						$($('.thumb', $gallery)).each(function(index,element) {
							if((index < $gallery.data('gallery:firstVisible') + $gallery.data('gallery:options')['visibleSlides']) || index >= $gallery.data('gallery:firstVisible') + (2 * $gallery.data('gallery:options')['visibleSlides'])) {
								
								$(element).hide();	
							}
							else {
								$(element).show();
							}
						});
						$gallery.data('gallery:firstVisible', $gallery.data('gallery:firstVisible') + $gallery.data('gallery:options')['visibleSlides']);
					}
				break;
				case 'prev':
					// check if we can move a full page 
					if($gallery.data('gallery:firstVisible') - $gallery.data('gallery:options')['visibleSlides'] <= 0) {
						// we don't have enough to move a full frame
						$('.thumb', $gallery).each(function(index,element) {
							if(index >= $gallery.data('gallery:options')['visibleSlides']) {
								
								$(element).hide();	
							}
							else {
								$(element).show();
							}
						});
						$gallery.data('gallery:firstVisible', 0);
					}
					else {
						$('.thumb', $gallery).each(function(index,element) {
							if((index <= $gallery.data('gallery:firstVisible') - $gallery.data('gallery:options')['visibleSlides']) || index > $gallery.data('gallery:firstVisible')) {
						
								$(element).hide();	
							}
							else {
								$(element).show();
							}
						});
						$gallery.data('gallery:firstVisible', $gallery.data('gallery:firstVisible') - $gallery.data('gallery:options')['visibleSlides']);
					}
				break;
			}
			_updateArrows($gallery);
		};
		
	  function _arrowClick(event) {
	  	$gallery = event.data;
			if($(this).hasClass('next')) {
				_moveFrame($gallery, 'next');
			}
			if($(this).hasClass('prev')) {
				_moveFrame($gallery, 'prev');
			}
		};
		
		function _start($gallery) {
			if($gallery.data('gallery:options')['autoRotate']) {
				$gallery.data('gallery:intervalID', setInterval(function() { _highlightNext($gallery); }, $gallery.data('gallery:options')['interval']));
			}
		};
		
		function _stop($gallery) {
			clearInterval($gallery.data('gallery:intervalID'));
		};
		
		function _highlightNext ($gallery) {
			if($gallery.data('gallery:selected') >= $('.thumb', $gallery).length - 1) {
				clearInterval($gallery.data('gallery:intervalID'));
			}
			else {
				if($gallery.data('gallery:selected') >= ($gallery.data('gallery:firstVisible') + $gallery.data('gallery:options')['visibleSlides'] - 1)) {
					_moveFrame($gallery, 'next');
				}
				$gallery.data('gallery:last', $gallery.data('gallery:selected'));
				$gallery.data('gallery:selected', $gallery.data('gallery:selected') + 1);
				_updateVisible($gallery);
			}
		};
		
		function _enablePause($gallery) {
			if($gallery.data('gallery:options')['pauseHover']) {
				$gallery.hover(function() {
					_stop($gallery);
				},
				function() {
					_start($gallery);
				});
			}
		};
		
		// end
		return this;
	};
})(jQuery);


