
//##############################################################################
// MOVABLE AND FLOATABLE MENU FUNCTIONS
//##############################################################################

var userMoveEvent=null;      // variable for saving users' mousemove event



// Ban the ability to select document content if the menu is in a moving process
if (b_IEComp)
{
  d_o.onselectstart = function() { return (moveRec.isMoving?false:true) }
}



function dm_getEventXY(e) {
 with (e) return [(b_IE||b_OP)?clientX:pageX, (b_IE||b_OP)?clientY:pageY];
}


function dm_getObjectStyleXY(obj)
// Returns [x,y] coords from object's style
{
  with (obj) return [offsetLeft, offsetTop];
//  return [parseInt(obj.style.left), parseInt(obj.style.top)];
}


function dm_startMoving(e, smID)
{
  with (moveRec)
  {
      if (!isLoaded || isMoving) return;

      smObj = dm_getObjectByID(smID);
      var mouseXY = dm_getEventXY(e);
      var mXY     = dm_getObjectSize(smObj);
      var pageOff = (b_IEComp?dm_getPageScrolling():[0,0]);

      cX = mouseXY[0] - mXY[0] + pageOff[0];
      cY = mouseXY[1] - mXY[1] + pageOff[1];
      smVar  = dm_getVarByID(smID);
      isMoving = true;                          // capture current menu

  }
}

function dm_stopMoving()
{
  with (moveRec)
  {
      if (!isLoaded || !isMoving) return;
      var pageOff = dm_getPageScrolling();
      var mXY     = dm_getObjectStyleXY(smObj);
      smVar.left  = mXY[0] - pageOff[0];
      smVar.top   = mXY[1] - pageOff[1];;
      isMoving = false;                         // uncapture current menu
  }
}


function dm_move(event)
// Sets new menu coords during a moving process
{
  if (moveRec.isMoving && isLoaded)
  {
      var mouseXY = dm_getEventXY(event);
      var pageOff = (b_IEComp?dm_getPageScrolling():[0,0]);
      var newX = mouseXY[0] - moveRec.cX + pageOff[0];
      var newY = mouseXY[1] - moveRec.cY + pageOff[1];

      with (moveRec)
      {
          smObj.style.left = ((newX>=0) ? newX : 0) + 'px';
          smObj.style.top  = ((newY>=0) ? newY : 0) + 'px';
          smVar.isMoved = 1;

          dm_showIFrame(smObj);
          if (dmObjectsCheck)
          {
              dm_showIntersectedObjects(smVar);
              dm_checkSubmenuIntersection(smVar, dm_getObjectSize(smObj));
          }
      }
  }
  return true;
}


function dm_assignMoveEvent()
// Assigns mousemove event to document
{
  if (document.attachEvent) document.attachEvent("onmousemove", dm_move);
  else
  {
      userMoveEvent = document.onmousemove;        // remember user event
      document.onmousemove = function(e)         // create new mousemove event
                             {
                                 dm_move(b_IEMAC?window.event:e);
                                 if (userMoveEvent) userMoveEvent(e);    // call users' event
                                 return true;
                             }
  }
}



function dm_getPageScrolling() {
  return [(b_IEComp?docElement.scrollLeft:pageXOffset), (b_IEComp?docElement.scrollTop:pageYOffset)]
}


function dm_scrollWindow()
// Assigned to scroll page event for floatable menu
{
  if (moveRec.isMoving) return;

  for (var i=0; i<dm_menu.length; i++)
  {
      if (dm_menu[i])
          with (dm_menu[i])
          {
              if (floating && absPos)
              {
                  var mObj    = dm_getObjectByID(m[0].id);
                  var mXY     = dm_getObjectStyleXY(mObj);

                  //window.status = mXY;

                  var pageOff = dm_getPageScrolling();
                  var x       = pageOff[0] + parseInt(m[0].left);
                  var y       = pageOff[1] + parseInt(m[0].top);


                  if (mXY[0]!=x || mXY[1]!=y)
                  {

                      if (floatableX)
                      {
                          var dx = (x-mXY[0]) / iterations;
                          with (Math) if (abs(dx)<1) dx = abs(dx)/dx;
                          mObj.style.left = parseInt(mXY[0] + ((mXY[0]!=x)?dx:0)) + 'px';
                      }
                      if (floatableX)
                      {
                          var dy = (y-mXY[1]) / iterations;
                          with (Math) if (abs(dy)<1) dy = abs(dy)/dy;
                          mObj.style.top  = parseInt(mXY[1] + ((mXY[1]!=y)?dy:0)) + 'px';
                      }

                      // Objects intersection ----------------------------------
                      with (dm_menu[i])
                      {
                          var smObj = dm_getObjectByID(m[0].id);
                          dm_showIFrame(smObj);
                          if (dmObjectsCheck)
                          {
                              dm_showIntersectedObjects(m[0]);
                              dm_checkSubmenuIntersection(m[0], dm_getObjectSize(smObj));
                          }
                      }
                  }
              }
          }//with
  }
}



//##############################################################################
// OBJECTS INTERSECTION FUNCTIONS
//##############################################################################


function dm_ptInRect(x, y, r) {
  return (x>=r.x1 && x<=r.x2 && y>=r.y1 && y<=r.y2)?1:0;
}


function dm_vertPartIntersectRect(x, y1, y2, r) {
  return (x>=r.x1 && x<=r.x2 && y1<=r.y1 && y2>=r.y2)?1:0;
}

function dm_horizPartIntersectRect(x1, x2, y, r) {
  return (y>=r.y1 && y<=r.y2 && x1<=r.x1 && x2>=r.x2)?1:0;
}


function dm_isDiagonalIntersect(r, tr)
{
  if ((dm_ptInRect(r.x1, r.y1, tr) + dm_ptInRect(r.x2, r.y2, tr)) ||
      (dm_ptInRect(r.x1, r.y2, tr) + dm_ptInRect(r.x2, r.y1, tr)) ) return 1;
  return 0;
}


function dm_rectIntersectRect(r, tr)
// Checks if rect intersects another one
{
  // Check corners (diagonal intersection)
  if (dm_isDiagonalIntersect(r, tr) || dm_isDiagonalIntersect(tr, r)) return 1;

  // Check sides
  if (dm_vertPartIntersectRect (r.x1, r.y1, r.y2, tr) || dm_vertPartIntersectRect (r.x2, r.y1, r.y2, tr) ||
      dm_horizPartIntersectRect(r.y1, r.x1, r.x2, tr) || dm_horizPartIntersectRect(r.y2, r.x1, r.x2, tr)) return 1;

  return 0;
}


function dm_getRectFromSize(r, size)
// Converts array of sizes to rect type
{
  with (r)
  {
      x1 = size[0];   x2 = size[0]+size[2];
      y1 = size[1];   y2 = size[1]+size[3];
  }
}


function dm_hideIntersectedObjects(smVar, smSize, objTagName)
// Checks submenus' intersection with objects on page by tag name and hides inersected objects
{
  if (b_OP & b_VER<6) return;
  var menu = dm_menu[smVar.mInd];

  var frame = (!menu.isCrossFrame || cfType==3) ? window : parent.frames[menu.cfSFInd];
  var objs  = frame.document.getElementsByTagName(objTagName);
  if (!objs) return;

  var oSize, o;
  var smR = {x1:0, y1:0, x2:0, y2:0};
  var oR  = {x1:0, y1:0, x2:0, y2:0};
  dm_getRectFromSize(smR, smSize);

  for (var i=0; i<objs.length; i++)                                           // don't use ln() prototype instead length property
  {
      o = objs[i];
      oSize = dm_getObjectSize(o);
      dm_getRectFromSize(oR, oSize);
      if (o.style && !o.dm)                                                   // check for special object attribute 'dm' -> don't hide the object
      {
          //alert(smR.x1+'  '+smR.y1+'  '+smR.x2+'  '+smR.y2+' : '+
          //      oR.x1+'  '+oR.y1+'  '+oR.x2+'  '+oR.y2+' : ')
          if (o.style.visibility!='hidden' && dm_rectIntersectRect(smR, oR))
          {
              o.style.visibility = 'hidden';
              smVar.hidObjs[smVar.hidObjs.ln()] = o;
          }
      }

  }
}


function dm_showIntersectedObjects(smVar)
// Shows object that were hidden by specified submenu
{
  with (smVar)
  {
      for (var j=0; j<hidObjs.ln(); j++) hidObjs[j].style.visibility = 'visible';
      hidObjs = [];
  }
}


function dm_checkSubmenuIntersection(smVar, smSize)
// Checks submenus' intersection with specified objects on page.
// Individual rule (function) can be created for each type of objects.
{
  var hIE = (b_IE && (b_VER<6 || useHTTPS));

  if (typeof(dm_ext_ruleIFrameHide)=='function')
  {
    if (dm_ext_ruleIFrameHide())
      dm_hideIntersectedObjects(smVar, smSize, 'IFRAME');
  }
  else
    if (hIE || (b_OP && b_VER<9) || (b_NS && b_VER<7 /*&& !b_SAF*/))
      dm_hideIntersectedObjects(smVar, smSize, 'IFRAME');
      
  if (typeof(dm_ext_ruleObjectHide)=='function')
  {
    if (dm_ext_ruleObjectHide())
    {
      dm_hideIntersectedObjects(smVar, smSize, 'OBJECT');
      dm_hideIntersectedObjects(smVar, smSize, 'EMBED');
    }
  }
  else
    if (hIE || (b_NS && b_VER>=7) || (b_MZ) || (b_OP))
    {
      dm_hideIntersectedObjects(smVar, smSize, 'OBJECT');
      dm_hideIntersectedObjects(smVar, smSize, 'EMBED');
    }


  if (typeof(dm_ext_ruleSelectHide)=='function')
  {
    if (dm_ext_ruleSelectHide())
      dm_hideIntersectedObjects(smVar, smSize, 'SELECT');
  }
  else
    if (hIE || (b_OP && b_VER<7))
      dm_hideIntersectedObjects(smVar, smSize, 'SELECT');


  if (typeof(dm_ext_ruleInputHide)=='function')
  {
    if (dm_ext_ruleInputHide())
    {
      dm_hideIntersectedObjects(smVar, smSize, 'TEXTAREA');
      dm_hideIntersectedObjects(smVar, smSize, 'INPUT');
    }
  }
  else
    if (b_OP && b_VER<7)
    {
      dm_hideIntersectedObjects(smVar, smSize, 'TEXTAREA');
      dm_hideIntersectedObjects(smVar, smSize, 'INPUT');
    }


  if (typeof(dm_ext_ruleAppletHide)=='function')
  {
    if (dm_ext_ruleAppletHide())
      dm_hideIntersectedObjects(smVar, smSize, 'APPLET');
  }
  else
    if (hIE || b_OP)
      dm_hideIntersectedObjects(smVar, smSize, 'APPLET');
}
