(function($) {

  $.dragscroller = function(el, o) {
    var options = { slowMode: false };
    $.extend(options, o);
    var self = this;
    $.extend(options, {
      _start: function(h, p, c, t, e) {
	self.start.apply(t, [self, e]); // Trigger the start callback				
      },
      _beforeStop: function(h, p, c, t, e) {
	self.stop.apply(t, [self, e]); // Trigger the start callback
      },
      _drag: function(h, p, c, t, e) {
	self.drag.apply(t, [self, e]); // Trigger the start callback
      },
      startCondition: function(e) {
	return (e.target.className.indexOf("dragscroller") != -1);
      }			
    });
    $.data(el, "dragscroller", this);
    $(el).addClass("dragscroller");
    this.interaction = new $.ui.mouseInteraction(el, options);
    this.scrollLeft  = 0;
    this.scrollTop   = 0;
    this.iteration   = 0;
  };

  $.extend($.dragscroller.prototype, {
    start: function(that, e) {
      that.scrollLeft = $(document).scrollLeft();
      that.scrollTop = $(document).scrollTop();
      that.ox = e.screenX;
      that.oy = e.screenY;
      if ($.browser.mozilla) {
        $('.dragscroller').css({ cursor: '-moz-grabbing' });
      } else {
        $('.dragscroller').css({ cursor: 'move' });
      }
    },
    drag: function(that, e) {
      var dx = that.ox - e.screenX;
      var dy = that.oy - e.screenY;
      x = that.scrollLeft + dx
      if (x < 0) x = 0;
      y = that.scrollTop + dy
      if (y < 0) y = 0;
      window.scrollTo(x, y);
    },
    stop: function(that, e) { 
      if ($.browser.mozilla) {
        $('.dragscroller').css({ cursor: '-moz-grab' });
      } else {
        $('.dragscroller').css({ cursor: 'default' });
      }
    }
  });
  $.fn.dragscroller = function(o) {
    if (!o) o = {};
    return this.each(function() {
      new $.dragscroller(this, o);
    });
  };

})(jQuery);
