
Drag.Move = Drag.Base.extend({

	options: {
		droppables: [],
		container: false,
		overflown: [],
		setThisStyle: true
	},	
	
	initialize: function(el, options){
		this.setOptions(options);
		this.element = $(el);
		this.droppables = $$(this.options.droppables);
		this.container = $(this.options.container);
		pos = this.element.getStyle('position');		
		this.position = {'element': pos, 'container': false};		
		if (this.container) this.position.container = pos;						
		if (!['relative', 'absolute', 'fixed'].contains(this.position.element)) this.position.element = 'absolute';		
		var top = this.element.getStyle('top').toInt();
		var left = this.element.getStyle('left').toInt();
		if (this.position.element == 'absolute' && !['relative', 'absolute', 'fixed'].contains(this.position.container)){
			top = $chk(top) ? top : this.element.getTop(this.options.overflown);
			left = $chk(left) ? left : this.element.getLeft(this.options.overflown);
		} else {
			top = $chk(top) ? top : 0;
			left = $chk(left) ? left : 0;
		}
		if (this.options.setThisStyle) this.element.setStyles({'top': top, 'left': left, 'position': this.position.element});
		this.parent(this.element);		
	},

	start: function(event){
		this.overed = null;	
		if (this.container){
			var cont = this.container.getCoordinates();
			var el = this.element.getCoordinates();
			if (this.position.element == 'absolute' && !['relative', 'absolute', 'fixed'].contains(this.position.container)){
				this.options.limit = {
					'x': [cont.left, cont.right - el.width],
					'y': [cont.top, cont.bottom - el.height]
				};
			} else {
				this.options.limit = {
					'y': [0, cont.height - el.height],
					'x': [0, cont.width - el.width]
				};
			}
		}
		this.parent(event);
	},

	drag: function(event){		
		this.parent(event);
			var overed = this.out ? false : this.droppables.filter(this.checkAgainst, this).getLast();
			if (this.overed != overed){
				if (this.overed) this.overed.fireEvent('leave', [this.element, this]);
				this.overed = overed ? overed.fireEvent('over', [this.element, this]) : null;
			}			
		return this;
	},
	
	checkAgainst: function(el){
		el = el.getCoordinates();
		var now = this.mouse.now;
		return (now.x > el.left && now.x < el.right && now.y < el.bottom && now.y > el.top);
	},

	stop: function(){
		if(this.overed && !this.out){	
			this.overed.fireEvent('drop', [this.element, this])				
		}else{		
			this.element.fireEvent('emptydrop', this);
		}
		this.parent();
		return this;
	}

});

/*
Class: Element
	Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>.
*/

Element.extend({

	/*
	Property: makeDraggable
		Makes an element draggable with the supplied options.

	Arguments:
		options - see <Drag.Move> and <Drag.Base> for acceptable options.
	*/
	makeDraggable: function(options){
		return new Drag.Move(this, options);
	}

});