/**
 *  object for effects with div elements (fading, animation, drag'n drop, ...)
 *
 *  @author   Tobias Hettinger
 *  @version  $Id: diveffects.js,v 1.28 2009/04/07 12:23:21 tobias Exp $
 */


//=====================================================================================================================
//  div events
//=====================================================================================================================

/**
 *  constructor of the OnDivEffectsModify event
 */
function WATDivEffectsModifyEvent()
{
  //  set the member variables
  this.eventHandlers = new Array();
}

/**
 *  function to register the passed event handler
 */
WATDivEffectsModifyEvent.prototype.AddHandler = function(eventHandler)
{
  this.eventHandlers.push(eventHandler);
}

/**
 *  function to raise the event
 *
 *  @param class divEffects  div effects object that raised the event
 *  @param int   flags       flags of the event
 *                           - 1 - moving has been finished
 *                           - 2 - movement in progress
 *                           - 3 - resizing in progress
 */
WATDivEffectsModifyEvent.prototype.Raise = function(divEffects, flags)
{
  for(var i=0; i<this.eventHandlers.length; i++)
    this.eventHandlers[i](divEffects, flags);
}

//  create an instance of the OnDivEffectsModify event
WATOnDivEffectsModify = new WATDivEffectsModifyEvent();


//=====================================================================================================================
//  div effects manager
//=====================================================================================================================
 
/**
 *  constructor
 * 
 *  @param string name   name of the div effects object (this is required e.g. for setTimeout calls)
 *  @param string divId  id of the div to control
 */
var WATDivEffects = function(name, divId)
{
  //  set the member variables
  this.name = name;
  this.divId = divId;
  this.divElement = document.getElementById(divId);
  this.initialized = true;

  //  check if the div exists
  if (this.divElement == null)
  {
    this.initialized = false;
    alert('WATDivEffects: The div with id "' + divId + '" does not exist.');
  }
  
  //  flag that notifies that fading is just in progress
  this.fading = false;
  //  last fading command (0: unknown, 1: fade in, 2: fade out)
  this.lastFadeCommand = 0;
  this.lastFadeTime = 0;
  
  //  user interactive movement
  this.enableMouseMove = false;
  this.enableResizeWidth = false;
  this.enableResizeHeight = false;
  this.eventsRegistered = false;
  this.overlayDivElement = null;
  this.hasFocus = false;
  this.moving = false;
  this.resize = 0;  // 1: top, 2: top/left, 3: left, 4: bottom:left, 5: bottom, 6: bottom/right, 7: right, 8:top/right
  this.resizeBorderTop = 10;
  this.resizeBorderBottom = 10;
  this.resizeBorderLeft = 10;
  this.resizeBorderRight = 10;
  this.resizeOffsetTop = 0;
  this.moveFrameTop = -1;
  this.moveFrameLeft = -1;
  this.moveFrameHeight = -1;
  this.moveFrameWidth = -1;
  this.moveFrameWidthOffset = 0;
  this.moveFrameHeightOffset = 0;
  this.keepAspectRatio = false;
  this.keepAspectRatioEdge = false;
  this.moveOffsetX = 0;
  this.moveOffsetY = 0;
  this.moveGridX = 5;
  this.moveGridY = 5;
  this.topDiff = 0;
  this.leftDiff = 0;
  this.modifyCurrentTop = 0;
  this.modifyCurrentLeft = 0;
  this.modifyCurrentWidth = 0;
  this.modifyCurrentHeight = 0;
}


//=====================================================================================================================
//  object management
//=====================================================================================================================

/**
 *  function to remove the div element from the document
 *  
 *  after executing this function, the diveffects object can be deleted
 */
WATDivEffects.prototype.RemoveDiv = function()
{
  if (this.initialized)
  {
    //  remove the div element
    var divParent = this.divElement.parentNode;
    if (divParent) divParent.removeChild(this.divElement);
    delete this.divElement;
    
    //  stop all actions of the div effects class
    this.initialized = false;
  }
}


//=====================================================================================================================
//  opacity and fading
//=====================================================================================================================

/**
 *  function to set the opacity of the div
 *
 *  @param int opacity  opacity to set between 0 (invisible) and 1 (completely visible)
 */
WATDivEffects.prototype.SetOpacity = function(opacity)
{
  //  do nothing if the object is not initialized
  if (!this.initialized) return false;

  if (opacity == 1)
  {
    //  if no transparency is required, simply delete the filter
    if (WATBrowserInfo.IsIE)
      this.divElement.style.filter = "";
    else
      this.divElement.style.opacity = opacity;
  }
  else
  {
    //  set the opacity
    if (WATBrowserInfo.IsIE)
      this.divElement.style.filter="Alpha(opacity="+(opacity*100)+", finishopacity="+(opacity*100)+", style=1)";
    else
      this.divElement.style.opacity = opacity;
  }
}

/**
 *  function to get the opacity of the div
 *
 *  @return float  the function returns the opacity of the div as float (not as string)
 */
WATDivEffects.prototype.GetOpacity = function()
{
  //  do nothing if the object is not initialized
  if (!this.initialized) return 0;
  
  //  the function returns 0 if the opacity can not be determined
  var result = 0;

  //  in case of the Internet Explorer, the filter string has to be parsed
  if (WATBrowserInfo.IsIE)
  {
    var filter = this.divElement.style.filter;
    
    //  parse the filter string
    var startPos = filter.indexOf('opacity=');
    if (startPos > 0)
    {
      startPos += 8;
      var endPos = filter.indexOf(',', startPos);
      if (endPos > startPos)
      {
        var opacity = filter.substr(startPos, endPos-startPos);
        result = opacity / 100;
      }
    }
    else
    {
      //  there is no filter, opacity must be 1
      result = 1;
    }
  }
  else
  {
    //  get the opacity
    if (this.divElement.style.opacity) result = this.divElement.style.opacity;
  }
  
  //  return the opacity
  return parseFloat(result);
}

/**
 *  function to fade the div in
 *
 *  the function does nothing if the current opacity is higher than the required one
 *
 *  @param int opacity  opacity, the object should have when fading has finished (1-100, 0 fades to 100%)
 *  @param int msec     time in milliseconds to fade in (if the parameter is not defined, the time is set to 350 msec)
 */
WATDivEffects.prototype.FadeIn = function(opacity, msec)
{
  //  do nothing if the object is not initialized
  if (!this.initialized) return false;
  
  //  check the parameters
  if (!msec) msec = 350;
  if (!opacity || opacity < 0 || opacity > 100) opacity = 100;

  //  get the actual opacity
  var actOpacity = this.GetOpacity() * 100;
  if (!watDivIsDisplayed(this.divId)) actOpacity = 0;
  var opacityDiff = opacity - actOpacity;
  if (opacityDiff < 0) return false;
  
  //  set the flags
  this.lastFadeCommand = 1;
  this.lastFadeTime = msec;
  
  //  check if fading is possible
  if (this.fading) return false;
  this.fading = true;

  //  initialize the variables
  var step = 5;
  var speed = Math.round(msec / 100 * step); 
  var timer = 0;

  //  fade the div in
  for(i=0; i<=opacityDiff; i+=step)
  {
    setTimeout(this.name+".SetOpacity("+((actOpacity+i)/100)+");"+(i==0 ? "watDivDisplay('"+this.divId+"');" : "")+
              (i==opacityDiff ? this.name+".fading=false; "+this.name+".__FinishFading(1);" : ""),(timer*speed)); 
    timer++; 
  }
}

/**
 *  function to fade the div out
 *
 *  the function does nothing if the current opacity is lower than the required one
 *
 *  @param int opacity  opacity, the object should have when fading has finished (0-100)
 *  @param int msec     time in milliseconds to fade out (if the parameter is not defined, the time is set to 500 msec)
 */
WATDivEffects.prototype.FadeOut = function(opacity, msec)
{
  //  do nothing if the object is not initialized
  if (!this.initialized) return false;
  
  //  check the parameters
  if (!msec) msec = 500;
  if (!opacity || opacity < 0 || opacity > 100) opacity = 0;
 
  //  get the actual opacity
  var actOpacity = this.GetOpacity() * 100;
  var opacityDiff = opacity - actOpacity;
  if (opacityDiff > 0) return false;
 
  //  set the flags
  this.lastFadeCommand = 2;
  this.lastFadeTime = msec;
 
  //  check if fading is possible
  if (this.fading) return false;
  this.fading = true;
 
  //  initialize the variables
  var step = 5;
  var speed = Math.round(msec / 100 * step);
  var timer = 0;

  //  fade the div out
  for(i=actOpacity; i>=opacity; i-=step)
  { 
    setTimeout(this.name+".SetOpacity("+(i/100)+");"+(i==0 ? "watDivRemove('"+this.divId+"');" : "")+
              (i==opacity ? this.name+".fading=false; "+this.name+".__FinishFading(2);" : ""),(timer*speed)); 
    timer++;
  }
}

/**
 *  function that is called when fading finished. If fading-in finished but the last command was a fade-out,
 *  the fade-out function is triggered and vice versa.
 *
 *  @param int mode  mode of the fading function that has just finished
 *                   - 1 - the fade-in function has finished
 *                   - 2 - the fade-out function has finished
 */
WATDivEffects.prototype.__FinishFading = function(mode)
{
  //  fade out if the div was just faded in but the last command was a fade-out
  if (mode == 1 && this.lastFadeCommand == 2)
    this.FadeOut(0, this.lastFadeTime);
  
  //  fade in if the div was just faded out but the last command was a fade-in
  if (mode == 2 && this.lastFadeCommand == 1)
    this.FadeIn(100, this.lastFadeTime);
}


//=====================================================================================================================
//  size and movement
//=====================================================================================================================

/**
 *  function to get the width of the div even if it is not shown (display:none)
 *
 *  @return int  the function returns the width of the div as integer value (not as string)
 */
WATDivEffects.prototype.GetWidth = function()
{
  //  do nothing if the object is not initialized
  if (!this.initialized) return 0;
  
  //  the function returns 0 if the width could not be determined
  var width = 0;

  //  get the width and delete the 'px' string
  if (this.divElement.style.width)
  {
    width = this.divElement.style.width.replace(/ /, '');
    width = parseInt(width.replace(/px/i, ''));
  }
  else
  {
    //  check if the div is already displayed    
    var display = watDivIsDisplayed(this.divId);
    var opacity = this.GetOpacity();
    
    //  display the div with 100% transparency
    if (!display)
    {
      //  "show" the div
      this.SetOpacity(0);
      watDivDisplay(this.divId);
    }
    
    //  get the width of the div
    width = this.divElement.clientWidth;
    
    //  reset the display state
    if (!display)
    {
      this.SetOpacity(opacity);
      watDivRemove(this.divId);
    }
  }
  
  //  return the width of the div
  return width;
}

/**
 *  function to get the height of the div even if it is not shown (display:none)
 *
 *  @return int  the function returns the height of the div as integer value (not as string)
 */
WATDivEffects.prototype.GetHeight = function()
{
  //  do nothing if the object is not initialized
  if (!this.initialized) return 0;
  
  //  the function returns 0 if the height could not be determined
  var height = 0;
  
  //  get the height and delete the 'px' string
  if (this.divElement.style.height)
  {
    height = this.divElement.style.height.replace(/ /, '');
    height = parseInt(height.replace(/px/i, ''));
  }
  else
  {
    //  check if the div is already displayed    
    var display = watDivIsDisplayed(this.divId);
    var opacity = this.GetOpacity();
    
    //  display the div with 100% transparency
    if (!display)
    {
      //  "show" the div
      this.SetOpacity(0);
      watDivDisplay(this.divId);
    }
    
    //  get the height of the div
    height = this.divElement.clientHeight;
    
    //  reset the display state
    if (!display)
    {
      this.SetOpacity(opacity);
      watDivRemove(this.divId);
    }
  }

  //  return the height of the div
  return height;
}

/**
 *  function to get the left position of the div even if it is not shown (display:none)
 *
 *  @param bool absolute  if true, the absolute position of the div is returned
 *                        if false, the relative position to the position of the div's parent is returned
 *
 *  @return int  the function returns the left position of the div as integer value (not as string)
 */
WATDivEffects.prototype.GetLeft = function(absolute)
{
  //  do nothing if the object is not initialized
  if (!this.initialized) return 0;
  
  //  the function returns 0 if the position could not be determined
  var left = 0;

  //  get the left position and delete the 'px' string
  if (this.divElement.style.left && !absolute)
  {
    left = this.divElement.style.left.replace(/ /, '');
    left = parseInt(left.replace(/px/i, ''));
  }
  else
  {
    //  check if the div is already displayed    
    var display = watDivIsDisplayed(this.divId);
    var opacity = this.GetOpacity();
    
    //  display the div with 100% transparency
    if (!display)
    {
      //  "show" the div
      this.SetOpacity(0);
      watDivDisplay(this.divId);
    }
    
    //  get the left position
    if (absolute)
      left = watGetLeftPos(this.divElement);
    else
      left = this.divElement.clientLeft;
    
    //  reset the display state
    if (!display)
    {
      this.SetOpacity(opacity);
      watDivRemove(this.divId);
    }
  }
  
  //  return the left position
  return left;
}

/**
 *  function to get the top position of the div even if it is not shown (display:none)
 *
 *  @param bool absolute  if true, the absolute position of the div is returned
 *                        if false, the relative position to the position of the div's parent is returned
 *
 *  @return int  the function returns the top position of the div as integer value (not as string)
 */
WATDivEffects.prototype.GetTop = function(absolute)
{
  //  do nothing if the object is not initialized
  if (!this.initialized) return 0;
  
  //  the function returns 0 if the top position could not be determined
  var top = 0;
  
  //  get the top position and delete the 'px' string
  if (this.divElement.style.top && !absolute)
  {
    top = this.divElement.style.top.replace(/ /, '');
    top = parseInt(top.replace(/px/i, ''));
  }
  else
  {
    //  check if the div is already displayed    
    var display = watDivIsDisplayed(this.divId);
    var opacity = this.GetOpacity();
    
    //  display the div with 100% transparency
    if (!display)
    {
      //  "show" the div
      this.SetOpacity(0);
      watDivDisplay(this.divId);
    }
    
    //  get the top position
    if (absolute)
      top = watGetTopPos(this.divElement);
    else
      top = this.divElement.clientTop;
    
    //  reset the display state
    if (!display)
    {
      this.SetOpacity(opacity);
      watDivRemove(this.divId);
    }
  }
  
  //  return the top position
  return top;
}

/**
 *  function to set the width of the div
 *
 *  @param int width  new width of the div
 *  @param int align  alignment: 0 - left - the left position is fixed
 *                               1 - right - the right position is fixed
 *                               2 - center - the left and the right border are moved one half
 */
WATDivEffects.prototype.SetWidth = function(width, align)
{
  //  do nothing if the object is not initialized
  if (!this.initialized) return false;

  switch(align)
  {
    case 1 :
      this.divElement.style.left = (this.GetLeft() - (width-this.GetWidth()))+'px';
      this.divElement.style.width = width+'px';
      break;
  
    case 2 :
      this.divElement.style.left = (this.GetLeft() - ((width-this.GetWidth()) / 2))+'px';
      this.divElement.style.width = width+'px';
      break;
  
    default :
      this.divElement.style.width = width+'px';
      break;
  }
}

/**
 *  function to set the height of the div
 *
 *  @param int height  new height of the div
 *  @param int align   alignment: 0 - top - the top position is fixed
 *                                1 - bottom - the bottom position is fixed
 *                                2 - center - the top and the bottom border are moved one half
 *  @param int maxTop  maximum top position
 */
WATDivEffects.prototype.SetHeight = function(height, align, maxTop)
{
  //  do nothing if the object is not initialized
  if (!this.initialized) return false;

  switch(align)
  {
    case 1 :
      var top = this.GetTop();
      if (top >= maxTop) this.divElement.style.top = (top - (height-this.GetHeight()))+'px';
      this.divElement.style.height = height+'px';
      break;
  
    case 2 :
      this.divElement.style.top = (this.GetTop() - ((height-this.GetHeight()) / 2))+'px';
      this.divElement.style.height = height+'px';
      break;
  
    default :
      this.divElement.style.height = height+'px';
      break;
  }
}

/**
 *  function to move the div in an animated way
 *
 *  @param int top     new top position of the div or -1 if the top position should not be changed
 *  @param int left    new left position of the div or -1 if the left position should not be changed
 *  @param int width   new width of the div or -1 if the width should not be changed
 *  @param int height  new height of the div or -1 if the heigth should not be changed
 *  @param int maxTop  maximum top position
 */
WATDivEffects.prototype.Move = function(top, left, width, height, maxTop)
{
  //  do nothing if the object is not initialized
  if (!this.initialized) return false;
  
  var actWidth = this.GetWidth();
  var widthDiff = Math.abs(width - actWidth);
  var actHeight = this.GetHeight();
  var heightDiff = Math.abs(height - actHeight);

  var msec = 500;
  var timer = 0;
  var speed = Math.round(msec/100);
  
  for (i=0; i<=widthDiff; i=i+2)
  {
    var newWidth = width>actWidth ? actWidth+i : actWidth-i;
    setTimeout(this.name+".SetWidth("+newWidth+",0);", (timer*speed));
    timer++;
  }
  
  for (i=0; i<=heightDiff; i=i+2)
  {
    var newHeight = height>actHeight ? actHeight+i : actHeight-i;
    setTimeout(this.name+".SetHeight("+newHeight+", 1, "+maxTop+");", (timer*speed));
    timer++;
  }  
}

/**
 *  function to estimate the time an animated movement will take
 *
 *  @param int top     new top position of the div or -1 if the top position should not be changed
 *  @param int left    new left position of the div or -1 if the left position should not be changed
 *  @param int width   new width of the div or -1 if the width should not be changed
 *  @param int height  new height of the div or -1 if the heigth should not be changed
 */
WATDivEffects.prototype.GetMoveTime = function(top, left, width, height)
{
  //  do nothing if the object is not initialized
  if (!this.initialized) return false;
  
  var actWidth = this.GetWidth();
  var widthDiff = Math.abs(width - actWidth);
  var actHeight = this.GetHeight();
  var heightDiff = Math.abs(height - actHeight);
  
  var msec = 500;
  var speed = Math.round(msec/100);
  
  return (speed*(widthDiff/2) + speed*(heightDiff/2));
}


//=====================================================================================================================
//  mouse interactive movement
//=====================================================================================================================

/**
 *  function to setup the movement of the div
 *
 *  @param int mouseX  left position of the mouse that should be used to determine the move mode
 *  @param int mouseY  top position of the mouse that should be used to determine the move mode
 */
WATDivEffects.prototype.SetupMove = function(mouseX, mouseY)
{
  //  initialize the variables
  var top = this.GetTop(true);
  var left = this.GetLeft(true);
  var width = this.GetWidth();
  var height = this.GetHeight();
  var moveFrameExists = false;
  var requireOverlay = false;
  
  this.modifyCurrentTop = top;
  this.modifyCurrentLeft = left;
  this.modifyCurrentWidth = width;
  this.modifyCurrentHeight = height;
  this.topDiff = top - this.GetTop(false);
  this.leftDiff = left - this.GetLeft(false);

  this.moveOffsetX = mouseX - left;
  this.moveOffsetY = mouseY - top;
  
  //  move the div if a move frame is defined
  if (this.enableMouseMove && this.moveFrameTop > -1 && this.moveFrameLeft > -1 &&
     (this.moveFrameWidth > -1 || this.moveFrameHeight > -1))
  {
    var moveFrameWidth = this.moveFrameWidth > -1 ? this.moveFrameWidth : width;
    var moveFrameHeight = this.moveFrameHeight > -1 ? this.moveFrameHeight : height;
    moveFrameExists = true;
    
    if (this.moveOffsetX >= this.moveFrameLeft && this.moveOffsetY >= this.moveFrameTop &&
        this.moveOffsetX <= (this.moveFrameLeft + moveFrameWidth - this.moveFrameWidthOffset) &&
        this.moveOffsetY <= (this.moveFrameTop + moveFrameHeight - this.moveFrameHeightOffset))
    {
      this.moving = true;
      requireOverlay = true;
      document.body.style.cursor = 'move';
    }
  }
  
  //  get the resize mode if resizing is allowed
  if (!this.moving && (this.enableResizeWidth || this.enableResizeHeight))
  {
    if (this.moveOffsetX < this.resizeBorderLeft)
    {
      //  the cursor is in the left resize area
      if (this.moveOffsetY < this.resizeBorderTop)
      {
        //  the cursor is in the top/left resize area
        if (this.enableResizeWidth && this.enableResizeHeight) this.resize = 2;
          else if (this.enableResizeWidth) this.resize = 3;
                 else this.resize = 1;
      }
      else
      {
        if (height - this.moveOffsetY < this.resizeBorderBottom)
        {
          //  the cursor is in the bottom/left resize area
          if (this.enableResizeWidth && this.enableResizeHeight) this.resize = 4;
            else if (this.enableResizeWidth ) this.resize = 3;
                   else this.resize = 5;
        }
        else
        {
          //  the cursor is in the left resize area
          if (this.enableResizeWidth) this.resize = 3;
        }
      }
    }
    else
    {
      if (width - this.resizeBorderRight < this.moveOffsetX)
      {
        //  the cursor is in the right resize area
        if ((this.moveOffsetY + this.resizeOffsetTop) < this.resizeBorderTop)
        {
          //  the cursor is in the top/right resize area
          if (this.enableResizeWidth && this.enableResizeHeight) this.resize = 8;
            else if (this.enableResizeWidth) this.resize = 7;
                   else this.resize = 1;
        }
        else
        {
          if (height - this.moveOffsetY < this.resizeBorderBottom)
          {
            //  the cursor is in the bottom/right resize area
            if (this.enableResizeWidth && this.enableResizeHeight) this.resize = 6;
              else if (this.enableResizeWidth) this.resize = 7;
                     else this.resize = 5;
          }
          else
          {
            //  the cursor is in the right resize area
            if (this.enableResizeWidth && (this.moveOffsetY > this.resizeOffsetTop)) this.resize = 7;
          }
        }
      }
      else
      {
        if ((this.moveOffsetY + this.resizeOffsetTop) < this.resizeBorderTop)
        {
          //  the cursor is in the top resize area
          if (this.enableResizeHeight) this.resize = 1;
        }
        else
        {
          if (this.moveOffsetY > height - this.resizeBorderBottom)
          {
            //  the cursor is in the bottom resize area
            if (this.enableResizeHeight) this.resize = 5;
          }
        }
      }
    }
     
    //  set the mouse cursor
    switch(this.resize)
    {
      case 1 : document.body.style.cursor = 'n-resize'; break;
      case 2 : document.body.style.cursor = 'nw-resize'; break;
      case 3 : document.body.style.cursor = 'w-resize'; break;
      case 4 : document.body.style.cursor = 'sw-resize'; break;
      case 5 : document.body.style.cursor = 's-resize'; break;
      case 6 : document.body.style.cursor = 'se-resize'; break;
      case 7 : document.body.style.cursor = 'e-resize'; break;
      case 8 : document.body.style.cursor = 'ne-resize'; break;
    }
  }
  
  //  require the overlay div
  if (this.resize > 0) requireOverlay = true;
        
  //  no resizing, start moving
  if (!moveFrameExists && this.resize == 0 && this.enableMouseMove)
  {
    this.moving = true;
    requireOverlay = true;
    document.body.style.cursor = 'move';
  }
  
  //  show the overlay div if it is required
  if (requireOverlay)
  {
    //  create a new div if it does not yet exist
    if (!this.overlayDivElement)
    {
      //  create a new div
      this.overlayDivElement = document.createElement('div');
      this.overlayDivElement.style.position = 'absolute';
      this.overlayDivElement.style.backgroundColor = '#333333';
      this.overlayDivElement.style.top = '0px';
      this.overlayDivElement.style.left = '0px';
      this.overlayDivElement.style.zIndex = 99999;
      
      //  set the opacity
      if (WATBrowserInfo.IsIE)
        this.overlayDivElement.style.filter="Alpha(opacity="+(20)+", finishopacity="+(20)+", style=1)";
      else
        this.overlayDivElement.style.opacity = 0.3;
      
      //  add the overlay div to the div element
      var firstElement = this.divElement.firstChild;
      if (firstElement) this.divElement.insertBefore(this.overlayDivElement, firstElement);
        else this.divElement.appendChild(this.overlayDivElement);
    }
    
    //  show the overlay div
    this.overlayDivElement.style.width = width + 'px';
    this.overlayDivElement.style.height = height + 'px';
    this.overlayDivElement.style.display = 'block';
    this.__PrepareContent(this.divElement);
    setTimeout(this.name + '.__SetFocus();', 50);
  }
}

/**
 *  function to prepare the child elements of the passed node in order to make the div movable
 */
WATDivEffects.prototype.__PrepareContent = function(node)
{
  var node = node.firstChild;
  while(node)
  {
    switch(node.nodeName.toLowerCase())
    {
      //  disable drag'n drop for images that is the automatically done by the browser
      case 'img' :
        if (WATBrowserInfo.IsIE)
          node.ondrag = function() { return false; };
      //  and for firefox ??
      break;
    }
    
    //  parse the child elements of the current node
    var child = node.firstChild;
    if (child) this.__PrepareContent(child);
    
    //  get the next element
    node = node.nextSibling;
  }
}

/**
 *  function to set the focus to the div in order to be able to move it
 */
WATDivEffects.prototype.__SetFocus = function()
{
  this.divElement.focus();
}

/**
 *  function to enable or disable interactive movement of the div
 *
 *  @param bool enableMouseMove     enable(true) / disable(false) the possibility to move the div
 *  @param bool enableResizeWidth   enable(true) / disable(false) the possibility to resize the width of the div
 *  @param bool enableResizeHeight  enable(true) / disable(false) the possibility to resize the height of the div
 */
WATDivEffects.prototype.EnableMouseMove = function(enableMouseMove, enableResizeWidth, enableResizeHeight)
{
  //  do nothing if the object is not initialized
  if (!this.initialized) return false;

  //  set the member variables
  var obj = this;
  this.enableMouseMove = enableMouseMove;
  this.enableResizeWidth = enableResizeWidth;
  this.enableResizeHeight = enableResizeHeight;
    
  //  get the sum of horizontal scroll positions of the parent divs 
  function __GetParentScrollLeft(div)
  {
    //  initialize the variables
    var parent = div.parentNode;
    var result = 0;
   
    if (parent)
    {
      //  get the scroll positions of the parent elements
      result += __GetParentScrollLeft(parent);
      if (parent.nodeName.toLowerCase() == 'div') result += parent.scrollLeft;
    }
    
    return result;
  }
  
  //  get the sum of vertical scroll positions of the parent divs 
  function __GetParentScrollTop(div)
  {
    //  initialize the variables
    var parent = div.parentNode;
    var result = 0;
   
    if (parent)
    {
      //  get the scroll positions of the parent elements
      result += __GetParentScrollTop(parent);
      if (parent.nodeName.toLowerCase() == 'div') result += parent.scrollTop;
    }
    
    return result;
  }
  
  //  align the div on the grid
  function __AlignGrid(position, direction)
  {
    //  return the passed position if the grid is not active
    var result = position;
  
    //  vertical alignment
    if (direction == 1 && obj.moveGridY > 0)
    {
      var grid = (position % obj.moveGridY);
      if (grid < (obj.moveGridY / 2)) result = result - grid;
        else result = result + (obj.moveGridY - grid);
    }
    
    //  horizontal alignment
    if (direction == 2 && obj.moveGridX > 0)
    {
      var grid = (position % obj.moveGridX);
      if (grid < (obj.moveGridX / 2)) result = result - grid;
        else result = result + (obj.moveGridX - grid);
    }
    
    //  return the new position
    return result;
  }
  
  //  the OnFocus handler is called when the div gets the focus
  function __Focus()
  {
    obj.hasFocus = true;
  }
  
  //  the OnBlur handler is called when the div looses the focus
  function __Blur()
  {
    obj.hasFocus = false;
  }
  
  //  OnMouseDown handler that is called when the user presses a mouse button
  function __MouseDown(event)
  {
    obj.SetupMove(watMousePosX + __GetParentScrollLeft(obj.divElement),
                  watMousePosY + __GetParentScrollTop(obj.divElement));
  }
  
  //  OnMouseMove handler that is called when the user moves the mouse in order to move the div
  function __MouseMove()
  {
    //  make the input fields selectable (the div may not move if text in an input field is selected)
    if (obj.hasFocus && WATBrowserInfo.IsIE || !obj.hasFocus && !WATBrowserInfo.IsIE)
    {        
      //  get the relative mouse mosition that respects scrolling of parent div elements
      var mousePosX = watMousePosX + __GetParentScrollLeft(obj.divElement);
      var mousePosY = watMousePosY + __GetParentScrollTop(obj.divElement);
      
      //  move the element
      if (obj.moving)
      {
        obj.divElement.style.top = __AlignGrid((mousePosY - obj.moveOffsetY - obj.topDiff), 1) + 'px';
        obj.divElement.style.left = __AlignGrid((mousePosX - obj.moveOffsetX - obj.leftDiff), 2) + 'px';
        
        //  send an event if the div has been modified
        if (obj.modifyCurrentTop != obj.GetTop() || obj.modifyCurrentLeft != obj.GetLeft())       
          WATOnDivEffectsModify.Raise(obj, 2);
      }
      
      //  resize the element
      if (obj.resize > 0)
      {
        //  get the current position
        var top = obj.GetTop();
        var left = obj.GetLeft();
        var width = obj.GetWidth();
        var height = obj.GetHeight();
        
        //  initialize the new position
        var newTop = top;
        var newLeft = left;
        var newWidth = width;
        var newHeight = height;
      
        switch(obj.resize)
        {
          //  resize top
          case 1 :
            newTop = mousePosY - obj.moveOffsetY - obj.topDiff;
            newHeight = height + (top - newTop);
            if (obj.keepAspectRatio) newWidth = Math.ceil(newHeight / height * width);
            break;
            
          //  resize top/left
          case 2 :
            newTop = mousePosY - obj.moveOffsetY - obj.topDiff;
            newLeft = mousePosX - obj.moveOffsetX;
            newHeight = height + (top - newTop);
            newWidth = width + (left - newLeft);
            if (obj.keepAspectRatio || obj.keepAspectRatioEdge) newWidth = Math.floor(newHeight / height * width);
            break;
            
          //  resize left
          case 3 :
            newLeft = mousePosX - obj.moveOffsetX;
            newWidth = width + (left - newLeft);
            if (obj.keepAspectRatio) newHeight = Math.ceil(newWidth / width * height);
            break;
            
          //  resize bottom/left
          case 4 :
            newHeight = mousePosY - watGetTopPos(obj.divElement);
            newLeft = mousePosX - obj.moveOffsetX;
            newWidth = width + (left - newLeft);
            if (obj.keepAspectRatio) newWidth = Math.ceil(newHeight / height * width);
            break;
            
          //  resize bottom
          case 5 :
            newHeight = mousePosY - watGetTopPos(obj.divElement);
            if (obj.keepAspectRatio) newWidth = Math.ceil(newHeight / height * width);
            break;
            
          //  resize bottom/right
          case 6 :
            newHeight = mousePosY - watGetTopPos(obj.divElement);
            newWidth = mousePosX - left + 7;
            if (obj.keepAspectRatio || obj.keepAspectRatioEdge) newHeight = Math.ceil(newWidth / width * height);
            break;
            
          //  resize right
          case 7 :
            newWidth = mousePosX - left + 7;
            if (obj.keepAspectRatio) newHeight = Math.ceil(newWidth / width * height);
            break;
           
          //  resize right/top
          case 8 :
            newWidth = mousePosX - left + 7;
            newTop = mousePosY - obj.moveOffsetY - obj.topDiff;
            newHeight = height + (top - newTop);
            if (obj.keepAspectRatio || obj.keepAspectRatioEdge) newWidth = Math.floor(newHeight / height * width);
            break;
        }

        //  apply the new position
        obj.divElement.style.top = __AlignGrid(newTop, 1) + 'px';
        obj.divElement.style.left = __AlignGrid(newLeft, 2) + 'px';
        obj.divElement.style.height = __AlignGrid(newHeight, 1) + 'px';
        obj.divElement.style.width = __AlignGrid(newWidth, 2) + 'px';
        
        //  the overlayDiv should never be null but in some cases when the content of the (main) div has
        //  just been replaced by the user it can happen that the overlay div is (accidently) removed
        //  so be sure that it is available
        if (obj.overlayDivElement)
        {
          //  adjust the size of the overlayDivElement
          obj.overlayDivElement.style.width = obj.GetWidth(obj.divElement) + 'px';
          obj.overlayDivElement.style.height = obj.GetHeight(obj.divElement) + 'px';
        }
        
        //  send an event if the div has been modified
        if (obj.modifyCurrentTop != obj.GetTop(true) || obj.modifyCurrentLeft != obj.GetLeft(true) ||
            obj.modifyCurrentWidth != obj.GetWidth() || obj.modifyCurrentHeight != obj.GetHeight())       
          WATOnDivEffectsModify.Raise(obj, 3);
      }
    }
  }
  
  //  OnMouseUp handler that is called when the user releases the mouse button
  function __MouseUp()
  {
    //  reset the object
    if (obj.moving || obj.resize != 0)
    {
      obj.moving = false;
      obj.resize = 0;
      document.body.style.cursor = 'default';
      
      //  the overlayDiv should never be null but in some cases when the content of the (main) div has
      //  just been replaced by the user it can happen that the overlay div is (accidently) removed
      //  so be sure that it is available
      if (obj.overlayDivElement) obj.overlayDivElement.style.display = 'none';

      //  send an event if the div has been modified
      if (obj.modifyCurrentTop != obj.GetTop(true) || obj.modifyCurrentLeft != obj.GetLeft(true) ||
          obj.modifyCurrentWidth != obj.GetWidth() || obj.modifyCurrentHeight != obj.GetHeight())       
        WATOnDivEffectsModify.Raise(obj, 1);
    }
  }

  //  create the event handlers if it has not been done yet
  if (!this.eventsRegistered)
  {
    if (WATBrowserInfo.IsIE)
    {  
      //  ... for Internet Explorer
      this.divElement.attachEvent('onfocus', __Focus);
      this.divElement.attachEvent('onblur', __Blur);
      this.divElement.attachEvent('onmousedown', __MouseDown);
      document.attachEvent('onmousemove', __MouseMove);
      document.attachEvent('onmouseup', __MouseUp);
    }
    else
    {
      //  ... for other browsers
      this.divElement.addEventListener('focus', __Focus, true);
      this.divElement.addEventListener('blur', __Blur, true);
      this.divElement.addEventListener('mousedown', __MouseDown, true);
      document.addEventListener('mousemove', __MouseMove, true);
      document.addEventListener('mouseup', __MouseUp, true);
    }
  
    //  do not register the events several times
    this.eventsRegistered = true;
  }
}

