Dragger = Class.create({

	images: [],
	dragee: null, 
	mouseStart: null, 
	drageeStart: null, 
	drageeSize: null, 
	mbrMin: null,
	mbrMax: null,
	onDragStart: function() {},
	onDragStop: function() {},
	onDragging: function() {},

	initialize: function(extra) {
		this.mouseStart = new Coords();
		this.drageeStart = new Coords();
		this.drageeSize = new Coords();
		this.mbrMin = new Coords();
		this.mbrMax = new Coords(Number.MAX_VALUE, Number.MAX_VALUE);

		if (typeof extra != 'undefined') {
			Object.extend(this, extra);			
		}
		
		Event.observe(document, "mousemove", this.onMouseMove.bindAsEventListener(this));		
		Event.observe(document, "mouseup", this.onMouseUp.bindAsEventListener(this));		
	},
	
	register: function(item) {
		item.onMouseDown = this.onMouseDown.bindAsEventListener(this, item);
		Event.observe(item, "mousedown", item.onMouseDown);		
		this.images.push(item);
	},
	
	unregister: function(item) {
		if (item.onMouseDown) {
			Event.stopObserving(item, "mousedown", item.onMouseDown);
			delete item.onMouseDown;
		}
		this.images = this.images.without(item);
	},
	
	isDragging: function() {
		return (this.dragee != null); 
	},
	
	onMouseDown: function(event, image) {
		Event.stop(event);
		this.dragee = Event.element(event);
		this.drageeSize.setXy(this.dragee.getWidth(), this.dragee.getHeight());
		this.mouseStart.set(Event.pointer(event));
		this.drageeStart.setFromStyle(image);
		this.onDragStart(this.dragee);
		return false;
	},
	
	onMouseMove: function(event) {
		if (!this.isDragging()) return;
		Event.stop(event);
		var newCoords = (new Coords(Event.pointer(event)))
			.subtract(this.mouseStart)
			.add(this.drageeStart)
			.limit(this.mbrMin, this.mbrMax.subtract(this.drageeSize));
		this.dragee.style.left = newCoords.x + "px";
		this.dragee.style.top  = newCoords.y + "px";
		this.onDragging(this.dragee);
		return false;
	},
	
	onMouseUp: function(event) {
		if (this.isDragging()) {
			this.onDragStop(this.dragee); 
			this.dragee = null;
			return false;
		}
	}
	
});

