(function($) {
	$.fn.slipstream = function (options) {
		return this.each(function (i) {
			// select our list
			var imageList = $(this);
			
			// get/set the properties for our slideshow
			var imageProps = {
				 'height': imageList.find('img').height() + 30
				,'width': imageList.find('img').width() + 50
				,'count': imageList.find('li').size()
				,'listClass': imageList.attr('class')
				,'unique': 'ul_slipstream_' + i
			};
			
			// define some slideshow control variables
			controlVars = $.extend({}, $.fn.slipstream.defaults, options);
	
			// define our default CSS rules
			var containerCSS = {
				 'width': imageProps.width
				//,height: imageProps.height
				,'position': 'relative'
			};
			var viewportCSS = {
				 'width': imageProps.width
				//,height: imageProps.height
				,'position': 'relative'
				,'overflow': 'hidden'
			};
			var controlsCSS = {
				 'position': 'absolute'
				,'height': imageProps.height
				,'width': imageProps.width
				,'top': 0
			};
			var controlLinkCSS = {
				 'display': 'block'
				,'float': 'left'
				,'width': (imageProps.width/2)
				,'height': imageProps.height
				,'textIndent': '-9999em'
				,'outline': 'none'
			};
			var imageListCSS = {
				 'listStyle': 'none'
				,'margin': '0'
				,'padding': '0'
				,'left': '0'
				,'clear': 'both'
				,'display': 'block'
				,'position': 'relative'
				,'width': (imageProps.width * imageProps.count)
				//,height: imageProps.height
			};
			var imageListItemCSS = {
				 'display': 'block'
				,'float': 'left'
				,'width': imageProps.width
				//,height: imageProps.height
			};
	
			// define our container
			var container = $('<div class="slipstreamObject">').addClass(imageProps.listClass);
			// define our viewport
			var viewport = $('<div class="slipstreamViewport">');
			// define our controls
			var controls = $('<div class="controls clearfix"><a class="prev CM_pngFix" title="View Previous Image" href="">Previous Image</a><a class="next CM_pngFix" title="View Next Image" href="">Next Image</a>');
			$('a', controls).attr('rel', imageProps.unique);
			
			// append our viewport and controls to our container
			viewport.appendTo(container);
			controls.appendTo(container);
			
			// apply the css to our items
			controls.css(controlsCSS);
			$('a', controls).css(controlLinkCSS);
			container.css(containerCSS);
			viewport.css(viewportCSS);
			imageList.attr('id', imageProps.unique).css(imageListCSS);
			$('li', imageList).css(imageListItemCSS);
			
			// wrap the image list with the viewport div
			imageList.wrap(container);
			
			// set some assorted slide control vars
			isChanging = false;

			// binding makes the magic happen...
			$('.slipstreamObject .controls a').bind('click', $.fn.slipstream.slide);
		});
	};

	// the actual sliding function
	$.fn.slipstream.slide = function (e) {
		// make sure to only move the appropriate list (in case there are multiples)
		var target = $('#'+$(this).attr('rel'));
		var slipper = target.find('li');
		controlVars.origSpeed = $.fn.slipstream.defaults.speed;
		// size controls...
		var width = slipper.width();
		var count = slipper.size();
		var maxOffset = -(width * (count - 1));
		// previous or next?
		var action = jQuery(this).attr('class');
		// where are we in the photostream?
		var currOffset = parseInt(target.css('left'));
		// if we're going to a previous image...
		if (action.match('prev')) {offset = currOffset + width;}
		// else, if we're going to the next image...
		else {offset = currOffset - width;}
		// if we try to go to the previous image from the first, go to the end (as quick as possible)
		if (offset > 0){offset = maxOffset; controlVars.speed = 0;}
		// if we try to go to the next image from the last, go to the beginning (as quick as possible)
		else if (offset < maxOffset){offset = 0; controlVars.speed = 0;}
		// make sure we didn't somehow get stuck 'between' two pictures (fast user clicking *may* cause this)
		var change = (offset/width);
		if (change != Math.round(change)){offset = Math.round(change)*width;}
		// now, move our photostream
		if (!isChanging){
			isChanging = true;
			target.animate({left:offset}, controlVars.speed, controlVars.easing, function() {isChanging = false;});
			controlVars.speed = controlVars.origSpeed;
		}
		e.preventDefault();
	};

	// default options
	$.fn.slipstream.defaults = {
		 speed: 750
		,easing: 'swing'
	};
})(jQuery);
