if(! Fx.Scroll)
{
	Fx.Scroll = new Class({
	
		Extends: Fx,
	
		options: {
			offset: {x: 0, y: 0},
			wheelStops: true
		},
	
		initialize: function(element, options){
			this.element = this.subject = document.id(element);
			this.parent(options);
			var cancel = this.cancel.bind(this, false);
	
			if ($type(this.element) != 'element') this.element = document.id(this.element.getDocument().body);
	
			var stopper = this.element;
	
			if (this.options.wheelStops){
				this.addEvent('start', function(){
					stopper.addEvent('mousewheel', cancel);
				}, true);
				this.addEvent('complete', function(){
					stopper.removeEvent('mousewheel', cancel);
				}, true);
			}
		},
	
		set: function(){
			var now = Array.flatten(arguments);
			if (Browser.Engine.gecko) now = [Math.round(now[0]), Math.round(now[1])];
			this.element.scrollTo(now[0], now[1]);
		},
	
		compute: function(from, to, delta){
			return [0, 1].map(function(i){
				return Fx.compute(from[i], to[i], delta);
			});
		},
	
		start: function(x, y){
			if (!this.check(x, y)) return this;
			var scrollSize = this.element.getScrollSize(),
				scroll = this.element.getScroll(), 
				values = {x: x, y: y};
			for (var z in values){
				var max = scrollSize[z];
				if ($chk(values[z])) values[z] = ($type(values[z]) == 'number') ? values[z] : max;
				else values[z] = scroll[z];
				values[z] += this.options.offset[z];
			}
			return this.parent([scroll.x, scroll.y], [values.x, values.y]);
		},
	
		toTop: function(){
			return this.start(false, 0);
		},
	
		toLeft: function(){
			return this.start(0, false);
		},
	
		toRight: function(){
			return this.start('right', false);
		},
	
		toBottom: function(){
			return this.start(false, 'bottom');
		},
	
		toElement: function(el){
			var position = document.id(el).getPosition(this.element);
			return this.start(position.x, position.y);
		},
	
		scrollIntoView: function(el, axes, offset){
			axes = axes ? $splat(axes) : ['x','y'];
			var to = {};
			el = document.id(el);
			var pos = el.getPosition(this.element);
			var size = el.getSize();
			var scroll = this.element.getScroll();
			var containerSize = this.element.getSize();
			var edge = {
				x: pos.x + size.x,
				y: pos.y + size.y
			};
			['x','y'].each(function(axis) {
				if (axes.contains(axis)) {
					if (edge[axis] > scroll[axis] + containerSize[axis]) to[axis] = edge[axis] - containerSize[axis];
					if (pos[axis] < scroll[axis]) to[axis] = pos[axis];
				}
				if (to[axis] == null) to[axis] = scroll[axis];
				if (offset && offset[axis]) to[axis] = to[axis] + offset[axis];
			}, this);
			if (to.x != scroll.x || to.y != scroll.y) this.start(to.x, to.y);
			return this;
		},
	
		scrollToCenter: function(el, axes, offset){
			axes = axes ? $splat(axes) : ['x', 'y'];
			el = $(el);
			var to = {},
				pos = el.getPosition(this.element),
				size = el.getSize(),
				scroll = this.element.getScroll(),
				containerSize = this.element.getSize(),
				edge = {
					x: pos.x + size.x,
					y: pos.y + size.y
				};
	
			['x','y'].each(function(axis){
				if(axes.contains(axis)){
					to[axis] = pos[axis] - (containerSize[axis] - size[axis])/2;
				}
				if(to[axis] == null) to[axis] = scroll[axis];
				if(offset && offset[axis]) to[axis] = to[axis] + offset[axis];
			}, this);
			if (to.x != scroll.x || to.y != scroll.y) this.start(to.x, to.y);
			return this;
		}
	
	});
}
