(function($) {
	
	$.fn.carousel = function(options) {
	
		var defaults = {
	    	numberVisible : 1,
	    	type : 'back_forward',
	    	controlPosition: 'after'
	  	};
	  	
  		// Extend our default options with those provided.
  		var o = $.extend(defaults, options);
				
		return $.each( this, function() {
		
			var elements = $(this).children();
			var elemWidth = elements.width();
			var elemHeight = elements.height();
		
			var source = $(this);
			var id = source.attr('id');
			var height = source.height();
			var width = source.width();
			
			// Inject Carousel Mark-up
			$(this).after('<div id="'+ id +'"><div class="carousel_content"><div><ul></ul></div></div></div>');
			
			// Remove original content
			$(this).remove();
			
			var content = $('#' + id + ' .carousel_content');
			
			switch(o.type) {
				
				case 'paging' :
					// Inject page controls
					var noPages = Math.ceil( elements.length / o.numberVisible );
					
					// Set width of content to maximum
					content.height(height).width(width);
					
					if ( noPages > 1) {
						
						var ctrlString = '<div class="carousel_pages"><a class="back" href="#">&laquo;</a>&nbsp;';
						
						for(var i=1; i<=noPages; i++ ) {
							ctrlString += '<a class="page_click" rel="'+ i +'" href="#">'+ i +'</a>&nbsp;';
						}
						
						ctrlString += '<a class="forward" href="#">&raquo;</a></div>';
						
						if ( o.controlPosition == 'after' ) {
							$('#' + id + ' .carousel_content').after(ctrlString);
						}
						
						if ( o.controlPosition == 'before' ) {
							$('#' + id + ' .carousel_content').before(ctrlString);
						}
						
						if ( o.controlPosition == 'both' ) {
							$('#' + id + ' .carousel_content').after(ctrlString);
							$('#' + id + ' .carousel_content').before(ctrlString);
						}
						
						// Grab ze buttons
						var backBtn = $('#' + id + ' .carousel_pages .back');
						var fwdBtn = $('#' + id + ' .carousel_pages .forward');
						var classBtns = $('#' + id + ' .carousel_pages .page_click');
						
						// Set-up Button functionality
						var ptr = 1;
						
						var checkBtns = function() {							
							if ( ptr > 1 ) {
								$(backBtn).removeClass('disabled', 0);
							} else {
								$(backBtn).addClass('disabled', 0);
							}
							
							if ( ptr < noPages ) {
								$(fwdBtn).removeClass('disabled', 0);
							} else {
								$(fwdBtn).addClass('disabled', 0);
							}
							
							$.each( $('#' + id + ' .carousel_pages a'), function() {
								var thisId = $(this).attr('rel');
								
								if ( thisId == ptr ) {
									$(this).addClass('current', 0);
								} else {
									$(this).removeClass('current', 0);
								}
								
							});
						}
						
						function move() {
							
							slide.stop().animate({'left' : ( ( -elemWidth * Math.ceil( ( elements.length /  noPages ) ) ) ) * (ptr - 1) }, 200);
							
						}
						
						backBtn.click(function(e){
							
							if ( ptr > 1 ) {
								ptr--;			
								
								move();
								
								checkBtns();
								
								e.preventDefault();
							}
							
						});
						
						fwdBtn.click(function(e){
							
							if ( ptr < noPages ) {
								ptr++;
								
								move();
								
								checkBtns();
								
								e.preventDefault();
								
							}
							
						});
						
						classBtns.click(function(e){
							
							ptr = $(e.currentTarget).attr('rel');
							
							move();
								
							checkBtns();
							
							e.preventDefault();
							
						});
						
						checkBtns();
					}
				break;
				
				case 'back_forward' :
				default:
					// Inject Back Button
					$('#' + id + ' .carousel_content').before('<div class="back" class="button"></div>');
					var backBtn = $('#' + id + ' .back');
					backBtn.height(height).width('5%');
				
					// Inject Forward Button
					$('#' + id + ' .carousel_content').after('<div class="forward" class="button"></div>');
					var fwdBtn = $('#' + id + ' .forward');
					fwdBtn.height(height).width('5%');
				
					// Reduce width of content to accomadate back and forward buttons
					content.height(height).width('90%');
					
					// Set-up Button functionality						
					var ptr = 0;
					
					var checkBtns = function() {						
						if ( ptr > 0 ) {
							backBtn.removeClass('disabled');
						} else {
							backBtn.addClass('disabled', 0);
						}
						
						if ( ptr < ( elements.length - o.numberVisible )) {
							fwdBtn.removeClass('disabled');
						} else {
							fwdBtn.addClass('disabled', 0);
						}
					}
					
					backBtn.mouseover(function() { $(this).addClass('active'); }).mouseout(function() { $(this).removeClass('active') });
					
					backBtn.click(function(e){
						if ( ptr > 0 ) {
							ptr--;				
							
							slide.stop().animate({'left' : -elemWidth * ptr }, 200);
							
							checkBtns();
						}
						
					});
					
					fwdBtn.mouseover(function() { $(this).addClass('active'); }).mouseout(function() { $(this).removeClass('active') });
					
					fwdBtn.click(function(e){
						
						if ( ptr < ( elements.length - o.numberVisible )) {
							ptr++;
							
							slide.stop().animate({'left' : -elemWidth * ptr }, 200);
							
							checkBtns();
						}
						
					});
					
					checkBtns();
				break;
			}
			
			// Format Injected Content
			
			var aperture = content.children('div');
			aperture.height(elemHeight).width(elemWidth).css({
														'overflow' : 'hidden', 
														'position' : 'relative'
													});
			
			var slide = aperture.children('ul');
			slide.height(elemHeight).width(elemWidth * elements.length).css({ 
																'position' : 'absolute',
																'left' : 0
																});
			
			// Inject Elements into Carousel
			$.each(elements, function() {
				
				slide.append('<li>' + $(this).html() + '</li>');
				
			});
			
			var slides = slide.children('li')
			
			for ( i = 0; i < slides.length; i++ ) {
				$(slides[i]).width(elemWidth).css({
					'display' : 'inline-block',
					'position' : 'absolute',
					'top' : 0,
					'left' : i * elemWidth
				});
			}
		});
		
	};

})(jQuery);
