/*
 * Paginator jQuery Plugin
 *
 * To init:
 * Call $('#element').paginator();
 *
 * To update:
 * Call $('#element').paginator('<option>', <value>);
 *
 */
(function($) {
	$.widget('ui.paginator', {
		leftArrow: null,
		rightArrow: null,
		container: null,
		ul : null,
		liFirst : null,
		liLast : null,
		_init : function() {
			if (this.options.total < 2) {
				this.destroy();
				return;
			}

			this.element.empty().addClass('paginator');

			var widget = this;

			this.ul = $('<ul>');
			for(var i=0; i<this.options.total; i++) {
				var li = $('<li>'+(i+1)+'</li>').click(function(){ widget.select($('li', widget.ul).index(this)); });
				if (!i) {
					li.addClass('first');
					this.liFirst = li;
				}
					
				if (i == this.options.active) {
					li.addClass('active');
				}
				if (i == this.options.visible-1) {
					li.addClass('last');
					this.liLast = li;
				}
				this.ul.append(li);
			}				

			this.container = $('<div class="container">').append(this.ul);

			if (this.options.mousewheel) {
				this.container.mousewheel(function(event, delta) {
					if(delta>0)
						widget._prev();
					else if (delta<0)
						widget._next();
					event.preventDefault();
				});
			}

			this.leftArrow = $('<span class="arrow left hidden"></span>').click(function(){ widget._prev(); });
			this.rightArrow = $('<span class="arrow right'+(this.options.total<=this.options.visible ? ' hidden' : '')+'"></span>').click(function(){ widget._next(); });

			//this.element.append(this.leftArrow);
			this.element.append(this.container);
			//this.element.append(this.rightArrow);

			if (!this.liLast) {
				this.liLast = this._findLiByN(this.options.total-1);
				this.liLast.addClass('last');
			}

			this.container.css('width', li.outerWidth(true)*Math.min(this.options.visible, this.options.total));
			this.ul.css('width', li.outerWidth(true)*this.options.total);
			this.element.css('width', this.container.outerWidth(true) );
		},
		destroy : function() {
			$.widget.prototype.destroy.apply(this, arguments);
			return this;
		},
		_findLiByN : function(n) {
			return $('ul li', this.element).eq(n);
		},
		_scrollTo : function(li) {
			var liN = $('li', this.ul).index(li);
			var liFirstN = $('li', this.ul).index(this.liFirst);
			var liLastN = $('li', this.ul).index(this.liLast);
			if (liN >= liFirstN && liN <= liLastN || liN < 0 || liN >= this.options.total)
				return;
			var newLiFirstN, newLiFirst, newLiLastN, newLiLast;
			newLiFirstN = Math.floor(liN / this.options.visible) * this.options.visible;
			newLiLastN = newLiFirstN + this.options.visible - 1;
			if (newLiLastN >= this.options.total)
				newLiLastN = this.options.total - 1;

			newLiFirst = this._findLiByN(newLiFirstN);
			newLiLast  = this._findLiByN(newLiLastN);

			//this.leftArrow.toggleClass('hidden', !newLiFirstN);
			//this.rightArrow.toggleClass('hidden', newLiFirstN + this.options.visible >= this.options.total);

			var marginLeft = -li.outerWidth(true) * newLiFirstN;

			newLiFirst.addClass('first');
			newLiLast.addClass('last');
			if (this.options.animate || this.options.animateScroll) {
				var liFirst = this.liFirst;
				var liLast = this.liLast;
				$('li:animated', this.ul).stop(true, true);
				this.ul.animate({marginLeft:marginLeft},this.options.animate || this.options.animateScroll, 'linear', function(){
					liFirst.removeClass('first');
					liLast.removeClass('last');
				});
			} else {
				this.ul.css('marginLeft', marginLeft);
				this.liFirst.removeClass('first');
				this.liLast.removeClass('last');
			}
			this.liFirst = newLiFirst;
			this.liLast = newLiLast;
		},
		_prev : function() {
			this.select($('li', this.ul).index(this.liFirst) - this.options.visible);
		},
		_next : function() {
			this.select($('li', this.ul).index(this.liLast) + 1);
		},
		show : function() {
		},
		select : function(num) {
			var num = Number(num);

			var liActive = $('li.active', this.ul);

			if ($('li', this.ul).index(liActive) == num ||  num < 0 || num >= this.options.total)
				return;

			var li = this._findLiByN(num);

			this._scrollTo(li);

			if (this.options.animate || this.options.animateSelect) {
				var aSpeed = this.options.animate || this.options.animateSelect;
				$('li:animated', this.ul).stop(true, true).removeClass('active');
				liActive.animate({opacity:0.5}, aSpeed, 'linear', function(){liActive.removeClass('active').animate({opacity:1}, aSpeed)});
				li.animate({opacity:0.5}, aSpeed, 'linear', function(){li.addClass('active').animate({opacity:1}, aSpeed)});
			}
			else
			{
				liActive.removeClass('active');
				li.addClass('active');
			}

			// triggering event
			this._trigger('select', 0, num);
			
			// calling onSelect callback if exists
			if (this.options.onSelect) {
				if (typeof(this.options.onSelect) == 'function') {
					this.options.onSelect(num, this.element);
				} else if ($.isArray(this.options.onSelect)) {
					for (var i=0; i<this.options.onSelect.length; i++) {
						this.options.onSelect[i](num, this.element);
					}
				}
			}
		}
	});

	$.extend($.ui.paginator, {
		version : '0.1.0',
		defaults : {
			visible: 10,
			total: 0,
			active: 0,
			animate: 0,
			mousewheel: true,
			animateSelect: 0,
			animateScroll: 0,
			onSelect: null
		}
	});

})(jQuery);