var dragdrop = {

	dragging : false,
	x : 0,
	y : 0,
	el : null,
	tx : 0,
	ty : 0,
	regX : new RegExp("\\bdrag-(x)\\b"),
	regY : new RegExp("\\bdrag-(y)\\b"),
	regCopy : new RegExp("\\bdrag-(copy)\\b"),
	zIndex : 1,
	ondrop : null,
	ondragstart : null,

	init : function()
	{
		dragdrop.bind();
		events.add(window, "unload", dragdrop.dispose, false);
	},

	bind : function()
	{
		var els = document.getElementsByTagName("*");
		var regex = new RegExp("\\bdraggable\\b");
		
		for (var i=0;i<els.length;i++)
		{
			var el = els[i];
			if ((el) && (dragdrop.regX.test(el.className) || (dragdrop.regY.test(el.className))))
			{
				/* cache width and height*/
				if (dragdrop.regX.test(el.className)) el.dragX=true;
				if (dragdrop.regY.test(el.className)) el.dragY=true;
				if (dragdrop.regCopy.test(el.className)) el.copy=true;
			
				events.add(el, "mousedown", dragdrop.select);
			}
		}
	},
	
	select : function(e)
	{
		var e = (e) ? e : event;
		var el = (e.target) ? e.target : e.srcElement;

		if ((el) && ((el.dragX) || (el.dragY)))
		{
			var pos = support.getPos(el);

			if (el.copy)
			{
				var element = el.cloneNode(true);
				element.style["position"] = "absolute";
				element.style["top"] = pos.y + "px";
				element.style["left"] = pos.x + "px";
				element.style["width"] = pos.w + "px";
				element.style["height"] = pos.h + "px";
				element.dragX = el.dragX
				element.dragY = el.dragY;
				element.copied=true;
				document.body.appendChild(element);
				el=element;
			}
			
			// fire dragdrop event
			if (dragdrop.ondragstart)
			{
				var o = dragdrop.ondragstart(el,pos.x,pos.y);
				if (o) el=o;
			}

			dragdrop.dragging	= true;
			dragdrop.el			= el;
			el.className		+= " dragging";
			dragdrop.tx			= pos.x;
			dragdrop.ty			= pos.y;
			dragdrop.x			= e.clientX;
			dragdrop.y			= e.clientY;
			dragdrop.zIndex		= el.style["zIndex"];
			el.style["zIndex"]	= 1000;
			
			/* assign drag movment */
			events.add(document, "mousemove", dragdrop.move, false);
			events.add(document, "mouseup", dragdrop.clear, false);
			
			events.add(document, "selectstart", events.cancel, false);
			events.add(document, "mousedown", events.cancel, false);	
			events.add(document, "mouseover", events.cancel, false);
		}
	},
	
	clear : function()
	{
		if ((dragdrop.dragging) && (dragdrop.el))
		{
			dragdrop.dragging			= false;
			dragdrop.el.className		= dragdrop.el.className.replace(new RegExp("\\bdragging\\b"), "");
			dragdrop.el.style["zIndex"] = dragdrop.zIndex;
			
			events.remove(document, "mousemove", dragdrop.move, false);
			events.remove(document, "mouseup", dragdrop.clear);
			events.remove(document, "selectstart", events.cancel, false);
			events.remove(document, "mousedown", events.cancel);
			events.remove(document, "mouseover", events.cancel);
			
			// fire dragdrop event and pass paramaters
			if (dragdrop.ondrop)
			{
				var pos = support.getPos(dragdrop.el);
				dragdrop.ondrop(dragdrop.el, pos.x,pos.y);//Math.max(pos.x + pos.w,0),pos.y + pos.h);
			}
			
			// remove reference to element
			dragdrop.el	= null;
		}
	},

	move : function(e)
	{
		if ((dragdrop.dragging) && (dragdrop.el))
		{
			var e = (e) ? e : event;
			
			if (dragdrop.el.dragX) dragdrop.el.style["left"] = (dragdrop.tx + e.clientX - dragdrop.x) + "px";
			if (dragdrop.el.dragY) dragdrop.el.style["top"]	= (dragdrop.ty + e.clientY - dragdrop.y) + "px";
			
			return false;
		}
	},
	
	dispose : function()
	{
		el = null; regX = null; regY = null; regCopy = null;
	}
}

/* register */
events.add(window, "load", dragdrop.init, false);