// 
//  imageSlider.js
//  jcontonio.com
//  
//  Created by Jay Contonio on 2009-11-11.
//	Added wrapping as an option
// 

var _captions = new Array();
var _descriptions = new Array();
var _urls = new Array();

var _mask;
var _maskHeight;
var _container;
var _listItems;
var _arrowClass;
var _captionElement;
var _descriptionElement;

var _currentIndex = 0;
var _slidesWidth;
var _slideWidth;
var _numSlides;
var _time = 8000;
var _intervalID;
var _wrap;

/* Splash object
--------------------------------------------- */
var Slides = {
	create: function(mask, domElement, listItems, arrowClass,slidesPer,spacing,wrap) {
		// Pass a mask div, the containing DOM element (ul,ol), the items (li,a,etc), and a class name for your arrow elements
		// The requirement here is your href for each arrow element should be #next or #previous
		_mask = mask;
		_container = domElement;
		_listItems = listItems;
		_arrowClass = arrowClass;
		_wrap = wrap;
		slidesPer == undefined ? _slidesPer = 1 : _slidesPer = slidesPer;
		spacing == undefined ? _spacing = 0 : _spacing = spacing;
	},
	start: function() {
		
		if(_wrap) Slides.createWrappingItem();
		
		// Set the number of slides
		_numSlides = $(_listItems).length;
		
		// Set slide width
		_slideWidth = $(_listItems[0]).width() + _spacing;
		$(_container).width(_numSlides * _slideWidth);
		_slidesWidth = $(_mask).width();
		
		// Override the number of slides if we are passed a slidesPer variable
		// ie: if there are 3 slides per Slide
		_numSlides = Math.floor(_numSlides / _slidesPer);
		
		// Set the mask height
		$(_mask).height($(_listItems[0]).height());
		
		// Add the click handlers to the arrows
		Slides.enableArrows();
		
		if(!_wrap) Slides.disableArrow('previous');
	},
	
	/* Setters and getters
	--------------------------------------------- */
	setTime: function(time) {
		_time = time;
		Slides.killTimer();
		Slides.startTimer();
		return _time;
	},
	time: function() { return _time; },
	currentIndex: function() { return _currentIndex; },
	setMask: function(mask) { _mask = mask; },
	setContainer: function(container) { _container = container; },
	setListItems: function(listItems) { _listItems = listItems; },
	listItems: function() { return _listItems; },
	setArrowClass: function(arrowClass) { _arrowClass = arrowClass; },
	setCaptionElement: function(captionElement) { _captionElement = captionElement; },
	setDescriptionElement: function(descriptionElement) { _descriptionElement = descriptionElement; },
	
	/* Timer
	--------------------------------------------- */
	startTimer: function() {
		_intervalID = setInterval(Slides.move, _time, 'next');
	},
	killTimer: function() { clearTimeout(_intervalID); },
	
	/* Captions
	--------------------------------------------- */
	setCaptions: function(captionElements) {
		$(captionElements).each(function() { _captions.push($(this).html()); });
		// Set the first caption
		Slides.displayCaption(0);
	},
	displayCaption: function(index) {
		$(_captionElement).html(_captions[index]);
		return false;
	},
	
	/* Descriptions
	--------------------------------------------- */
	setDescriptions: function(descriptionElements) {
		$(descriptionElements).each(function() { _descriptions.push($(this).html()); });
		// Set the first description
		Slides.displayDescription(0);
	},
	displayDescription: function(index) {
		$(_descriptionElement).html(_descriptions[index]);
		return false;
	},
	
	/* Arrows
	--------------------------------------------- */
	disableArrow: function(arrow) {
		$(_arrowClass + '[href=#' + arrow + ']').css({ cursor:'default',backgroundPosition:'bottom' });
	},
	enableArrow: function(arrow) {
		$(_arrowClass + '[href=#' + arrow + ']').css({ cursor:'pointer',backgroundPosition:'top' });
	},
	enableArrows: function() {
		$(_arrowClass).click(function(e) {
			e.preventDefault();
			$(this).attr('href') == "#previous" ? Slides.move('previous') : Slides.move('next');
			Slides.killTimer();
			return false;
		});
	},
	disableArrows: function() {
		$(_arrowClass).unbind('click');
	},
	
	/* Wrapper item
	   Duplicates the first list item and appends it to the list so we can create a looping effect
	--------------------------------------------- */
	createWrappingItem: function() {
		$(_listItems[0]).clone().appendTo(_container);
		_listItems.push($(_listItems[0]));
	},
	
	/* Navigating
	--------------------------------------------- */
	move: function(direction) {
		
		if(direction == 'previous') {
			// If wrapping is turned on, position the container to the duplicated list item, set the current index manually
			// and then move
			if(_wrap) {
				if(_currentIndex <= 0) {
					var wrappingPosition = -($(_container).width() - _slideWidth);
					$(_container).css({'left':wrappingPosition + 'px'});
					_currentIndex = _numSlides - 1;
				}
			} else {
				if(_currentIndex <= 0) { return; }
			}
			_currentIndex--;
			
		} else if(direction == 'next') {
			// If wrapping is turned on, position the container to the first list item after the last move, set the current index manually
			if(_wrap) {
				if(_currentIndex >= _numSlides - 1) {
					$(_container).css({'left':'0'});
					_currentIndex = 0;
				}
			} else {
				if(_currentIndex >= _numSlides - 1) {
					Slides.killTimer();
					return;
				}
			}
			_currentIndex++;
		} else {
			_currentIndex = direction;
			Slides.enableArrow('previous');
			Slides.enableArrow('next');
		}
		
		// Set the mask height so each slide can have it's own unique height
		$(_mask).height($(_listItems[_currentIndex]).height());
		
		if(!_wrap) {
			// Disable or enable arrows based on position
			if(_currentIndex == 0) { Slides.disableArrow('previous'); }
			if(_currentIndex == _numSlides - 1) { Slides.disableArrow('next'); }
		}
		
		var currentPosition = $(_container).css('left');
		
		if(typeof direction == 'string') {
			var calculation = direction == 'previous' ? (parseFloat(currentPosition) + _slidesWidth) + _spacing : parseFloat(currentPosition) - _slidesWidth - _spacing;
			Slides.enableArrow(direction == 'next' ? 'previous' : 'next');
		} else {
			var calculation = -(direction * _slideWidth) + _spacing;
		}
		
		Slides.disableArrows();
		$(_container).animate({
			left: (calculation) + 'px'
		}, "medium", Slides.enableArrows);
		
		// Trigger an event so we can do other things when the carousel moves
		var event = jQuery.Event("carouselMoved");
		event.frame = _currentIndex;
		event.direction = direction
		$().trigger(event);
		
		// If there is a caption element set, display the caption
		if(_captionElement != undefined) {
			Slides.displayCaption(_currentIndex);
		}
		
		// If there is a description element set, display the description
		if(_descriptionElement != undefined) {
			Slides.displayDescription(_currentIndex);
		}
		
		
	},
	navigateTo: function(index) {
		location.href = _urls[index];
	}
}
