/**
 * Your typical slider object
 * @author Empire Creative
 * @version 1.1
 */
(function($){
	$.fn.empcSlider = function( settings ) {

		var defaults = {
			transition		: 'fade', // instant, fade
			easing			: 'swing', // linear
			direction		: 'horizontal', // verticle
			speed			: 500,
			auto			: true,
			interval		: 8000,
			hoverPause		: true,
			navigation		: false,
			buttons			: false,
			prevText		: 'Prev',
			nextText		: 'Next',
			loop			: true
		};

		settings = $.extend({}, defaults, settings); 

		$(this).each( function() {
			var $this = $(this),
			$frames,
			$wrapper,
			$boundary,
			$container,
			$prev,
			$next,
			$navigation,
			boundaryWidth,
			boundaryHeight,
			frameWidth,
			frameHeight,
			frameCount,
			currentFrame = 1,
			auto,

			_init = function( ) {		
				$wrapper		= $this.wrap('<div />').parent().addClass('empc-slider-wrap');
				$boundary		= $this.wrap('<div />').parent().addClass('empc-slider-bound');
				$container		= $this.addClass('empc-slider-cont');

				$frames			= $this.children().addClass('empc-slider-slide').children().fadeIn(1);
				frameCount		= $frames.length;
				frameWidth		= 0;
				frameHeight		= 0;
				boundaryWidth	= 0;
				boundaryHeight	= 0;
				if( settings.buttons ) {
					$prev		= $('<a />').addClass('empc-slider-prev').text(settings.prevText)
									.click( function(e){ 
										e.preventDefault()

										if( !$this.hasClass('disabled') ) {
											_transition( currentFrame - 1 );
										}
									 });

					$next		= $('<a />').addClass('empc-slider-next').text(settings.nextText)
									.click( function(e){
										e.preventDefault();

										if(!$this.hasClass('disabled')) {
											_transition(currentFrame + 1);
										}
									});

					$wrapper.prepend($prev).append($next);
				}

				if( settings.navigation ) {
					$navigation = $('<ol />').addClass('empc-slider-nav');

					$frames.each(function(i, frame) {
						var $tab = $('<li />')
										.addClass('empc-slider-tab').append('<span />').find('span').addClass('number').text(i + 1).end()
										.click(function(e) {
											e.preventDefault();

											if( (i+1) != currentFrame ) {
												_transition(i+1);
											}
										});

						if( i == 0 ) {
							$tab.addClass('current');
						}

						if( $(frame).attr('title') ) {
							$('<span />').addClass('title').text($(frame).attr('title')).appendTo($tab)
						}

						$navigation.append($tab);
					});

					$wrapper.append($navigation);
				}

				$frames.each(function() {
					if($(this).width() > frameWidth) frameWidth = $(this).width(); // Get widest frame's width
					if($(this).height() > frameHeight) frameHeight = $(this).height(); // Get tallest frame's height

					if($(this).outerWidth(true) > boundaryWidth) boundaryWidth = $(this).outerWidth(true); // Get widest frame's outer width
					if($(this).outerHeight(true) > boundaryHeight) boundaryHeight = $(this).outerHeight(true); // Get tallest frame's outer height
				});

				// Set dimensions on elements that need sizing
				$frames.css({
					width	: frameWidth,
					height	: frameHeight,
					float	: 'left'
				});

				if( settings.transition == 'slide' ) {
					if( settings.direction == 'horizontal' ) {
						$container.css({
							width	: boundaryWidth * frameCount,
							height	: boundaryHeight,
							overflow: 'hidden'
						});
					}else{
						$container.css({
							width	: boundaryWidth,
							height	: boundaryHeight * frameCount,
							overflow: 'hidden'
						});
					}
				}else{
					$container.css({
						position: 'relative',
						width	: boundaryWidth,
						height	: boundaryHeight
					});

					$frames.css({
						position: 'absolute',
						left	: 0,
						top		: 0
					}).hide();

					$frames.eq(0).show();
				}

				$boundary.css({
					width	: boundaryWidth,
					height	: boundaryHeight,
					overflow: 'hidden'
				});

				if( settings.auto ) {
					_startTimer(settings.interval);

					if( settings.hoverPause ) {
						$wrapper.hover( function() {
							_stopTimer();
						}, function() {
							_startTimer();
						});
					}
				}
			},

			_transition = function( toFrame ) {
				if( settings.loop ) {
					if( toFrame > frameCount ) {
						_transition(1);
						return;
					}else{
						if( toFrame <= 0 ) {
							_transition(frameCount);
							return;
						}
					}
				}else{
					if( toFrame > frameCount || toFrame <= 0 ) 
						return;
				}

				switch(settings.transition) {
					case 'slide':
						var diff = toFrame - currentFrame;
						_slide(diff);
						break;

					case 'fade':
						_fade(toFrame);
						break;

					default:
						_cut(toFrame);
						break;
				}

				currentFrame = toFrame;

				/*
					TODO get the button disabling / enabling and looping to work
				*/
				if( !settings.loop && settings.buttons ) {
					if(currentFrame == 1) {
						$prev.addClass('disabled');
					}else{
						$prev.removeClass('disabled');
					}

					if(currentFrame == frameCount) {
						$next.addClass('disabled');
					}else{
						$next.removeClass('disabled');;
					}
				}

				if( settings.navigation ) {
					$navigation.children().removeClass('current').eq(currentFrame - 1).addClass('current');	
				}

			},

			_slide = function( frames ) {
				if(settings.direction == 'horizontal') {
					$this.stop().animate({
						marginLeft: (-1) * (currentFrame + frames - 1) * boundaryWidth + 'px'
					}, settings.speed, settings.easing);
				}else{
					if(settings.direction == 'vertical') {
						$this.stop().animate({
							marginTop: (-1) * (currentFrame + frames - 1) * boundaryHeight + 'px'
						}, settings.speed, settings.easing);
					}
				}
			},

			_fade = function( toFrame ) {
				$frames.eq(toFrame - 1).fadeIn(settings.speed);
				$frames.eq(currentFrame - 1).fadeOut(settings.speed);
			},

			_cut = function( toFrame ) {
				$frames.eq(toFrame - 1).show();	
				$frames.eq(currentFrame - 1).hide();		
			},

			_startTimer = function( ) {
				auto = setInterval( function() {
					_transition(currentFrame + 1);
				}, settings.interval);
			},

			_stopTimer = function( ) {
				if( settings.auto !== false ){
					clearInterval(auto);
				}
			}

			_init();
		});
	}
})(jQuery);
