sk.widgets.Carousel = function (element, options){
	
	this.$element = $(element);
	this.options = $.extend({
		item: 'li', // elementy ktere se budou scrollovat
		visible: 2, // počet viditelných elementů
		animation: 500, // čas za který se provede animace kroku
		boxClass: 'carousel-box', 
		spcClass: 'carousel-spc',
		clipClass: 'carousel-clip',	
		axis: 'x', // x, y
		htmlPager: '.pager',
		pause: false,   
		repeat: false, // opakovat
		pauseOnHover: '',
		pagerPages: true,
		pagerMask: '', // {$active} = aktivní položka, {$all} = celkový počet
		timeout: 5000,
		auto: true
	}, options);
	
	this.paused = false;
	this.$items = this.$element.find(this.options .item);
	this.length = this.$items.length;
	this.visible = this.options.visible;
	this.end = this.length - this.visible;
	this.animate = false;
	this.current = 0;
	this.axProps = this.options.axis == 'x' ? 
		{
			left: 'left',
			width: 'width',
			outerWidth: 'outerWidth',
			scrollWidth: 'scrollWidth',
			scrollLeft: 'scrollLeft',
			offset: 'offsetLeft'
		} :
		{
			left: 'top',
			width: 'height',
			outerWidth: 'outerHeight',
			scrollWidth: 'scrollHeight',
			scrollLeft: 'scrollTop',
			offset: 'offsetTop'
		};

};

sk.widgets.Carousel.prototype = {
	
	constructor: sk.widgets.Carousel,
	
	// reference na jquery proxy
	proxy : $.proxy,
	
	// reference na globální objekt Math
	abs: Math.abs,
		
	init: function() {
		if(this.$element.data('carouselInit') || !this.$element.length || !this.end)
		{
			return this;
		}
		
		var o = this.options,
			e = this.$element;
			
		// repeat init
		if(o.repeat){
			this.$items
				.slice(0, this.visible)
				.clone()
				.addClass('clone')
				.appendTo(this.$element);
			
			this.$items
				.slice(this.length-this.visible, this.length)
				.clone()
				.addClass('clone')
				.prependTo(this.$element);
				
			this.$items = this.$element.find(this.options .item);
			this.current = this.current+this.visible;
		}
		
		
		
		// vypočítání pozic elementů - nemusí se pořád dokola zjišťovat
		this.offsets = [];
		for (var i=0, l=this.$items.length; i < l; i++) {
			this.offsets[i] = this.$items.get(i)[this.axProps.offset];
		};
	
		e
			.wrap('<div class="'+ o.boxClass +'"><div class="'+ o.spcClass +'"><div class="'+ o.clipClass +'"></div></div></div>')
			[this.axProps.width](e.attr(this.axProps.scrollWidth))
			[this.axProps.scrollLeft](0)
			.css({'overflow':'visible', 'position':'relative'})
			.css(this.axProps.left, -this.offsets[this.current]+'px')
			.data('carouselInit', true);
			
		this.$box = e.closest('.' + o.boxClass);
		this.$spc = e.closest('.' + o.spcClass);
		this.$clip = e.closest('.' + o.clipClass);
		this.$pager = $(o.htmlPager);
		
		
		if(this.end && this.$pager.length){
			var pager = [];
			// prev
			pager.push('<a href="#" class="btn-prev"></a>');
			// page
			if(o.pagerPages && !o.pagerMaks){
				pager.push('<span class="pages">');
				for (var i=0, l=Math.ceil(this.length/this.visible); i < l; i++) {
					pager.push('<a href="#" class="page">'+ (i+1) +'</a>');
				};
				pager.push('</span>');
			}
			else if(o.pagerMask){
				pager.push('<span class="pages"></span>');	
			}
			// next
			pager.push('<a href="#" class="btn-next"></a>');
			
			// pause
			o.pause && pager.push('<a href="#" class="control"></a>');
			
			// create pager
			this.$pager
				.append(pager.join(' '))
				.delegate('.control', 'click', this.proxy(this.control, this))
				.delegate('.page', 'click', this.proxy(this.page, this))
				.delegate('.btn-prev', 'click', this.proxy(this.prev, this))
				.delegate('.btn-next', 'click', this.proxy(this.next, this));
			
            // počáteční nastavení	
			(o.pagerPages && !o.pagerMaks) && this.getPage();
			(o.pagerMask) && this.getPages();    
			
			(!o.repeat) && this.controlPrev();
			(!o.repeat) &&this.controlNext();
			
			this.getControl();
		}
		
		if(o.pauseOnHover){
            $(document)
                .delegate(o.pauseOnHover, 'mouseenter', this.proxy(function(){
                       this.clearInterval();
                       this.paused = true;
                       this.getControl();
                }, this))
                .delegate(o.pauseOnHover, 'mouseleave', this.proxy(function(){
                       this.resetInterval();
                       this.paused = false;
                       this.getControl();
                }, this));
        }
		
		this.resetInterval();
		return this;
	},
	// metoda pro zjištění zda je daný element plně vidět ve výřezu
	isVisible: function(i){
		var cW = this.$clip[this.axProps.width](),
			cOff = this.offsets[this.current],
			iW = this.$items.eq(i)[this.axProps.outerWidth](),
			iOff = this.offsets[i];	
		
		return (cOff <= iOff && (cW+cOff) >= (iW + iOff));
	},
	getVisible: function(){
		var count = 0;
		
		for(var i = 0, l = this.$items.length; i < l; i++){
			this.isVisible(i) && count++;	
		}
		
		return count;
	},
	interval: function()
	{
		this.next();
	},
	clearInterval: function()
	{
		this.mainTimer = clearTimeout(this.mainTimer);
	},
	resetInterval: function()
	{
		if(this.options.auto){
			this.mainTimer = clearTimeout(this.mainTimer);
			this.mainTimer = setTimeout(this.proxy(function(){this.interval()}, this), this.options.timeout);
		}
	},
	control: function() {
		this.paused = !this.paused;
		this.getControl();
		this.paused ? this.clearInterval() : this.resetInterval();
	},
	next: function() {
		var i = this.current + this.visible;	
		this.scrollTo(i);
		return false;
	},
	prev: function() {
		var i = this.current - this.visible;
		this.scrollTo(i);
		return false;	
	},
	page: function(e) {
		var i = (parseInt($(e.target).text())) * this.visible;
		this.scrollTo(i);
		return false;	
	},
	scrollTo: function(i, type) {
		var o = this.options;
		
		if(!o.repeat)
		{
			var i = i < 0 ? 0 : i;
			i = i > this.end ? this.end : i;	
		}
			
		if(i != this.current && !this.animate )
		{
			this.animate = true;
			var props = {};
				props[this.axProps.left] = -this.offsets[i];
			// animace
			this.$element
				.animate(
					props, 
					o.animation, 
					'swing',
					this.proxy(function(){
						this.animate = false;
						!this.paused && this.resetInterval();
						if (o.repeat){
							if(i < this.visible)
							{
								this.$element.css(this.axProps.left, -this.offsets[this.length]);
								return;	
							}
							if(i > this.length)
							{
								this.$element.css(this.axProps.left, -this.offsets[this.visible]);
								return;
							}	
						}
						
					}, this)
				).trigger('scroll', [i]);
				
			if(o.repeat)
			{
				this.current = (i < this.visible) ? this.length : (i > this.length) ? this.visible : i;
			}
			else
			{
				this.current = i	
			}
			
			
			(o.pagerPages && !o.pagerMaks) && this.getPage();
			(o.pagerMask) && this.getPages();
			
			(!o.repeat) && this.controlPrev();
			(!o.repeat) &&this.controlNext();
		}

	},
	// nastaví přehrávacího tlačítka
	getControl: function(){
		this.$pager
			.find('.control')
			.removeClass(this.paused ? 'pause' : 'play')
			.addClass(this.paused ? 'play' : 'pause')
			.text(this.paused ? 'play' : 'pause');
	},
	// nastaví správné stránkování
	getPage: function(){
		this.$pager
			.find('.page')
			.removeClass('active')
			.eq((this.current - this.visible) / this.visible)
			.addClass('active');	
	},
	// nastaví správné stránkování (stránkován s maskou)
	getPages: function(){
		this.$pager
			.find('.pages')
			.text(this.options.pagerMask.replace('{$active}', this.current).replace('{$all}', this.length))	;
	},
		
	controlPrev: function() {
		this.$pager
			.find('.btn-prev')[(this.current == 0) ? 'addClass' : 'removeClass']('btn-prev-disable');
	},
	controlNext: function() {
		this.$pager
			.find('.btn-next')[(this.current == this.end) ? 'addClass' : 'removeClass']('btn-next-disable');
	}
	
};


