//http://code.google.com/p/jquery-pirates/source/browse/trunk/WebContent/demos/resizable/resizable.html?r=18

(function($) {
        var resizable = function(els, opts) {
                var $this = $(els), helper = null;
                $.extend(this, {
                        init : init,
                        disabled : function(e) {
                                $this.unbind("mousemove", setDirection);
                                $this.unbind("mousedown", startResize);
                        }
                });
                function init() {
                        $this.bind("mousemove", setDirection);
                        $this.bind("mousedown", startResize);
                }
                function getDirection(e) {
                        var dir = "";
                        var place = $this.offset();
                        var width = $this.outerWidth();
                        var height = $this.outerHeight();
                        var edge = opts.edge;
                        if (e.pageY > place.top && e.pageY < place.top + edge) {
                                dir += "n";
                        } else {
                                if (e.pageY < place.top + height
                                                && e.pageY > place.top + height - edge) {
                                        dir += "s";
                                }
                        }
                        if (e.pageX > place.left && e.pageX < place.left + edge) {
                                dir += "w";
                        } else {
                                if (e.pageX < place.left + width
                                                && e.pageX > place.left + width - edge) {
                                        dir += "e";
                                }
                        }
                        var handle = opts.handles.split(",");
                        for ( var i = 0; i < handle.length; i++) {
                                var hand = handle[i].replace(/(^\s*)|(\s*$)/g, "");
                                if (hand == "all" || hand == dir) {
                                        return dir;
                                }
                        }
                        return "";
                }
                function setDirection(e) {
                        var dir = getDirection(e);
                        if (dir == "") {
                                $this.css("cursor", "default");
                        } else {
                                $this.css("cursor", dir + "-resize");
                        }
                }
                function startResize(e) {
                        opts.onStartResize.call($this, e);
                        var dir = getDirection(e);
                        if (dir == "")
                                return;
                        $this.unbind("mousemove", setDirection);
                        $this.css("-moz-user-select", "none");
                        $this.attr("unselectable", "on");
                        var data = {
                                target : $this,
                                dir : dir,
                                startLeft : getCssValue('left'),
                                startTop : getCssValue('top'),
                                left : getCssValue('left'),
                                top : getCssValue('top'),
                                startX : e.pageX,
                                startY : e.pageY,
                                startWidth : $this.outerWidth(),
                                startHeight : $this.outerHeight(),
                                width : $this.outerWidth(),
                                height : $this.outerHeight(),
                                deltaWidth : $this.outerWidth() - $this.width(),
                                deltaHeight : $this.outerHeight() - $this.height()
                        };
                        if (opts.helper) {
                                helper = $this.clone().empty().appendTo($("body"));
                                helper.css(opts.helperStyle);
                                helper.css( {
                                        "opacity" : "0.3",
                                        "filter" : "alpha(opacity = 30)"
                                });
                                data.target = helper;

                        }
                        $(document).bind("mousemove", data, resize);
                        $(document).bind("mouseup", data, stop);
                }
                function doResize(e) {
                        var rData = e.data;
                        if (rData.dir.indexOf('e') != -1) {
                                var width = rData.startWidth + e.pageX - rData.startX;
                                width = Math.min(Math.max(width, opts.doWsize[0]),
                                                opts.doWsize[1]);
                                rData.width = width;
                        }
                        if (rData.dir.indexOf('s') != -1) {
                                var height = rData.startHeight + e.pageY - rData.startY;
                                height = Math.min(Math.max(height, opts.doHsize[0]),
                                                opts.doHsize[1]);
                                rData.height = height;
                        }
                        if (rData.dir.indexOf('w') != -1) {
                                w = rData.startWidth - e.pageX + rData.startX;
                                if (w >= opts.doWsize[0] && w <= opts.doWsize[1]) {
                                        rData.width = w;
                                        rData.left = rData.startLeft + e.pageX - rData.startX;
                                }
                        }
                        if (rData.dir.indexOf('n') != -1) {
                                h = rData.startHeight - e.pageY + rData.startY;
                                if (h >= opts.doHsize[0] && h <= opts.doHsize[1]) {
                                        rData.height = h;
                                        rData.top = rData.startTop + e.pageY - rData.startY;
                                }
                        }
                }
                function applySize(e) {
                        var rData = e.data;
                        if ($.boxModel == true) {
                                rData.target.css( {
                                        width : rData.width - rData.deltaWidth,
                                        height : rData.height - rData.deltaHeight,
                                        left : rData.left,
                                        top : rData.top
                                });
                        } else {
                                rData.target.css( {
                                        width : rData.width,
                                        height : rData.height,
                                        left : rData.left,
                                        top : rData.top
                                });
                        }
                        opts.onResize.call($this, e);
                }
                function resize(e) {
                        doResize(e);
                        applySize(e);
                        return false;
                }
                function stop(e) {
                        if (opts.helper) {
                                e.data.target = $this;
                                helper.remove();
                                applySize(e);
                        }
                        $(document).unbind("mousemove", resize);
                        $(document).unbind("mouseup", stop);
                        $this.bind("mousemove", setDirection);
                        opts.onStopResize.call($this, e);
                        return false;
                }
                function getCssValue(css) {
                        var val = parseInt($this.css(css));
                        if (isNaN(val)) {
                                return 0;
                        } else {
                                return val;
                        }
                }
        };
        $.fn.resizable = function(options) {
                var pir = this.eq(typeof options == 'number' ? options : 0).data(
                                "resizable");
                if (pir) {
                        return pir;
                }
                this.each(function() {
                        var opts = $.extend( {}, $.fn.resizable.defaults, {}, options);
                        if (opts.obj) {
                                pir = new resizable(opts.obj, opts);
                        } else {
                                pir = new resizable(this, opts);
                        }
                        pir.init();
                        $(this).data("resizable", pir);
                });
                return pir;
        };
        $.fn.resizable.defaults = {
                handles : "n,e,s,w,se,all",
                obj : null,
                helper : false,
                helperStyle : null,
                doWsize : [ 10, 10000 ],
                doHsize : [ 10, 10000 ],
                edge : 5,
                onStartResize : function() {
                },
                onResize : function() {
                },
                onStopResize : function() {
                }
        };
})(jQuery);


