(function($){
	var num = function(el, props) {
		var r = 0;
		$.each(props.split(/\s+/) || [], function(i,v){
			r += parseInt($(el).css(v)) || 0;
		});
		return r;
	}
	
	
	$.fn.jcarousel = function(options){
		var isMethodCall = (typeof options == "string"),
			args = Array.prototype.slice.call(arguments, 1);
			
		return this.each(function() {
			var instance = $(this).data("jcarousel");
			if (isMethodCall && instance && $.isFunction(instance[options])) {
				instance[options].apply(instance, args);
			} else if (!instance) {
				$(this).data("jcarousel", new $.jcarousel(this, options));
			}
		});
	};
	
	$.jcarousel = function(element, options) {
		this.element = $(element);
		this.options = $.extend(true, {},$.jcarousel.defaults, options);
		this.init();
	};
	
	$.extend($.jcarousel.prototype, {
		init: function() {
			this.items = this.element.children();
			this.parent = this.element.parent();
			
			this.parent.append(
				'<div class="jcarousel-skin-tango">' +
					'<div class="jcarousel-container jcarousel-container-horizontal">' +
					'<div class="jcarousel-prev jcarousel-prev-horizontal"></div>' +
					'<div class="jcarousel-next jcarousel-next-horizontal"></div>' +
					'<div class="jcarousel-clip jcarousel-clip-horizontal">');
					
			this.carousel = $(".jcarousel-skin-tango", this.parent);
			this.carouselContainer = $(".jcarousel-container", this.carousel);
			this.carouselNext = $(".jcarousel-next", this.carousel),
			this.carouselPrev = $(".jcarousel-prev", this.carousel);
			this.carouselClipper = $(".jcarousel-clip", this.carousel);
			
			this.carouselClipper.append(this.element.addClass("jcarousel-list jcarousel-list-horizontal"));
			this.items.addClass("jcarousel-item jcarousel-item-horizontal");
			
			this.initPages();
			this.initNav();
		},
		
		initPages: function() {
			var usedW, spaceL, spaceR, maxW, totalW, fromI, toI, count, pix;
			
			maxW = this.clipperWidth = this.carouselClipper.width();
			this.clipperHeight = this.carouselClipper.height();
			
			usedW = spaceL = spaceR = totalW = fromI = toI = count = 0;
			
			var initGridsGroup = function(items) {
				count = toI - fromI + 1;
				spaceL = Math.floor( (maxW - usedW) / count );
				pix = maxW - (spaceL * count);
				
				spaceR = spaceL - Math.floor(spaceL / 2);
				spaceL = Math.floor(spaceL / 2);
				
				for (var j = fromI; j <= toI; j++) {
					var mr = num(items[j], "marginRight"),
						ml = num(items[j], "marginLeft");
					
					mr += spaceR;
					ml += spaceL;
					
					if (pix > 0) {
						ml += 1;
						pix--;
					} else if (pix < 0) {
						ml -= 1;
						pix++;
					}
					
					$(items[j]).css({
						marginLeft: ml,
						marginRight: mr
					});
				}
			}
			
			this.pagesCount = 0;
			
			for (var i = 0; i < this.items.length; i++ ) {
				var item = $(this.items[i]),
					w = item.outerWidth(true);
					
				if ( (usedW + w) > maxW ) {
					initGridsGroup(this.items);
					usedW = count = 0;
					fromI = toI = i;
					this.pagesCount++;
				}
				
				usedW += w;
				toI = i;
				count++;
			}
			
			if (usedW > 0) {
				initGridsGroup(this.items);
				this.pagesCount++;
			}
			
			this.element.css("width", this.pagesCount * maxW);
			
			w = 0;
			this.items.each(function(){
				w+= $(this).outerWidth(true);
			});
			
			this.element.css("width", w);
			
			this.currentPage = -1;
			this.moveTo(0);
			
			this.setInterval();
		},
		
		initNav: function() {
			this.carouselNext.bind("click", $.proxy(this.moveNext, this));
			this.carouselPrev.bind("click", $.proxy(this.movePrev, this));
		},
		
		moveTo: function(page, animate) {
			var anim = typeof animate === "undefined" ? true : animate,
				left = 0;
				
			if (page < 0) {
				page = 0;
			}  else if ( page > this.pagesCount-1 ) {
				//page = this.pagesCount - 1;
				page = 0;
			}
			
			if (page === this.currentPage) {
				return;
			}
				
			left = page * this.clipperWidth;
			
			if (anim) {
				this.element.stop().animate({left: -left}, {queue: false, duration: 1200, easing: "easeOutExpo"});
			} else {
				this.element.css("left", -left);
			}
			
			this.currentPage = page;
			
			if (this.pagesCount > 1) {
				if (this.currentPage > 0) {
					this.carouselPrev.show();
				} else {
					this.carouselPrev.hide();
				}
				
				if (this.currentPage <= this.pagesCount-1) {
					this.carouselNext.show();
				} else {
					this.carouselNext.hide();
				}
			} else {
				this.carouselNext.hide();
				this.carouselPrev.hide();
			}
			
		},
		
		moveNext: function(event) {
			this.moveTo(this.currentPage+1);
			(event && event.preventDefault());
		},
		
		movePrev: function(event) {
			this.moveTo(this.currentPage-1);
			(event && event.preventDefault());
		},
		
		setInterval: function() {
			var self = this;
			window.setInterval(function() {
				self.moveNext();
			}, 4200);
		}
	});
})(jQuery);
