$.fn.carousel = function(_options){	
	
	options = arrayMerge({
		'visible': 1,
		'beforeSeek': null,
		'afterSeek': null,
		'speed': 500
	}, _options);
	
	var total = 0;
	var offset = (options.visible - 1) / 2;
	var current = 1 + offset;
	var center = Math.round(this.width() / 2) - Math.round($('.block', this).outerWidth(true) / 2);
	
	$.extend(this, {
		getCurrent: function(){
			return current;
		},
		getSpeed: function(){
			return options.speed;
		},
		next: function(_callback){
			if(options.beforeSeek){
				options.beforeSeek();
			}
			var last = current + offset;
			if(last > total) {last = last - total;}	
			if($('.block:last', this).attr('index') == $('.block[index=' + last + ']', this).attr('index')){
				$('.block:last', this).after($('.block:first', this).clone());
				$('.block:first', this).remove();
			}
			current++;
			current = inRange(current, 1, total);
			var from = $('.current', this).position().left;
			$('.current', this).removeClass('current');
			$('.block[index=' + current + ']', this).addClass('current');
			var to = $('.current', this).position().left;
			if(_callback){
				move(this, from, to, _callback);
			}
			else{
				move(this, from, to, options.afterSeek);
			}
		},
		prev: function(_callback){
			if(options.beforeSeek){
				options.beforeSeek();
			}
			var first = current - offset;
			if(first < 1) {first = total + first;}	
			if($('.block:first', this).attr('index') == $('.block[index=' + first + ']', this).attr('index')){
				$('.block:first', this).before($('.block:last', this).clone());
				$('.block:last', this).remove();
			}
			current--;
			current = inRange(current, 1, total);
			var from = $('.current', this).position().left;
			$('.current', this).removeClass('current');
			$('.block[index=' + current + ']', this).addClass('current');
			var to = $('.current', this).position().left;
			if(_callback){
				move(this, from, to, _callback);
			}
			else{
				move(this, from, to, options.afterSeek);
			}
		},
		jump: function(_value){
			var def = {
				'speed': options.speed,
				'afterSeek': options.afterSeek,
				'beforeSeek': options.beforeSeek
			};
			options.speed = 0;
			options.afterSeek = null;
			options.beforeSeek = null;
			
			while(_value != current){
				this.next();
			}
			options.speed = def.speed;
			options.afterSeek = def.afterSeek;
			options.beforeSeek = def.beforeSeek;
		}
	});
	
	return this.each(function(){
		 $('.block', this).each(function(){
		 	total++;
		 	$(this).attr('index', total);
		 });
		 $('.block[index=' + current + ']', this).addClass('current');
		 $('.items', this).css('left', ($('.current').position().left - center) * -1);
	});
	
	function inRange(_num, _min, _max){
		if(_num < _min){
			return _max;
		}else if(_num > _max){
			return _min;
		}else{
			return _num;
		}
	}
	
	function arrayMerge(_a, _b) {
		if(_a){
			if(_b){
				for(var i in _b){
					_a[i] = _b[i];
				}
			}
			return _a;
		}else{
			return _b;		
		}
	};
	
	function move(_obj, _from, _to, _callback){
		$('.items', _obj).stop().css('left', _from * -1 + center);
		$('.items', _obj).animate({
			'left': _to * -1 + center
		}, options.speed, function(){
			if(_callback){
				_callback();
			}
		});
	}
}
