/*
 * Fader - jQuery Plugin
 * Simple plugin that allows you to create a interface where items fade in opacity
 *
 * Copyright (c) 2010 Miro Keller
 *
 * Version: 1.0.1 (31/06/2011)
 * Requires: jQuery v1.3+
 *
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 */

//create a closure to isolate the variables from other code
(function($, undefined) {
	$.fn.fader = function(options){
		var opts = $.extend(this, $.fn.fader.defaults, options);
		
		var
			$outer,
			$inner,
			itemsWidth = 0,
			$navContainer,
			$navInner,
			$numbers = new Array(),
			i,
			$navPrev,
			$navNext,
			autoFadeTimer,
			$this = $(this),
			fader = this;
			
			
		if(this.goToItem == undefined){
			this.goToItem = function(index, speedOverride){
				
				index = parseInt(index);
				if(index >= this.items.length) index = this.items.length -1;

				if(this.currentIndex != index){
					if(this.currentIndex != undefined){
						$(this.items[this.currentIndex]).animate({
							opacity: 0
						}, (speedOverride == undefined) ? opts.speed : speedOverride);
					}
					
					$(this.items[index]).animate({
						opacity: 1
					}, (speedOverride == undefined) ? opts.speed : speedOverride);
					this.currentIndex = index;

					$numbers.removeClass('selected');
					$($numbers).filter('[data-index = '+index+']').addClass('selected');

					this.showOrHideNav();

					clearTimeout(autoFadeTimer);
					autoFadeTimer = setTimeout(function() {
						if(fader.autoFade){
							fader.fadeToNext();
						}
					}, this.autoFadeDelay);
				}
				
				return this;
			}
		}
		
		if(this.fadeToNext == undefined){
			this.fadeToNext = function(){
				var new_index;
				if(this.currentIndex >= fader.items.length-1){
					new_index = 0;
				} else {
					new_index = this.currentIndex + 1;
				}	
				this.goToItem(new_index);
			}
		}

		if(this.fadeToPrev == undefined){
			this.fadeToPrev = function(){
				var new_index;
				if(this.currentIndex <= 0){
					new_index = fader.items.length-1;
				} else {
					new_index = this.currentIndex - 1;
				}	
				this.goToItem(new_index);
			}
		}

		if(this.showOrHideNav == undefined){
			this.showOrHideNav = function(){
				if(!opts.continuous){
					if(this.currentIndex == 0){
						if($.support.opacity){
							$navPrev.fadeOut();
						} else {
							$navPrev.css('display', 'none');
						}
					} else {
						if($.support.opacity){
							$navPrev.fadeIn();
						} else {
							$navPrev.css('display', 'block');
						}
					}

					if(this.currentIndex == fader.items.length - 1 || fader.items.length == 0){
						if($.support.opacity){
							$navNext.fadeOut();
						} else {
							$navNext.css('display', 'none');
						}
					} else {
						if($.support.opacity){
							$navNext.fadeIn();
						} else {
							$navNext.css('display', 'block');
						}
					}
				}
			}
		}
		
		if(this.clearTimers == undefined){
			this.clearTimers = function(){
				clearTimeout(autoFadeTimer);
			}
		}
		
		//get all the items to fade
		fader.items = $this.children().get();
		//add the two wrapper elements
		$outer = $('<div class="fader_outer"></div>');
		$outer.append(
			$inner = $('<div class="fader_inner"></div>')
		).appendTo($this);
		
		//get the most-inner element of the navContainer
		$navContainer = $(opts.navContainer);
		$this.append($navContainer);
		$navInner = $navContainer.add($navContainer.find('*')).last();
		
		$numbers = jQuery();
		
		i = 0;
		
		$(fader.items).appendTo($inner).css('float', 'left').each(function(){
			itemsWidth += $(this).outerWidth();
			
			//create a new number element
			var $number_element = $(opts.navNumber);
			$numbers = $numbers.add($number_element);
			$navInner.append($number_element);
			
			//get the most-inner element of the navContainer
			var $num_inner = $number_element.add($number_element.find('*')).last();
			
			$number_element.attr('data-index', i);
			$num_inner.text(i+1);
			
			$number_element.click(function(){
				fader.goToItem($(this).attr('data-index'));
			})
			i++;
		});
		
		$inner.css({
			'width' : itemsWidth+100,
			'position' : 'relative'
		}).append('<div style="clear:both"></div>');
		
		$outer.css({
			'width' : '100%',
			'height' : '100%',
			'overflow' : 'hidden'
		});
		
		
		
		$this.prepend(
			$navPrev = $(opts.navPrev).click(function(e){
				if(fader.navPrevHandler == undefined){
					fader.fadeToPrev();
				} else {
					fader.navPrevHandler(fader, e);
				}
			})
		);
		
		$this.append(
			$navNext = $(opts.navNext).click(function(e){
				if(fader.navNextHandler == undefined){
					fader.fadeToNext();
				} else {
					fader.navNextHandler(fader, e);
				}
			})
		);
		
		//initial index
		$(this.items).animate({ opacity: 0 }, 0);
		this.goToItem(this.defaultIndex, 0);
		
		return this;
	}
	
	$.fn.fader.defaults = {
		speed: 500,
		autoFade: false,
		autoFadeDelay: 5000,
		autoFadeInitialDelay: 8000,
		defaultIndex: 0,
		currentIndex: undefined,
		continuous: false,
		navContainer: '<div class="nav_container"></div>',
		navNumber: '<div class="nav_number"><a href="javascript:"></a></div>',
		navPrev: '<div class="nav_prev"><a href="javascript:">&lt;</a></div>',
		navNext: '<div class="nav_next"><a href="javascript:">&gt;</a></div>',
		navPrevHandler: undefined,
		navNextHandler: undefined
	};
	 
})(jQuery);
