(function($) {
	$.fn.extend({
		resizable: function(opts) {
			opts = $.extend({},$.fn.resizable.defaults,opts);
			
			var args = Array.prototype.slice.call(arguments, 1);
			return this.each(function() {
				if (typeof opts == "string") {
					var Resizable = $.data(this, "resizable");
					Resizable[opts].apply(Resizable, args);
				} else if(!$.data(this, "resizable")) {
					$.data(this, "resizable", new $.Resizable(this, opts));
				}
					
			});
		}
	});
	$.Resizable = function(elm, opts){
		
		var that = this;
		this.elm = $(elm);
		this.o = opts;
		if(this.o.southHandle) {$(this.o.southHandle).css({display:'block'}); };
		this.innerElm = this.elm.children(':first');
		this.maximumHeight = this.innerElm.height();
		this.curHeight = this.elm.height();
		this.startHeight = this.elm.height();
		this.startTop = document.documentElement.scrollTop;
		
		this.mouseY = 0;
		
		$(opts.southHandle).bind('mousedown.resizable', function(e){
			that.onMouseDown.call(that,e, $(this));
		}).bind('mouseup.resizable', function(e){
			that.onMouseUp.call(that,e, $(this));
		});
		
	}
	$.extend($.Resizable.prototype, {
		onMouseDown: function(e, handle){
			var that = this;
			this.maximumHeight = this.innerElm.height();
			this.mouseY = e.clientY;
			this.startHeight = this.elm.height();
			this.startTop = document.documentElement.scrollTop;
			$('body').bind('mousemove.resizable', function(e){
				that.resizable.call(that,e);
			}).bind('mouseup.resizable', function(e){
				that.onMouseUp.call(that,e, $(this));
			}).bind('mouseleave.resizable', function(e){
				that.onMouseUp.call(that,e, $(this));
			});
		},
		onMouseUp: function(e,handle){
			$('body').unbind('.resizable');
		},
		resizable: function(e) {
				var delta = e.clientY - this.mouseY - (this.startTop - document.documentElement.scrollTop);
				
				if(this.startHeight + delta < this.o.minimumHeight) {
					this.curHeight = this.o.minimumHeight;
				}
				else if (this.startHeight + delta > this.maximumHeight) {
					this.curHeight = this.maximumHeight;
				}
				else { 
					this.curHeight = this.startHeight + delta;
				}
				this.elm.css({height: this.curHeight});
		}
	});
	$.fn.resizable.defaults = {
		minimumHeight:100,
		south:true,
		southHandle:null,
		start:function(){},
		complete:function(){}
	};
})(jQuery);
