function MMO(){
	this.currentLeft = 0;
	this.currentTop = 0;
	this.deltaX = 0;
	this.deltaY = 0;
	this.onchange = new DOMEvent();
}
MMO.prototype.start = function(e){
	this.currentLeft = e.clientX;
	this.currentTop = e.clientY;
	this.offsetX = e.offsetX || e.layerX;
	this.offsetY = e.offsetY || e.layerY;
}
MMO.prototype.change = function(e){
	var ev = window.event || e;
	this.deltaX = ev.clientX - this.currentLeft;
	this.deltaY = ev.clientY - this.currentTop;
	this.currentLeft = ev.clientX;
	this.currentTop = ev.clientY;
	this.onchange.fire(this.deltaX, this.deltaY);

}
function DragDrop(oMov, handles, IDLE){
	this.moveable = moveable.detectMoveable(oMov);
	this.moveable._IDLE = IDLE || false;
	this.mmo = new MMO();
	this.mmo.onchange.register("move", function(x, y){
		this.moveable.moveBy(x, y);
	}.bind(this))
	this.elem = this.moveable.elem;
	this.handles = DragDrop.detectHandles(handles, this.elem);
	this.currentMouseLeft = null;
	this.currentMouseTop = null;
	this.ondragstart = new DOMEvent(this);
	this.ondrag = DOMEvent.cloneEvent(this.moveable.onmove, this);
	this.ondrop = new DOMEvent(this);
	this._events = [
		{name: "dragstart", func_name: "_start"}	
	];
	this.mouse_x = 0;
	this.mouse_y = 0;
	this.active_handle = null;
	this.IS_DRAGGING = false;
	this.init();
	if(this.constructor._TO_INSTANCES){
		this.constructor._instances.push(this);
	}
}
DragDrop.prototype.init = function(){
	this.initEvents();
	this.init_handles();
}
DragDrop.prototype.initEvents = _initEvents;
DragDrop.prototype.init_handles = function(){
	this.handles.each(function(handle){
		handle.onselectstart = function(){return false;}
		handle.onmousedown = function(e, oHandle){
			var _handle = oHandle || e; //ev in case of IE
			var ev = window.event || e;
			var x = ev.offsetX || ev.layerX;
			var y = ev.offsetY || ev.layerY;
			this.active_handle = _handle;
			this.mouse_x = x;
			this.mouse_y = y;
			this.start(ev);
		}.bind(this, handle);
	}.bind(this));
}
DragDrop.prototype.start = function(e){
	var ev = e || window.event;
	this.mmo.start(ev);
	this.curr_pageXOffset = window.pageXOffset;
	this.curr_pageYOffset = window.pageYOffset;
	this._start();
	return false;
}
DragDrop.prototype._start = function(){
	this.IS_DRAGGING = true;
	document.onmousemove = this.mmo.change.bind(this.mmo);
	window.onscroll = this.scroll.bind(this);
	DragDrop.mouseup = this.drop.bind(this);
	AttachEvent(document, "mouseup", DragDrop.mouseup);
	document.onselectstart = document.onmousedown = function(){
		return false;
	}
}
DragDrop.prototype.drop = function(e){
	this.IS_DRAGGING = false;
	document.onmousemove = null;
	window.onscroll = null;
	DetachEvent(document, "mouseup", DragDrop.mouseup);
	document.onselectstart = document.onmousedown = null;
	this.ondrop.fire();
}
/*
DragDrop.prototype.move = function(e){
	var ev = window.event || e;
	var mLeft = ev.clientX;
	var mTop = ev.clientY;
	this.moveable.moveBy(mLeft - this.currentMouseLeft, mTop - this.currentMouseTop);
	this.currentMouseLeft = mLeft;
	this.currentMouseTop = mTop;
}
*/
DragDrop.prototype.scroll = function(e){
	var deltaX = window.pageXOffset - this.curr_pageXOffset;
	var deltaY = window.pageYOffset - this.curr_pageYOffset;
	this.moveable.moveBy(deltaX, deltaY);
	this.curr_pageXOffset = window.pageXOffset;
	this.curr_pageYOffset = window.pageYOffset;
}
DragDrop.prototype.__name = "DragDrop";
DragDrop.prototype.toString = __toString;

DragDrop.detectHandles = function(handles, el){
	var ret;
	if(typeof handles == "string"){
		ret = $C(handles, el) || [el];
	}else if(handles instanceof Array){
		ret = handles;
	}else if(typeof handles == "object" && handles.nodeName){
		ret = [handles];
	}else if(typeof handles == "undefined" || typeof handles == "boolean"){
		ret = [el];
	}
	return ret;
}
DragDrop.mouseup = null;
DragDrop._TO_INSTANCES = true;
DragDrop._instances = [];
DragDrop.__loaded = true;