/**
 * 
 */

(function($) {
	$.fn.carousel = function(o) {
		o = $.extend({
			k: 0,
	        prevBtn: 'prev',
	        nextBtn: 'next',
			btnGo: null,
			mouseWheel: true,
			auto: null,

	        vertical: false,
	        circular: true,
			
			speed: 500,
			easing: null,

			visible: 3,
			start: 0,
			scroll: 1,
			
			afterLoad: null,
			beforeStart: null,
	        afterEnd: null,
	        
	        pagination: true,
	        generatePagination: false,
	        paginationClass: 'pagination'
			
		}, o || {});
	
		return this.each(function(){
			
			if (o.k < 0) o.k = 0;
			
			var run = false,
				wrap = $(this),
				list = wrap.find('ul:first'),
				items = list.find('li').each(function(index){
					$(this).attr('num', index);
				}),
				itemsTotal = items.size(),
				itemWidth = items.outerWidth(true),
				current = o.start,
				animateInterval = null;
			
			list.css({
				'width': itemWidth*(o.visible+o.scroll*2+o.k*2)+'px',
				'position': 'relative',
				'left': -(itemWidth*(o.scroll+o.k))+'px',
				'overflow': 'hidden'
			});
			list.html(getSlice(current));
			if (o.pagination) {
				if (o.generatePagination) {
					wrap.append('<ul class="'+o.paginationClass+'"></ul>');
					var pagination = $('.'+o.paginationClass, wrap);
					items.each(function(index){
						pagination.append('<li><a href="#" rel="'+index+'">'+(index+1)+'</a></li>');
					});
				} else {
					var pagination = $('.'+o.paginationClass, wrap);
				}
				currentSlide();
				var paginationLi = pagination.find('li');
				pagination.width(paginationLi.outerWidth(true)*paginationLi.size());
				$('.'+o.paginationClass+' a').click(function(){
					return go(0, $(this).attr('rel'));
				});
				$('.'+o.paginationClass+' a').hover(
					function(){$(this).addClass('hover');},
					function(){$(this).removeClass('hover');}
				);
			}
			if(o.afterLoad)o.afterLoad.call(this,list.find('li'));

			if (o.auto) {
				startAnimation();
				wrap.hover(
						function(){
							pauseAnimation();
						},
						function(){
							startAnimation();
						}
					);
			}
			
			$('.'+o.nextBtn, $(this)).click(function(){return go(false);});
			$('.'+o.prevBtn, $(this)).click(function(){return go(true);});
			
			function go(direction, num) {
				var scroll = o.scroll;
				if (direction === 0) {
					(current < num) ? direction = -1 : direction = 1;
					scroll = Math.abs(num-current);
					if (scroll > o.scroll) {
						(current < num)
							? q = getSlice(current, parseInt(num) + o.visible)
							: q = getSlice(num, current+ o.visible);
					} else {
						var q = getSlice(current);
					}
					list.css('width', itemWidth*$(q).size()+'px');
					list.html(q);
					if (scroll > o.scroll)
						if (direction === 1) 
							list.css('left', -(itemWidth*(current-num+1+o.k))+'px');
				} else
					direction = !direction ? -1 : 1;
				animate(direction, scroll);
				return false;
			}
			
			function animate(d, s) {
				if (!run) {
					if(o.beforeStart)
						o.beforeStart.call(this, list.find('li'));
					run = true;
					if (d === undefined) d = -1;
					if (s === undefined) s = o.scroll;
					var leftIndent = parseInt(list.css('left')) + itemWidth * s * d + 'px';
					list.animate({'left': leftIndent}, {queue: false, duration: o.speed, complete: function() {
						current = current - s * d;
						if (current >= itemsTotal) current -= itemsTotal;
						if (current < 0) current+=itemsTotal;
						list.css('left', -(itemWidth*(o.scroll+o.k))+'px').html(getSlice(current));
						if(o.afterEnd)o.afterEnd.call(this,list.find('li'));
						currentSlide();
						run = false;
					}});
				}
				return false;
			}
			
			if(o.mouseWheel && $(this).mousewheel)
				$(this).mousewheel(function(e, d) {
	                return d>0 ? go(true) : go(false);
	            });
			/**
			 * Получаем срез элементов
			 * start - первый элемент выборки
			 * num - количество элементов выборки
			 */
			function getSlice(start, num) {
				if (num === undefined)
					num = o.visible;
				start -= o.scroll+o.k;
				var end = parseInt(num + start + o.scroll*2+o.k*2);
				while (Math.abs(start) > itemsTotal) {
					if (start < 0) {
						start+=itemsTotal;
						end+=itemsTotal
					} else {
						start-=itemsTotal;
						end-=itemsTotal;
					}
				}
				var q1 = new Array();
				if (start < 0) {
					q1 = $.merge(q1, items.slice(start).clone());
					start = 0;
				}
				while (end > itemsTotal) {
					q1 = $.merge(q1, items.slice(start, end).clone());
					end -= itemsTotal;
					start=0;
				}
				q1 = $.merge(q1, items.slice(start, end).clone());
				return q1;
			}
			function currentSlide(num) {
				if (o.pagination) {
					if (num === undefined) {num = current;}
						pagination.find('a').removeClass('current');
						pagination.find('a[rel="'+num+'"]').addClass('current');
				}
				return false;
			}
			function startAnimation() {
				animateInterval = setInterval(function() {
	                go(false);
	            }, o.auto+o.speed);
			}
			function pauseAnimation() {
				clearInterval(animateInterval);
			}
		});
	}
})(jQuery);
