/* little fade slideshow */
(function($) {
	$.fn.milestoneSlide = function(options)
	{
		var options = $.extend({
				delay: 4000,
				autoStart: true,
				disableAnimation: false
			}, options);

		function setArrowsVisibility(position, max, arrows)
		{
			if (position == (max - 1))
			{
				arrows[0].show();
				arrows[1].hide();
			}
			else if (position == 0)
			{
				arrows[0].hide();
				arrows[1].show();
			}
			else
			{
				arrows[0].show();
				arrows[1].show();
			}	
		}

		function setVisiblePicture(previousPic, currentPic)
		{
			previousPic.addClass('hidden');
			currentPic.removeClass('hidden');
					
			// some *VERY* outdated do not support opacity so jQuery will take care of them
			if (!options.opacity)
			{
				previousPic.fadeOut('fast');
				currentPic.fadeIn('fast');
			}
		}

		function setControlItem(source, selectedIndex)
		{
			source.parent().find('.controls .selected').removeClass('selected');
			source.parent().find('.controls span').eq(selectedIndex).addClass('selected');
		}

		// changes selected slide, updated control arrows and control items
		function advance(direction, andStop, direct)
		{
			var data = $(this).data(),
				self = this,
				previous = -15,
				contents = data.fromElement.children('.content');
		
			// be sure to stop timeout
			clearTimeout(data.timeout);

			if (andStop)
				data.playing = false;

			previous = data.currentPosition;

			if (direct == true)
				data.currentPosition = direction;
			else
				data.currentPosition += direction;
			
			if (data.currentPosition >= data.numElements)
				data.currentPosition = 0;
			else if (data.currentPosition < 0)
				data.currentPosition = data.numElements - 1;

			setArrowsVisibility(data.currentPosition, data.numElements, [$(this).parent().find('.slidePrev'), $(this).parent().find('.slideNext')]);

			setVisiblePicture(contents.eq(previous), contents.eq(data.currentPosition));

			setControlItem($(this), data.currentPosition);

			$(this).data(data);
		}	

		function addNavigation(num, startPos, dest)
		{
			var $controls = $('<div class="controls"/>');
			for (var i = 0; i < num; i++) {
				$('<span class="goto"/>').appendTo($controls).css({cursor:'pointer'}).bind(CM.MOUSEUP, 
					(function(i) {
						return function() { advance.apply($(this).data('from'), [i, false, true]); return false; };
					})(i)).data({from: dest});
			}

			$controls.find('span:eq(' + startPos + ')').addClass('selected');

			$controls.appendTo(dest.parent());
		}

		function addKBNavigation(numElements, dest)
		{
			var data = $(dest).data();

			$(document).keyup(function(event)
			{
				if (event.keyCode == 37 && data.currentPosition > 0)
					advance.apply($(dest), [-1, false, false]);
				else if (event.keyCode == 39 && data.currentPosition < (numElements -1))
					advance.apply($(dest), [1, false, false]);
			});
		}

		function addArrows(height, dest)
		{
			$('<a class="slideNext"/>').attr({
				href: '#',
				title: 'go to next picture'
			}).bind(CM.MOUSEUP, function()
			{
				advance.apply($(this).data('from'), [1, false, false]);
				return false;
			}).append('&nbsp;').appendTo(dest.parent()).data({from: dest});

			$('<a class="slidePrev"/>').attr({
				href: '#',
				title: 'go to previous picture'
			}).bind(CM.MOUSEUP, function()
			{
				advance.apply($(this).data('from'), [-1, false, false]);
				return false;
			}).append('&nbsp;').appendTo(dest.parent()).data({from: dest});
		}

		return this.each(function()
		{
			var sliderContainerWidth = $(this).parent().width(),
			numElements = 0,
			self = $(this),
			zIndex = 8;

			// set position/visibility of all slides
			$(this).children('.content').each(function(i)
			{
				$(this).bind('milestoneSlide.stop', function()
				{
					clearTimeout($(this).data('timeout'));
					$(this).data('playing', false);
				});

				$(this).css({position: 'absolute', top: '0', left: '0', right: '0', width: '100%', zIndex: zIndex--});

				numElements++;
			});
			
			// add navigation items if we have more than one element
			if (numElements > 1)
			{
				addArrows($(this).parent().height(), $(this));
				$(this).parent().find('.slidePrev').hide();
				addNavigation(numElements, 0, $(this));
				addKBNavigation(numElements, $(this));
			}

			/*
			if (Modernizr.touch == true) {
				// add swipe events for touch devices
				var self = this;

				$(this).touchwipe({
					wipeRight:function() { advance.apply(self, [-1, false]); },
					wipeLeft:function() { advance.apply(self, [1, false]); },
					min_move_x: 20,
					min_move_y: 5,
					preventDefaultEvents: false
				});
			}
			*/

			// save some data for later use
			$(this).data({
				numElements: numElements,
				currentPosition: 0,
				width: sliderContainerWidth,
				fromElement: $(this),
				playing: options.autoStart
			});

			if (options.autoStart)
				$(this).data('timeout', setTimeout(function() { advance.apply(self, [1, false, false]); }, options.delay));
		});
	}
})(jQuery);
