(function($){

	var $window = $(window);

	Dock = function(options){		
		$.extend(this, options);		
		return this;
	};
	
	Dock.prototype = {
		
		// Contants
		LEFT  : 0,
		RIGHT : 1,
			
		// Properties
		active		  : true,
		buttons       : {},
		callbacks     : {},
		intv          : {},
		item_hover    : null,
		item_mouse    : 0,
		item_width    : 0,
		items         : null,
		length        : 0,
		list          : null,
		mouse_x       : 0,
		speed		  : 0,
		short         : false,
		window_width  : 0,
		window_center : 0,

		// Methods
		init : function ()
		{	
			var _this = this;
			
			this.items         = this.list.find('>li');
			this.length        = this.items.length;
			this.window_width  = $window.width() - 100;	
			this.window_center = Math.round(this.window_width/2);
			
			this.list.css({
				width : this.length * this.item_width + this.item_width,
				left  : 0
			});				
			
			if (this.window_width < this.length * 2 * this.item_width) {
				this.events();
				//this.controls();
				this.duplicate();
			} else {				
				this.list.width(this.length*2 * this.item_width + this.item_width*2 + 700);	
				this.short = true;
			}
			
			this.list.find('>li').each(function(){
				
				var $this = $(this);
				$this.addClass('item'+$this.index())
				.bind('mouseenter', function(){
					$(this).animate({
						top: -15
					},{
						duration: 300,
						queue: false,
						easing: 'easeInOutQuad'
					});
				}).bind('mousemove', function(evt){
					_this.item_mouse = evt.offsetX;
				}).bind('mouseleave', function(evt){
					$(this).animate({
						top: 0
					},{
						duration: 300,
						queue: false,
						easing: 'easeOutBounce'
					});
				}).bind('click', function(){					
					_this.callbacks.click(_this, $this);
				});				
				
				var $prev = $('<span class="left"><span></span></span>');
				var $next = $('<span class="right"><span></span></span>');
				var $close = $('<span class="close">&times; close</span>');
				
				$this.append($next, $prev, $close);
				
				$prev.bind('click', function(evt){
					evt.stopPropagation();
					$this.prev().trigger('click');
				});
				
				$next.bind('click', function(evt){
					evt.stopPropagation();
					$this.next().trigger('click');	
				});
				
				$close.bind('click', function(evt){
					evt.stopPropagation();
					_this.callbacks.close(_this, $this);
				});
				
			});
			
			$window.resize($.proxy(this, 'resize'));			
		},
		
		center : function ($ele)
		{
			var _this = this;
			
			var center = Math.floor(($window.width()-this.item_width)/2);
			var left = parseInt(this.list.css('left'));
			var left_item = $ele.position().left;
			
			var away = left_item + left - center;
						
			this.intv.center_i = 0;
			this.intv.center = setInterval(function(){
				
				var ease = $.easing.easeOutExpo(null, _this.intv.center_i, left, -away-250, 300);
				
				_this.list.css({left: ease});
				
				if (_this.intv.center_i == 300) {
					clearInterval(_this.intv.center);					
					
					var len = Math.floor(parseInt(_this.list.css('left'))/_this.item_width);
					var len_abs = Math.abs(len);
					
					if (len < 0) {
						while(len_abs > 0) {
							_this.list.find('>li:first').appendTo(_this.list);
							_this.list.css('left', "+="+_this.item_width);
							len_abs--;
						}
					} else if(len > 0) {
						while(len_abs > 0) {
							_this.list.find('>li:last').css({opacity: 0}).animate({opacity: 1}, {duration: 300, queue: false}).prependTo(_this.list);
							_this.list.css('left', "-="+_this.item_width);
							len_abs--;
						}
					}
				}
				_this.intv.center_i += 1;
				
			}, 1);			
			
		},
		
		controls : function ()
		{
			this.buttons.previous = $('<span class="left"><span></span></span>');
			this.buttons.next     = $('<span class="right active"><span></span></span>');
				
			this.buttons.previous.insertAfter(this.list);
			this.buttons.next.insertAfter(this.list);
				
			this.buttons.next.css({
				left: this.window_width - this.buttons.next.outerWidth() 
			});
		},
		
		duplicate : function ()
		{
			var clones = this.items.clone(true, true);
			clones.addClass('clone');
			clones.appendTo(this.list);
			
			this.list.width(this.length*2 * this.item_width + this.item_width*2 + 700);			
		},
		
		events : function ()
		{
			var _this = this;
			
			this.list.bind('mouseenter', function(evt){
				_this.mouse_x = evt.pageX;
				_this.intv.slide = setInterval($.proxy(_this, 'slide'), 15);
			}).bind('mouseleave', function(){
				clearInterval(_this.intv.slide);
				if (_this.active) _this.list.animate({left: "-="+_this.speed*15}, {queue: false, duration: Math.abs(_this.speed)*450, easing: 'easeOutExpo'});
			}).bind('mousemove', function(evt){
				_this.mouse_x = evt.pageX;				
			});
		},
		
		resize : function ()
		{			
			this.window_width  = $window.width();	
			this.window_center = Math.round(this.window_width/2);
			
			/*this.buttons.next.css({
				left: this.window_width - this.buttons.next.outerWidth() 
			});*/
		},
		
		slide : function (speed)
		{
			if ( ! this.active && speed == undefined) return false;
			
			var inc   = (this.mouse_x - this.window_center) /this.window_width
			var left  = parseInt(this.list.css('left'));
			
			this.speed = speed ? speed : inc * 10;
			
			this.list.stop(true)
			.css({
				left : left-this.speed
			});
			
			if (left > 0 && left < this.item_width ) {
				this.slide_prepend();				
				//this.buttons.next.removeClass('active');
				//this.buttons.previous.addClass('active');
			} else if (left < -this.item_width) {
				this.slide_append();
				//this.buttons.next.addClass('active');
				//this.buttons.previous.removeClass('active');
			}
		},
		
		slide_append : function ()
		{
			this.list.css({
				left : '+='+this.item_width
			}).find('>li:first')
			.appendTo(this.list);
		},
		
		slide_prepend : function ()
		{
			this.list.css({
				left : '-='+this.item_width
			}).find('>li:last')
			.prependTo(this.list);
		}
		
	};
	
})(jQuery);
