
/* ---------------------------------------------- *\
 * dragDrop                                       *
 * ---------------------------------------------- *
 * 
 * Para usar:
 * <script language="javascript1.2" type="text/javascript" src="dragdrop.js"></script>
 * <script language="javascript1.2" type="text/javascript" defer>
 * // Liberar o que será movido:
 * setDragDrop('drag','id1','id2','id3'[ ...]);
 * // Travar o que não será movido:
 * setDragDrop('block','id1','id2','id3'[ ...]);
 * // Liberar o que será movido a partir de outro elemento:
 * setDragDrop('relation','id_da_chave_1','id_do_div_1','id_da_chave_2','id_do_div_2', [ ...]);
 * </script>
\* ---------------------------------------------- */

var isIE = (/msie/i.test(navigator.userAgent) && document.all); // é IExplorer?
var dragObj;           // objeto (atual) a ser movido
var dragTrue = false;  // algum objeto está sendo arrastado?
var bringToTop = false; // ao arrastar um objeto, passar ele para frente?
var dragDropList = []; // lista de IDs dos objetos para mover
var dragBlockList = []; // lista de IDs dos objetos vetados para mover
var dragRelations = {}; // lista de objetos para mover a partir de outros
var mX = 0;
var mY = 0;

var X = 0, Y = 0;

document.onmousedown = dragDrop;
document.onmouseup = new Function("dragTrue = false;");
document.onmousemove = function(evnt) { 
                       mX = (isIE ? event : (evnt || window.event)).clientX;
                       mY = (isIE ? event : (evnt || window.event)).clientY;
                         if(!dragTrue) return false;
                       dragObj.style.left = elX + (mX - X)+'px';
                       dragObj.style.top  = elY + (mY - Y)+'px';
                       return false; 
											 };

function dragDrop(ev) {
var objToMove = (isIE ? event.srcElement : ev.target);
  if(typeof(dragRelations[objToMove.id]) == 'string') {
  objToMove = document.getElementById(dragRelations[objToMove.id]);
  } else {
    while(objToMove && !isDragDrop(objToMove)) {
      if(inArray(dragBlockList, objToMove.id)) objToMove = document.getElementsByTagName('body')[0];
    objToMove = isIE ? (objToMove.parentElement || false) : (objToMove.parentNode || false);
    }
  }
  if(!objToMove) return;
	if(!objToMove.style.top || !objToMove.style.left) {
	var xy = absPos(objToMove);
	objToMove.style.top = xy.y+'px';
	objToMove.style.left = xy.x+'px';
	}
  if(/(absolute|relative)/.test(objToMove.style.position) == false) 
    objToMove.style.position = /^body$/i.test(objToMove.offsetParent.tagName) ? 
		  'absolute' : 'relative';
	//alert(objToMove.style.position);
  if(bringToTop) toTop(objToMove);
dragTrue = true;
dragObj = objToMove;
elX = parseInt(dragObj.style.left) || 0;
elY = parseInt(dragObj.style.top) || 0;
X = (isIE ? event : ev).clientX;
Y = (isIE ? event : ev).clientY;
}

function isDragDrop(obj) { 
return ((obj || false) && !/^(html|body)$/i.test(obj.tagName)) ? 
          inArray(dragDropList, obj.id) : false; 
}

function setDragDrop(typ) { //alert(typ);
  for(var i = 1; i < setDragDrop.arguments.length; i++) {
    if(typ == 'relation')   dragRelations[setDragDrop.arguments[i]] = setDragDrop.arguments[++i];
    else if(typ == 'drag')  dragDropList.push(setDragDrop.arguments[i]);
    else if(typ == 'block') dragBlockList.push(setDragDrop.arguments[i]);
	}
}

function inArray(arr, val, icase) {
  for(var i = 0; i < arr.length; i++) {
    if(typeof(icase) == 'function' && (icase(arr[i]) == icase(val))) return true;
    else if(icase && (arr[i].toLowerCase() == val.toLowerCase())) return true;
    else if(arr[i] == val) return true;
  }
return false;
}

function absPos(el) {
  for(var lx = 0, ly = 0; el != null; lx += el.offsetLeft, ly += el.offsetTop, el = el.offsetParent);
return { 'x': lx, 'y': ly }
}
