(function( $ ){
	var methods = 
	{
		init : function( options ) 
		{	
			return $(this).each(function()
			{
				var id = $(this).attr("id");
				$(this).data({"items":options.items, type:options.type, "nocorrection":options.nocorrection});
				var shifts = $(this).jscroller("detectShifts");
				var $elem = $(this);
				if (options.tobindscroll) $elem = options.tobindscroll;
				$(this).data({"shifts":shifts, page:0, pages:shifts.length, "$elem":$elem});
				var html = "";
				if (options.type == "horisontal")
					html = "<div class='jscroller_h_outer' id='"+id+"_scroller_outer'>"+"<div class='jscroller_h_button jscroller_h_prevbutton'></div>"+"<div class='jscroller_h_scroll_outer jscroller_scroll_outer'>"+"<div class='jscroller_h_scroll_outer2'>"+"<div class='jscroller_h_scroll_left'></div>"+"<div class='jscroller_h_scroll_inner'>"+"<div class='jscroller_h_scroll_runner jscroller_runner'>"+"<div class='jscroller_h_scroll_runner_left'></div>"+"<div class='jscroller_h_scroll_runner_right'></div>"+"</div>"+"</div>"+"<div class='jscroller_h_scroll_right'></div>"+"</div>"+"</div>"+"<div class='jscroller_h_button jscroller_h_nextbutton'></div>"+"</div>";
				else
					html = "<div class='jscroller_v_outer' id='"+id+"_scroller_outer'>"+"<div class='jscroller_v_button jscroller_v_prevbutton'></div>"+"<div class='jscroller_v_scroll_outer jscroller_scroll_outer'>"+"<div class='jscroller_v_scroll_outer2'>"+"<div class='jscroller_v_scroll_top'></div>"+"<div class='jscroller_v_scroll_inner'>"+"<div class='jscroller_v_scroll_runner jscroller_runner'>"+"<div class='jscroller_v_scroll_runner_top'></div>"+"<div class='jscroller_v_scroll_runner_bottom'></div>"+"</div>"+"</div>"+"<div class='jscroller_v_scroll_bottom'></div>"+"</div>"+"</div>"+"<div class='jscroller_v_button jscroller_v_nextbutton'></div>"+"</div>";
				
				$elem.after(html);
				
				$(this).jscroller("sizes_"+options.type, $elem, true);
				$(this).bind('mousewheel.jscroll', function(event, delta)
				{
					event.preventDefault();
					var direction = delta>0?-1:1;
					$(this).jscroller("topage", parseInt($(this).data("page"))+parseInt(direction));
				});
				$("#"+id+"_scroller_outer .jscroller_h_prevbutton, #"+id+"_scroller_outer .jscroller_h_nextbutton, #"+id+"_scroller_outer .jscroller_v_prevbutton, #"+id+"_scroller_outer .jscroller_v_nextbutton").bind("click.jscroll", function(event)
				{
					event.preventDefault();
					var direction = ($(this).hasClass("jscroller_h_prevbutton") || $(this).hasClass("jscroller_v_prevbutton"))?-1:1;
					$(this).data("owner").jscroller("topage", parseInt($(this).data("owner").data("page"))+parseInt(direction));
				});
				$("#"+id+"_scroller_outer .jscroller_scroll_outer").bind("click.jscroll", function(event)
				{
					event.preventDefault();
					if ($(this).data("owner").data("dragged"))
					{
						$(this).data("owner").data("dragged", false);
						return;
					}
					var id = $(this).data("owner").attr("id");
					if ($(this).data("owner").data("type") == "horisontal")
					{
						var direction = event.clientX > $("#"+id+"_scroller_outer .jscroller_runner").offset().left?1:-1;
					}
					else
					{
						
						var direction = event.clientY > $("#"+id+"_scroller_outer .jscroller_runner").offset().top?1:-1;
					}
					$(this).data("owner").jscroller("topage", parseInt($(this).data("owner").data("page"))+parseInt(direction));
				});
			});
		},
		update:function()
		{
			$(this).data("shifts", $(this).jscroller("detectShifts"));
			$(this).jscroller("sizes_"+$(this).data("type"), $(this).data("$elem"));
		},
		topage:function(page)
		{
			var id = $(this).attr("id");
			var shifts = $(this).data("shifts");
			var cpage = $(this).data("page");
			if ($(this).data("animating")) return;
			$(this).data("animating", true);
			if (page >= 0 && page < $(this).data("pages"))
			$(this).data("page", parseInt(page));
			else if (page < 0)
				$(this).data("page", 0);
			else if (page >= $(this).data("pages"))
				$(this).data("page", $(this).data("pages")-1)
			cpage = $(this).data("page");
			var newoff = cpage*$(this).data("rwidth");
			var ani_runner = "";
			var ani_inner  = ""; 
			switch ($(this).data("type"))
			{
				case "horisontal":
					ani_runner = "left";
					ani_inner  = "margin-left";
				break;
				case "vertical":
					ani_runner = "top";
					ani_inner  = "margin-top";
				break;
			}
			var ani_runner_data = {};
			ani_runner_data[ani_runner] = newoff;
			$("#"+id+"_scroller_outer .jscroller_runner").animate(ani_runner_data, 500, "easeInOutQuad", function()
			{
				$(this).data("owner").data("animating", false);
			});
			var ani_inner_data = {}
			ani_inner_data[ani_inner] = shifts[cpage];
			$("#"+id+" .inner").animate(ani_inner_data, 500, "easeInOutQuad");
		},
		detectShifts:function()
		{
			var items = $(this).data("items");
			var id = $(this).attr("id");
			var type = $(this).data("type");
			var result = [];
			var outerSize = type=="vertical"?$(this).height():$(this).width();
			$("#"+id+" "+items).each(function()
			{
				result[result.length] = {start:((type=="vertical")?$(this).offset().top-$(this).parent().offset().top:$(this).offset().left-$(this).parent().offset().left), size: ((type=="vertical")?$(this).outerHeight():$(this).outerWidth())};
			});
			var sorted = {};
			var starts = [];
			for (var i = 0; i < result.length; i++)
			{
				if (!sorted[result[i].start])
				{
					sorted[result[i].start] = 0;
					starts[starts.length] = parseInt(result[i].start);
				}
				if (result[i].size > sorted[result[i].start])
					sorted[result[i].start] = result[i].size;
			}
			starts.sort(function(a,b){return a-b});
			var fullLength = 0;
			for (var i = 0; i < starts.length; i++) fullLength+=sorted[starts[i]];
			var curLength = 0;
			result = [0];
			var lastChinese = false;
			for (var i = 0; i < starts.length; i++)
			{
				var shift = starts[i];
				if (fullLength-curLength<outerSize)
				{
					console.log($(this).data("nocorrection")+"nocorr");
					if (!$(this).data("nocorrection"))
						shift-=(outerSize - (fullLength-curLength));
					else
					{
						if (lastChinese)
							shift = 0;
						lastChinese = true;
					}
				}
				var test = result.length?result[result.length-1]:1000;
				if (shift > 0 && (-1*shift < test))
				{
					result[result.length] = -1*shift;
				}
				curLength+=sorted[starts[i]];
			}
			
			return result;
		},
		sizes_horisontal:function($elem, firsttime)
		{
			var id = $(this).attr("id");
			var shifts = $(this).data("shifts");
			$("#"+id+"_scroller_outer").css("width", $(this).outerWidth());
			$("#"+id+"_scroller_outer .jscroller_scroll_outer")
				.css("width", $(this).outerWidth()-2*($("#"+id+"_scroller_outer .jscroller_h_button:eq(1)").outerWidth()));
			$("#"+id+"_scroller_outer .jscroller_h_scroll_inner").css("width", $("#"+id+"_scroller_outer .jscroller_h_scroll_outer2").width());				
			var rwidth = Math.round($("#"+id+"_scroller_outer .jscroller_h_scroll_inner").width()/shifts.length);			
			$("#"+id+"_scroller_outer .jscroller_h_scroll_runner, #"+id+"_scroller_outer .jscroller_h_button, #"+id+"_scroller_outer .jscroller_scroll_outer").data("owner", $(this));
			$(this).data("rwidth", rwidth);
			if (firsttime)
			{
				$("#"+id+"_scroller_outer .jscroller_runner").css("width", rwidth+"px").draggable({
					containment:$("#"+id+"_scroller_outer .jscroller_h_scroll_inner"),
					axis:"x",
					stop:function(event, ui)
					{
						$(this).data("owner").data("dragged", true);
						var xoff = $(this).offset().left-$(this).parent().offset().left;
						$(this).data("owner").jscroller("stopDragging", xoff);
					}
				});
			}
			else
				$("#"+id+"_scroller_outer .jscroller_runner").css("width", rwidth+"px")
			
		},
		sizes_vertical:function($elem, firsttime)
		{
			var id = $(this).attr("id");
			var shifts = $(this).data("shifts");
			$("#"+id+"_scroller_outer").css({height:$elem.outerHeight(), "margin-left":$elem.outerWidth()+($elem.offset().left-$elem.parent().offset().left), "margin-top":-1*($elem.outerHeight())});
			$("#"+id+"_scroller_outer .jscroller_scroll_outer").css("height", $elem.outerHeight()-2*($("#"+id+"_scroller_outer .jscroller_v_button:eq(1)").outerHeight())-4);
			$("#"+id+"_scroller_outer .jscroller_v_scroll_outer2").css("height", $("#"+id+"_scroller_outer .jscroller_scroll_outer").height()-parseInt($("#"+id+"_scroller_outer .jscroller_v_scroll_outer2").css("margin-top").replace("px", ""))*2 );
			$("#"+id+"_scroller_outer .jscroller_v_scroll_bottom").css("margin-top", $("#"+id+"_scroller_outer .jscroller_v_scroll_outer2").height()-2*($("#"+id+"_scroller_outer .jscroller_v_scroll_bottom").outerHeight()));			
			$("#"+id+"_scroller_outer .jscroller_v_scroll_inner").css("height", $("#"+id+"_scroller_outer .jscroller_v_scroll_outer2").height());
			
			var rwidth = Math.round($("#"+id+"_scroller_outer .jscroller_v_scroll_inner").height()/shifts.length);
			$("#"+id+"_scroller_outer .jscroller_v_scroll_runner, #"+id+"_scroller_outer .jscroller_v_button, #"+id+"_scroller_outer .jscroller_scroll_outer").data("owner", $(this));
						
			$(this).data("rwidth", rwidth);
			
			$(".jscroller_v_scroll_runner_bottom").css("margin-top", rwidth-5);
			if (firsttime)
			{
				$("#"+id+"_scroller_outer .jscroller_runner").css("height", rwidth+"px").draggable({
					containment:$("#"+id+"_scroller_outer .jscroller_v_scroll_inner"),
					axis:"y",
					stop:function(event, ui)
					{
						$(this).data("owner").data("dragged", true);
						var yoff = $(this).offset().top-$(this).parent().offset().top;
						$(this).data("owner").jscroller("stopDragging", yoff);
					}
				});
			}
			else
			{
				$("#"+id+"_scroller_outer .jscroller_runner").css("height", rwidth+"px")
			}
		},
		stopDragging:function(offset)
		{
			$(this).data("dragged", true);
			if (offset < 0) offset = 0;
			console.log(offset);
			var tmpPage = Math.round(offset/parseInt($(this).data("rwidth")));
			console.log(tmpPage);
			$(this).jscroller("topage", tmpPage);
		}
	};

	$.fn.jscroller = function( method ) 
	{

		if ( methods[method] ) 
		{
			return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
		} 
		else if ( method instanceof Object || ! method ) 
		{
			return methods.init.apply( this, arguments );
		} 
		else 
		{
			$.error( 'Method ' +  method + ' does not exist on jQuery.jscroller' );
		}    

	};

})( jQuery );

