/**
 * Generic library used for drag and drop over HTML divs.
 *
 */
 
 
var currentDiv = null;
var containerDivId = null;
var collisionDivArray = new Array();
var colMap = new Object();
var arrayIndex = 0;
var initZIndex;

/**
 * Must be called before starting to dragg
 */
function initDrag(division) {
  containerDivId = division;
}

/**
 * Adds a DIV that can cause an event when dragging DIV goes over it
 */
function addCollisionDiv(colDivName) {
  collisionDivArray[arrayIndex] = colDivName;
  colMap[colDivName] = null;
  arrayIndex++;
}

/**
 * Must be called onmousedown event
 */
function startDragging(division) {

  // disable text selection
  if (typeof document.onselectstart!="undefined")
    document.getElementById(containerDivId).onselectstart=new Function ("return false");
  else{
    document.getElementById(containerDivId).onmousedown=new Function ("return false");
  }

  currentDiv = division;
  if (window.startEvent != null) {
    division = startEvent(currentDiv,containerDivId);
    if (division != null) {
      currentDiv = division;
    }
  }
  initZIndex = division.style.zIndex;
  currentDiv.style.zIndex = "100";
  currentDiv.style.cursor = "pointer";
  document.getElementById(containerDivId).onmousemove=function(e){mouseXY(e)}
}

/**
 * Must be called on container Div's onmouseup event
 */
function stopDragging() {
  if (currentDiv != null) {
    if (window.stopEvent != null) {
      stopEvent(currentDiv,checkCollision(), containerDivId);
    }
    currentDiv.style.cursor = "default";
    document.getElementById(containerDivId).onmousemove=null;
    currentDiv.style.zIndex = initZIndex;
    currentDiv = null;
  }
}

/**
 * Function used for calculating the new DIV position
 */
function mouseXY(e) {
  var curposx = window.event? event.clientX : e.clientX? e.clientX: "";
  var curposy = window.event? event.clientY : e.clientY? e.clientY: "";	
  var screenPageY = ( document.documentElement.scrollTop || document.body.scrollTop )
  
  curposy = curposy + screenPageY;
  
  var currentWidth = currentDiv.offsetWidth;
  var currentHeight = currentDiv.offsetHeight;

  var divPosX = 0;
  var divPosY = 0;
  
  var containerMaxX = 0;
  var containerMaxY = 0;
  
  var containerMinX = 0;
  var containerMinY = 0;
  
  if (document.getElementById(containerDivId).style.position != null && 
      (document.getElementById(containerDivId).style.position.indexOf("absolute") != -1 || 
       document.getElementById(containerDivId).style.position.indexOf("relative") != -1 )) {

    divPosX = curposx - currentWidth/2 - getAbsoluteLeft(document.getElementById(containerDivId));
    divPosY = curposy - currentHeight/2 - getAbsoluteTop(document.getElementById(containerDivId));
    
    containerMaxX = document.getElementById(containerDivId).offsetWidth;
    containerMaxY = document.getElementById(containerDivId).offsetHeight;
    
    containerMinX = 0;
    containerMinY = 0;
    
  }
  else {
    divPosX = curposx - currentWidth/2;
    divPosY = curposy - currentHeight/2;
    
    containerMinX = getAbsoluteLeft(document.getElementById(containerDivId));
    containerMinY = getAbsoluteTop(document.getElementById(containerDivId));
    
    containerMaxX = containerMinX + document.getElementById(containerDivId).offsetWidth;
    containerMaxY = containerMinY + document.getElementById(containerDivId).offsetHeight;
    
  }
	

  var outsideBounds = false;
  if (divPosX + currentWidth > containerMaxX) {
    divPosX = containerMaxX - currentWidth;
    outsideBounds = true;
  }
  else if (divPosX < containerMinX) {
    divPosX = containerMinX;
    outsideBounds = true;
  }
	
  if (divPosY + currentHeight > containerMaxY) {
    divPosY = containerMaxY - currentHeight;
    outsideBounds = true;
  }
  else if (divPosY < containerMinY) {
    divPosY = containerMinY;
    outsideBounds = true;
  }

	
  currentDiv.style.left= divPosX + "px"; 
  currentDiv.style.top= divPosY + "px";
	
  checkCollision();
  
  if (outsideBounds && window.onOutsideBoundaries != null) {
    onOutsideBoundaries(currentDiv, containerDivId);
  }
}

/**
 * Function that checks for collisions
 */
function checkCollision() {
  var collision = false;
  var collisionDivId = null;
	
  for (var i = 0; i < arrayIndex; i++) {
  
    var collision = false;
    
    var minX = 0;
    var minY = 0;
    var maxX = 0;
    var maxY = 0;

    var curPosX = 0;
    var curPosY = 0;
		
		
    if (document.getElementById(containerDivId).style.position != null && 
        (document.getElementById(containerDivId).style.position.indexOf("absolute") != -1 || 
         document.getElementById(containerDivId).style.position.indexOf("relative") != -1 )) {
       
      minX = getAbsoluteLeft(document.getElementById(collisionDivArray[i]));
      minY = getAbsoluteTop(document.getElementById(collisionDivArray[i]));
      maxX = minX + document.getElementById(collisionDivArray[i]).offsetWidth;
      maxY = minY + document.getElementById(collisionDivArray[i]).offsetHeight;
      curPosX = getAbsoluteLeft(currentDiv) + currentDiv.offsetWidth/2;
      curPosY = getAbsoluteTop(currentDiv) +  currentDiv.offsetHeight/2;
    
    } else {
    
      minX = getAbsoluteLeft(document.getElementById(collisionDivArray[i]));
      minY = getAbsoluteTop(document.getElementById(collisionDivArray[i]));
      maxX = minX + document.getElementById(collisionDivArray[i]).offsetWidth;
      maxY = minY + document.getElementById(collisionDivArray[i]).offsetHeight;
      curPosX = currentDiv.offsetLeft + currentDiv.offsetWidth/2;
      curPosY = currentDiv.offsetTop +  currentDiv.offsetHeight/2;
    }
	
	
    if (curPosX > minX && curPosX < maxX) {
      if (curPosY > minY && curPosY < maxY) {
        collision = true;
      }
    }
		
    if (collision) {
      collisionDivId = collisionDivArray[i];
      if (colMap[collisionDivArray[i]] == null) {
        colMap[collisionDivArray[i]] = "exists";
        if (window.onCollide != null) {
          onCollide(currentDiv, collisionDivArray[i], containerDivId);
        }
      }
    }
    else {
      if (colMap[collisionDivArray[i]] != null) {
      	colMap[collisionDivArray[i]] = null;
      	if (window.onUncollide != null) {
          onUncollide(currentDiv, collisionDivArray[i], containerDivId);
        }
      }
    }
  }
	
  return collisionDivId;
}

/**
 * Get the absolute top position
 */
function getAbsoluteTop(elem) {
  var left = 0;
  
  while (elem != null) {
    left += elem.offsetTop;
    elem = elem.offsetParent;
  }
  
  return left;
}

 
/**
 * Get the absolute left position
 */
function getAbsoluteLeft(elem) {
  var left = 0;
  
  while (elem != null) {
    left += elem.offsetLeft;
    elem = elem.offsetParent;
  }

  return left;
}
