(function($) {
	var scrollThis;
	function ScrollPane(options) {
		this.defaults = {
			target: "",
			vMargin: 0,
			bgImage: "",
			upArrow: "",
			downArrow: "",
			handle: ""
		};
		$.extend(this.defaults, options);
		scrollThis = this;
		
		this.target = $(this.defaults.target);
		var html = this.target.html();
		this.innerTarget = $("<div>" + html + "</div>");
		this.target.empty();
		this.target.append(this.innerTarget);
		
		this.target.css("overflow", "hidden");
		this.innerTarget
			.css("position", "absolute")
			.css("top", "0px")
			.css("left", "0px")
			.css("width", "100%")
			.css("z-index", "1000");
		this.currentPosition = 0;
		
		var targetPos = this.target.position();
		var parnetPos = this.target.parent().position();
		this.scrollBar = $("<div></div>").appendTo("#main");
		this.scrollBar
			.css("width", "20px")
			.css("position", "absolute")
			.css("top", (targetPos.top + this.defaults.vMargin) + "px")
			.css("left", (parnetPos.left - 30) + "px")
			.css("height", (this.target.height() - (2*this.defaults.vMargin + 40)) + "px")
			.addClass("scrollpane");
		
		this.upArrow = $("<div></div>").addClass("scrollpane-up").appendTo(this.scrollBar);
		this.handle = $("<div></div>").addClass("scrollpane-handle").appendTo(this.scrollBar);
		this.downArrow = $("<div></div>").addClass("scrollpane-down").appendTo(this.scrollBar);
		
		this.upArrow.hover(
				function(e) { $(this).addClass("scrollpane-up-active"); },
				function(e) { $(this).removeClass("scrollpane-up-active"); }
			).click(function(e) {
				scrollThis.currentPosition += 20;
				scrollThis.update(e);
				return false;
			});
		this.handle.hover(
				function(e) { $(this).addClass("scrollpane-handle-active"); },
				function(e) { $(this).removeClass("scrollpane-handle-active"); }
			).mousedown(function(e) {
				scrollThis.initHandleDrag(e.pageY);
				return false;
			});
		this.downArrow.hover(
				function(e) { $(this).addClass("scrollpane-down-active"); },
				function(e) { $(this).removeClass("scrollpane-down-active"); }
			).click(function(e) {
				scrollThis.currentPosition -= 20;
				scrollThis.update(e);
				return false;
			});
		
		this.target.mousewheel(this.update);
		$(window).resize(this.update).resize();
	};
	
	ScrollPane.prototype.update = function(e) {
		if (e.type == "mousewheel") {
			if (e.detail) scrollThis.currentPosition -= Math.round(e.detail);
			if (e.wheelDelta) scrollThis.currentPosition += Math.round(e.wheelDelta/40);
		}
		if (scrollThis.currentPosition < scrollThis.target.height() - scrollThis.innerTarget.height()) {
			scrollThis.currentPosition = scrollThis.target.height() - scrollThis.innerTarget.height();
		}
		if (scrollThis.currentPosition > 0) {
			scrollThis.currentPosition = 0;
		}
		scrollThis.innerTarget.css("top", scrollThis.currentPosition);
		
		var targetPos = scrollThis.target.position();
		var parnetPos = scrollThis.target.parent().position();
		scrollThis.scrollBar
			.css("width", "20px")
			.css("position", "absolute")
			.css("top", (targetPos.top + scrollThis.defaults.vMargin) + "px")
			.css("left", (parnetPos.left - 30) + "px")
			.css("height", (scrollThis.target.height() - (2*scrollThis.defaults.vMargin + 40)) + "px");
		
		if (scrollThis.target.height() - scrollThis.innerTarget.height() > 0) {
			scrollThis.scrollBar.hide();
		} else {
			scrollThis.scrollBar.show();
		}
		
		var newHandleTop = Math.round((scrollThis.currentPosition / (scrollThis.innerTarget.height() - scrollThis.target.height())) * (scrollThis.scrollBar.height()-34));
		scrollThis.handle.css("top", -newHandleTop + "px");
		return false;
	};
	
	ScrollPane.prototype.initHandleDrag = function(mouseTop) {
		scrollThis.handlePosition = scrollThis.handle.position().top;
		scrollThis.mouseTop = mouseTop;
		scrollThis.tmpScrollPosition = scrollThis.currentPosition;
		$("html").bind("mousemove", scrollThis.handleDrag);
		$("html").bind("mouseup", scrollThis.teardownHandleDrag);
	};
	
	ScrollPane.prototype.handleDrag = function(e) {
		var tmp = (scrollThis.innerTarget.height() - scrollThis.target.height()) * ((scrollThis.mouseTop - e.pageY)/(scrollThis.scrollBar.height()-34));
		scrollThis.currentPosition = tmp + scrollThis.tmpScrollPosition;
		scrollThis.update(e);
		return false;
	};
	
	ScrollPane.prototype.teardownHandleDrag = function(mouseTop) {
		$("html").unbind("mousemove", scrollThis.handleDrag);
		$("html").unbind("mouseup", scrollThis.teardownHandleDrag);
	};
	
	$.fn.scrollpane = function(options) {
		$(this).each(function() {
			var def = {
				target: this
			};

			$.extend(def, options);

			var scroll = new ScrollPane(def);
			$(this).data("scrollpae", scroll);
		});
	};
})(jQuery);
