jQuery.fn.makeScrollable = function(opts) {
	var root = this;
	var main = $('._main_', root);
	var box = $('._cnt_', main);
	var bar = $('._bar_', root);
	var hndl = $('._bar_hndl_', root);

	function left() {
		var pos = main.data("currpos");
		var list = main.data("positions");
		if (pos > 0) {
			--pos;
			var pixel = list[pos] - main.scrollLeft();
			main.animate({ "scrollLeft":list[pos]}, {
				duration: 2 * Math.abs(pixel * 2),
				step: updateScroller
			});
			main.data("currpos", pos);
		}
	}
	function right() {
		var pos = main.data("currpos");
		var list = main.data("positions");
		var boxWidth = main.data("boxwidth");
		if (pos < list.length-1 && (boxWidth-list[pos]) - main.width() > 0 ) {
			++pos;
			var pixel = list[pos] - main.scrollLeft();
			main.animate({"scrollLeft":list[pos]}, {
				duration: 2 * Math.abs(pixel * 2),
				step: updateScroller
			});
			main.data("currpos", pos);
		}
	}
	function updateScroller(e) {
		var p = Math.floor((main.data("scrwidth") * e) / main.data("boxwidth"));
		p = Math.min(p, main.data("scrwidth") - main.data("hndlwidth"));
		main.data("scroll").css('marginLeft', p);
	}

	var sumWidth = 0;
	var maxHeight = 0;
	var positions = [];
	$('._item_', this).each(function(i,e){
		e = $(e);
		positions[i] = sumWidth;
		sumWidth += e.width();
		maxHeight = Math.max(maxHeight, e.height());
	});
	main.data("vpwidth", root.width());
	main.data("boxwidth", sumWidth);
	main.data("scrwidth", bar.width());
	main.data("scroll", hndl);
	main.data("positions", positions);
	main.data("currpos", 0);

	$('#scr-l').click(function(){ left(main); });
	$('#scr-r').click(function(){ right(main); });

	// Größe der Box an die Summe aller Content-Elemente anpassen
	box.height(maxHeight);
	box.width(sumWidth);
	main.scrollLeft(0);

	// Größe des Scrollbars anpassen
	var w = Math.min(bar.width(), Math.floor((root.width() * bar.width())/ sumWidth));
	hndl.css('width', w);
	main.data("hndlwidth", w);

	// Dragging vom Scrollbar
	hndl.bind('dragstart', function(e){
		hndl.data("off", parseInt(main.data("scroll").css("marginLeft"), 10));
		hndl.data("start", e.offsetX);
		return true;
	});
	hndl.bind('drag', function(e) {
		var off = Math.max(0, hndl.data("off") + e.offsetX - hndl.data("start"));
		off  = Math.min(off, main.data("scrwidth") - main.data("hndlwidth"));
		main.data("scroll").css('marginLeft', off);
		main.scrollLeft((off * main.data("boxwidth")) / main.data("scrwidth"));
	});
	hndl.bind('dragend', function(e) {
		var list = main.data("positions");

		var off = Math.max(0, hndl.data("off") + e.offsetX - hndl.data("start"));
		off  = Math.min(off, main.data("scrwidth") - main.data("hndlwidth"));
		var left = (off * main.data("boxwidth")) / main.data("scrwidth");

		// find best match
		var bestPos = 0;
		var bestPosDelta = 10000;
		for(var i=0 ; i<list.length ; ++i) {
			var d = Math.abs(list[i]-left);
			if (d < bestPosDelta) {
				bestPos = i;
				bestPosDelta = d;
			}
		}

		// Scroll to best position
		var pixel = list[bestPos] - main.scrollLeft();
		main.animate({scrollLeft:list[bestPos]}, {
			duration: Math.abs(pixel * 2),
			step: updateScroller
		});
		main.data("currpos", bestPos);
	});
}
