var BASEDRAG_oDragged = null;
var BASEDRAG_oZoneHovered = null;
var BASEDRAG_oaDropZones = new Array();
var BASEDRAG_nMaxDragWidth = 300;

var BASEDRAG_fOldMouseMove = document.onmousemove;
document.onmousemove = BASEDRAG_OnMouseMove;          

var BASEDRAG_fOldMouseUp = document.onmouseup;
document.onmouseup = BASEDRAG_OnMouseUp;          

var BASEDRAG_fOldOnLoad = document.body.onload;
document.body.onload = BASEDRAG_OnLoad;          


//************************************************************

function BASEDRAG_Over (el)
//       ~~~~~~~~~~~~~
{
  el.className = "Draggable";
}
//-------------------------------------------------------

function BASEDRAG_Out (el)
//       ~~~~~~~~~~~~
{
  el.className = "";
}
//-------------------------------------------------------

function BASEDRAG_DragStart (el)
//       ~~~~~~~~~~~~~~~~~~
{
  window.document.selection.empty();
  var oCopy = el.cloneNode(true);
  oCopy.onmouseover = null;
  oCopy.onmouseout = null;
  oCopy.className = "Dragged";
  var oDragged = document.createElement("DIV");
  oDragged.onmousedown = oCopy.onmousedown;
  oCopy.onmousedown = null;
  if (el.bPlainText)
    oCopy.innerHTML = oCopy.innerText;
  oDragged.appendChild(oCopy);
  oDragged.style.position = "absolute";
  document.body.appendChild(oDragged);
  if (oDragged.offsetWidth > BASEDRAG_nMaxDragWidth)
    oDragged.style.width = BASEDRAG_nMaxDragWidth;
  el.bCapture = false;
  if (el.bHide)
    el.style.display = "none";
  oDragged.bReplace = el.bHide;
  oDragged.bCapture = true;
  oDragged.oSource = el;
  oDragged.targetLeft = COMMON_MouseXToAbsoluteLeft(event.clientX) - oDragged.offsetWidth/2;
  oDragged.targetTop  = event.clientY + document.body.scrollTop - oDragged.offsetHeight/2;
  BASEDRAG_oDragged = oDragged;
  BASEDRAG_DragMove(oDragged);
}
//-------------------------------------------------------

function BASEDRAG_MouseDown (el)
//       ~~~~~~~~~~~~~~~~~~
{
  var oTextRoot = BASETEXT_GetContainerControl(el);
  BASEDRAG_oDragged = el;
  el.bCapture = true;
  el.bHide = oTextRoot.bHideDraggable;
  el.bPlainText = oTextRoot.bDragAsText;
  el.bRollBackIncorrect = oTextRoot.bRollbackIncorrectDrags;
}
//-------------------------------------------------------

function BASEDRAG_DragEnd (el, bRollBack)
//       ~~~~~~~~~~~~~~~~
{
  BASEDRAG_oDragged = null;
  if (bRollBack)
    COMMON_MoveElementToTarget(el, el.oSource, true);
  else
    el.parentNode.removeChild(el);
}
//-------------------------------------------------------

function BASEDRAG_DragMove (el)
//       ~~~~~~~~~~~~~~~~~
{
  if (el.bCapture)
  {
    window.document.selection.empty();
    el.style.pixelLeft = COMMON_MouseXToAbsoluteLeft(event.clientX) - el.offsetWidth  / 2;
    el.style.pixelTop  = event.clientY + document.body.scrollTop  - el.offsetHeight / 2;
    
    var oZone = BASEDRAG_FindHoveredDropZone();
    if (oZone != BASEDRAG_oZoneHovered)
    {
      if (BASEDRAG_oZoneHovered)
        BASEDRAG_DropOut(BASEDRAG_oZoneHovered);
      BASEDRAG_oZoneHovered = oZone;
      if (BASEDRAG_oZoneHovered)
        BASEDRAG_DropOver(BASEDRAG_oZoneHovered);
    }
  }
}
//-------------------------------------------------------

function BASEDRAG_MouseMove (el)
//       ~~~~~~~~~~~~~~~~~~
{
  if (el.bCapture)
  {
    if (el.oSource)
      BASEDRAG_DragMove(el);
    else
      BASEDRAG_DragStart(el);
  }
}
//-------------------------------------------------------

function BASEDRAG_OnMouseUp ()
//       ~~~~~~~~~~~~~~~~~~~~
{
  if (BASEDRAG_oDragged)
  {
    BASEDRAG_oDragged.bCapture = false;
    if (BASEDRAG_oDragged.oSource)
    {
      if (BASEDRAG_oZoneHovered && !BASEDRAG_oZoneHovered.bDisabled)
      {
        var sDraggedID = BASEDRAG_oDragged.firstChild.id;
        var sCorrects = "," + BASEDRAG_oZoneHovered.sCorrects + ",";
        var sDropped  = "," + BASEDRAG_oZoneHovered.sDropped + ",";
        var bDouble = (sDropped.indexOf("," + sDraggedID + ",") >= 0);
        var bCorrect = (sDraggedID && sCorrects.indexOf("," + sDraggedID + ",") >= 0 && !bDouble);
        var bDropToZone = (bCorrect || !BASEDRAG_oDragged.oSource.bRollBackIncorrect) && !bDouble;
        var oSource = BASEDRAG_oDragged.oSource;
        if (bDropToZone)
        {
          if (BASEDRAG_oZoneHovered.bSingleAnswer)
          {
            if (BASEDRAG_oZoneHovered.childNodes.length > 0)
            {
              BASEDRAG_oZoneHovered.removeChild(BASEDRAG_oZoneHovered.childNodes[BASEDRAG_oZoneHovered.childNodes.length - 1]);
              BASEDRAG_oZoneHovered.sDropped = "";
            }
          }
          var oDropped = BASEDRAG_oDragged.cloneNode(true);
          oDropped.style.position = "";
          oDropped.onmouseover = oDropped.onmouseout = oDropped.onmousedown = null;
          oDropped.firstChild.className = "Dropped";
          BASEDRAG_oZoneHovered.appendChild(oDropped);
          
          if (BASEDRAG_oZoneHovered.sDropped)
            BASEDRAG_oZoneHovered.sDropped += ",";
          else
            BASEDRAG_oZoneHovered.sDropped = "";
          BASEDRAG_oZoneHovered.sDropped += sDraggedID;
          BASEDRAG_DragEnd(BASEDRAG_oDragged, false);
        }
        else
          BASEDRAG_DragEnd(BASEDRAG_oDragged, !bDouble);
        
        BASEDRAG_DropOut (BASEDRAG_oZoneHovered);
        // fire "event"
        if (!bDouble)
        {
          if (typeof(OnDragDrop) == "function")
            OnDragDrop (bCorrect, oSource, BASEDRAG_oZoneHovered);
          else
            BASEDRAG_OnDragDrop (bCorrect, oSource, BASEDRAG_oZoneHovered);
        }
      }
      else
        BASEDRAG_DragEnd(BASEDRAG_oDragged, true);
    }
  }
  if (BASEDRAG_fOldMouseUp != null)
    BASEDRAG_fOldMouseUp();
}
//-------------------------------------------------------------------

function BASEDRAG_OnMouseMove ()
//       ~~~~~~~~~~~~~~~~~~~~
{
  if (BASEDRAG_oDragged)
    BASEDRAG_MouseMove(BASEDRAG_oDragged);

  if (BASEDRAG_fOldMouseMove != null)
    BASEDRAG_fOldMouseMove();
}
//-------------------------------------------------------------------

function BASEDRAG_OnLoad ()
//       ~~~~~~~~~~~~~~~
{
  BASEDRAG_CollectDropZones ();
  if (BASEDRAG_fOldOnLoad != null)
    BASEDRAG_fOldOnLoad();
  
}
//-------------------------------------------------------------------

function BASEDRAG_CollectDropZones ()
//       ~~~~~~~~~~~~~~~~~~~~~~~~~
{
  BASEDRAG_oaDropZones.length = 0;
  var oDivs = document.getElementsByTagName("DIV");
  for (var i = 0; i < oDivs.length; i++)
  {
    if (oDivs[i].className.substr(0,8) == "DropZone")
      BASEDRAG_oaDropZones.push(oDivs[i]);
  }
}
//-------------------------------------------------------------------

function BASEDRAG_FindHoveredDropZone ()
//       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
{
  for (var i = 0; i < BASEDRAG_oaDropZones.length; i++)
  {
    if (COMMON_IsPointInElement(BASEDRAG_oaDropZones[i], COMMON_MouseXToAbsoluteLeft(event.clientX), event.clientY + document.body.scrollTop))
    {
      return BASEDRAG_oaDropZones[i];
    }
  }
  return null;
}
//-------------------------------------------------------------------

function BASEDRAG_DropOver (el)
//       ~~~~~~~~~~~~~~~~~
{
  if (BASEDRAG_oDragged)
    el.className = "DropZoneOver";
}
//-------------------------------------------------------

function BASEDRAG_DropOut (el)
//       ~~~~~~~~~~~~~~~~
{
  el.className = "DropZone";
}
//-------------------------------------------------------

function BASEDRAG_OnDragDrop (bCorrect, elDropped, elDropZone)
//       ~~~~~~~~~~~~~~~~~~~
{
  alert ("DEFAULT " + (bCorrect ? "correct!" : "wrong...") + " " + elDropped.id + " over " + elDropZone.id);
}
//-------------------------------------------------------

function BASEDRAG_RemoveIDFromDropZoneCorrectList (elDropZone, sDraggableID)
//       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
{
  var sCorrects = "," + elDropZone.sCorrects + ",";
  sCorrects = sCorrects.replace("," + sDraggableID + ",", ",");
  sCorrects = sCorrects.substring(1, sCorrects.length - 1);
  elDropZone.sCorrects = sCorrects;
}
//-------------------------------------------------------
