///////////////////////////////////////////////////////////////////////////////
//
// Module:           layer.js
//
// Description:      Uses an old `layers.js' module to implement a flexible
//                   interface for manipulating with layers (including dragging)
//
// Author:           Tihomir Lazarov (tihomir@netclime.com)
//                   Netclime, Inc.
//
// Revision History: 2002-09-13  Initial Release
//
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
//
// C O N S T A N T S
//
///////////////////////////////////////////////////////////////////////////////
var NN_4          = (document.layers)  ? 1 : 0;                         // Netscape Navigator 4
var IE            = (document.all)     ? 1 : 0;                         // Internet Explorer
var NN_6          = (!document.all && document.getElementById) ? 1 : 0; // Netscape Navigator 6
var VISIBLE       = NN_4 ? "show" : "visible"; /// FIX
var HIDDEN        = NN_4 ? "hide"  : "hidden";
var DISPLAY_ON    = "block";
var DISPLAY_OFF   = "none";
var LAYER__IS_NETSCAPE = (navigator.appName.indexOf( "Explorer" ) == -1);
var LAYER__NETSCAPE_TIME_PATCH_COEFFICIENT           = NN_4  ? 0 : 0;



///////////////////////////////////////////////////////////////////////////////
//
// G L O B A L S
//
///////////////////////////////////////////////////////////////////////////////
var inited_mouse_actions      = false;
var LAYERS_HASH               = new Array( );   // where all layers will be stored
                                                // also having some properties for each layer
var old_mouse_pos             = new Object( );
old_mouse_pos.left            = 0;
old_mouse_pos.top             = 0;

var allow_default_dragging    = false;

//
// Those pointers to functions below will be used in case the
// `allow_default_dragging' variable is `true' and none of the draggable
// layer is being currently dragged
//
var default_mousedown         = null;
var default_mousemove         = null;
var default_mouseup           = null;

///////////////////////////////////////////////////////////////////////////////
//
// P U B L I C    F U N C T I O N S
//
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
//
// Function:            Layer
//
// Description:         Constructs a `Layer' object
//
// Parameters:          layer_name    - the name of the layer
//
// Returns:             a reference to the constructed object
//
///////////////////////////////////////////////////////////////////////////////
function Layer( layer_name )
{
   //
   // Re-initialize those, because when we've initialized them above
   // the `document' object may have not been initialized. This is a
   // fix for Netscape Navigator
   //
   NN_4          = (document.layers)  ? 1 : 0;                         // Netscape Navigator 4
   IE            = (document.all)     ? 1 : 0;                         // Internet Explorer
   NN_6          = (!document.all && document.getElementById) ? 1 : 0; // Netscape Navigator 6

   if ( typeof( LAYERS_HASH ) == 'undefined' )
      LAYERS_HASH   = new Array( );

   //
   // Properties
   //
   this.LayerName    = layer_name;
   this.Layer        = Layer__GetLayerObj( layer_name );
   this.LayerStyle   = Layer__GetLayerObjStyle( layer_name );
   this.Draggable    = false;

   if ( typeof( this.Layer ) == 'undefined' || typeof( this.LayerStyle ) == 'undefined' ) {
      this.Success   = false;
      return null;
   }


   //
   // Methods
   //
   this.SetPosition     = Layer__SetLayerPosition;
   this.GetPosition     = Layer__GetLayerPosition;
   this.SetVisible      = Layer__SetLayerVisible;
   this.IsVisible       = Layer__IsLayerVisible;
   this.SetDisplay      = Layer__SetLayerDisplay;
   this.Move            = Layer__Move;
   this.GetDimentions   = IE || NN_6 ? Layer__GetLayerDimentions : Layer__GetLayerDimentions_NN;
   this.SetDimentions   = IE || NN_6 ? Layer__SetLayerDimentions : Layer__SetLayerDimentions_NN;
   this.HTML            = IE || NN_6 ? Layer__HTML : Layer__HTML_NN; // FIX
   this.DocumentMargins = IE || NN_6 ? Layer__GetDocumentMargins : Layer__GetDocumentMargins_NN;
   this.Document        = IE ? document : ( NN_6 ? document : this.Layer.document );
   this.InitDrag        = Layer__InitDrag;
   this.ReleaseDrag     = Layer__ReleaseDrag;   // if the layer must be clickable the
                                                // mousedown action must not take place
   this.Maximize        = Layer__Maximize;
   this.Center          = Layer__Center;

   this.DocumentMargins();

   LAYERS_HASH[ this.LayerName ]             = this;
   
   this.Success   = true;

   return this;
}


///////////////////////////////////////////////////////////////////////////////
//
// Function:            Layer__DefaultDragging
//
// Description:         Sets the functions that will be used as default functions
//                      on mouse{down|move|up} if the `default_dragging' is allowed
//                      and none of the layers is currently dragged
//
// Parameters:          func_handler_mousedown     - mousedown handler
//                      func_handler_mousemove     - mousemove handler
//                      func_handler_mouseup       - mouseup handler
//
// Returns:             (nothing)
//
///////////////////////////////////////////////////////////////////////////////
function Layer__DefaultDragging( func_handler_mousedown,
                                 func_handler_mousemove,
                                 func_handler_mouseup )
{
   default_mousedown       = func_handler_mousedown;
   default_mousemove       = func_handler_mousemove;
   default_mouseup         = func_handler_mouseup;

   allow_default_dragging  = true;
}

///////////////////////////////////////////////////////////////////////////////
//
// Function:            Layer__AllowDefaultDragging
//
// Description:         Allows default dragging
//
// Parameters:          (none)
//
// Returns:             (nothing)
//
///////////////////////////////////////////////////////////////////////////////
function Layer__AllowDefaultDragging( )
{
   allow_default_dragging  = true;
}

///////////////////////////////////////////////////////////////////////////////
//
// Function:            Layer__ForbidDefaultDragging
//
// Description:         Forbids default dragging
//
// Parameters:          (none)
//
// Returns:             (nothing)
//
///////////////////////////////////////////////////////////////////////////////
function Layer__ForbidDefaultDragging( )
{
   allow_default_dragging  = false;
}



///////////////////////////////////////////////////////////////////////////////
//
// P R I V A T E    F U N C T I O N S
//
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
//
// Function:         Layer__GetLayerObj
//
// Description:      Gets a reference to a layer object in the document
//
// Parameters:       layer_name     - the name of the layer
//                   nested_ref     - the parent of the layer (if `undefined',
//                                    the parent will be == `document'
//
// Returns:          Layer object reference
//
///////////////////////////////////////////////////////////////////////////////
function Layer__GetLayerObj ( layer_name, nested_ref )   {
   var layer;
   if ( NN_6 ) {
      layer = document.getElementById( layer_name );
   } else if ( IE ) {
      layer = document.all[ layer_name ];
   } else if ( NN_4 ) {
      var layer_parent;
      if ( typeof( nested_ref ) != 'undefined' ) {
         layer_parent = document.layers[nested_ref].document;
      } else {
         layer_parent = document;
      }
      layer = layer_parent.layers[ layer_name ];
   }

   return layer;
}


///////////////////////////////////////////////////////////////////////////////
//
// Function:         Layer__GetLayerObj
//
// Description:      Gets a reference to a layer object in the document, but also
//                   returns a reference to the `.style' property (if any)
//
// Parameters:       layer_name     - the name of the layer
//                   nested_ref     - the parent of the layer (if `undefined',
//                                    the parent will be == `document'
//
// Returns:          Reference to the Layer object's `.style' property
//
///////////////////////////////////////////////////////////////////////////////
function Layer__GetLayerObjStyle ( layer_name, nested_ref )   {
   var layer = Layer__GetLayerObj( layer_name, nested_ref );

   if ( !layer) return;
   
   if ( NN_6 ) {
      layer = layer.style;
   } else if ( IE ) {
      layer = layer.style;
   } else if ( NN_4 ) {
      // do nothing...
   }

   return layer;
}


///////////////////////////////////////////////////////////////////////////////
//
// Function:         Layer__SetLayerPosition
//
// Description:      Moves the layer on a certain postion
//
// Parameters:       left     - the left coordinate (relative to the window)
//                   top      - the top coordinate
//
// Returns:          (nothing)
//
///////////////////////////////////////////////////////////////////////////////
function Layer__SetLayerPosition( left, top )
{
   this.LayerStyle.left = left;
   this.LayerStyle.top  = top;
}

///////////////////////////////////////////////////////////////////////////////
//
// Function:         Layer__GetLayerPosition
//
// Description:      Gets the layer position
//
// Parameters:       (none)
//
// Returns:          returns an object with properties `.left' and `.top'
//
///////////////////////////////////////////////////////////////////////////////
function Layer__GetLayerPosition( )
{
   var pos = new Object();

   pos.left = parseInt( this.LayerStyle.left );
   pos.top  = parseInt( this.LayerStyle.top  );

   return pos;
}

///////////////////////////////////////////////////////////////////////////////
//
// Function:         Layer__SetLayerDimentions
//
// Description:      Sets layer dimentions
//
// Parameters:       width    - the desired width
//                   height   - the desired height
//
// Returns:          (nothing)
//
///////////////////////////////////////////////////////////////////////////////
function Layer__SetLayerDimentions( width, height )
{
   this.LayerStyle.width   = width;
   this.LayerStyle.height  = height;
}

///////////////////////////////////////////////////////////////////////////////
//
// Function:         Layer__SetLayerDimentions_NN
//
// Description:      Sets layer dimentions (Netscape version)
//
// Parameters:       width    - the desired width
//                   height   - the desired height
//
// Returns:          (nothing)
//
///////////////////////////////////////////////////////////////////////////////
function Layer__SetLayerDimentions_NN( width, height )
{
   this.LayerStyle.clip.width   = width;
   this.LayerStyle.clip.height  = height;
}



///////////////////////////////////////////////////////////////////////////////
//
// Function:         Layer__GetLayerDimentions
//
// Description:      Gets the layer dimentions {left, top, width, height}
//
// Parameters:       (none)
//
// Returns:          an object with properties `.left', `.top', `.width', `.height'
//
///////////////////////////////////////////////////////////////////////////////
function Layer__GetLayerDimentions( )
{
   var dimentions       = this.GetPosition( );
   dimentions.width     = parseInt( this.LayerStyle.width );
   dimentions.height    = parseInt( this.LayerStyle.height );

   return dimentions;
}


///////////////////////////////////////////////////////////////////////////////
//
// Function:         Layer__GetLayerDimentions_NN
//
// Description:      Gets the layer dimentions {left, top, width, height} (Netscape version)
//
// Parameters:       (none)
//
// Returns:          an object with properties `.left', `.top', `.width', `.height'
//
///////////////////////////////////////////////////////////////////////////////
function Layer__GetLayerDimentions_NN( )
{
   var dimentions       = this.GetPosition( );
   dimentions.width     = parseInt( this.LayerStyle.clip.width  );
   dimentions.height    = parseInt( this.LayerStyle.clip.height );

   return dimentions;
}



///////////////////////////////////////////////////////////////////////////////
//
// Function:         Layer__Move
//
// Description:      Moves a layer from one position to another using a timeout,
//                   that makes the layer as animation
//
// Parameters:       start_left        - the starting left position
//                   start_top         - the starting top position
//                   end_left          - the ending left position
//                   end_top           - the ending top position
//                   timeout           - the timeout for each movement
//                   speed_coefficient - number (e.g. 2 means 2x faster...)
//                   name              - the layer name (not obligatory)
//
// Returns:          (nothing)
//
///////////////////////////////////////////////////////////////////////////////
function Layer__Move( start_left, start_top, end_left, end_top, timeout, speed_coefficient, name )
{
   var layer      = typeof( name ) == 'undefined' ? this : new Layer( name );
   
   if ( start_left == end_left && start_top == end_top ) {
      layer.SetPosition( start_left, start_top );
      return;
   }
   
   if ( typeof( speed_coefficient ) == 'undefined' ) {
      speed_coefficient       = 1;
   }
   
   var sign_left     = __Layer__Sign( start_left, end_left );
   var sign_top      = __Layer__Sign( start_top, end_top );
   
   var dleft         = __Layer__Distance( start_left, end_left );
   var dtop          = __Layer__Distance( start_top, end_top );
   
   var offset_left   = 1;
   var offset_top    = 1;
   
   if ( dleft > dtop ) {
      if ( dtop == 0 ) {
         offset_top     = 0;
         offset_left    = 1;
      } else {
         offset_top     = 1;
         offset_left    = Math.floor( dleft / dtop );
      }
   } else {
      if ( dleft == 0 ) {
         offset_top     = 1;
         offset_left    = 0;
      } else {
         offset_top     = Math.floor( dtop  / dleft );
         offset_left    = 1;
      }
   }
   
   if ( start_left != end_left ) {
      start_left    += speed_coefficient * sign_left * offset_left + LAYER__NETSCAPE_TIME_PATCH_COEFFICIENT;
   }
   
   if ( start_top  != end_top ) {
      start_top     += speed_coefficient * sign_top * offset_top;
   }
   //alert('Setting Position from to [' + start_left + '][' + sign_left + '][' + LAYER__NETSCAPE_TIME_PATCH_COEFFICIENT + ']')
   layer.SetPosition( start_left, start_top );
   
   var new_sign_left     = __Layer__Sign( start_left, end_left );
   var new_sign_top      = __Layer__Sign( start_top, end_top );
   
   if ( sign_left * new_sign_left <= 0 && sign_top * new_sign_top <= 0 ) {
      return;
   }
   
   var _name    = typeof( name ) == 'undefined' ? this.LayerName : name;
   //alert('Moving the Menu from [' + start_left + '] to [' + end_left + '] [' + end_top + ']');
   if ( timeout > 0 ) {

      window.setTimeout( 'Layer__Move(' + start_left + ', ' + start_top + ', ' + end_left + ', ' + end_top + ', ' + timeout + ', ' + speed_coefficient + ', "' + _name + '")', timeout );
   } else {
      Layer__Move( start_left, start_top, end_left, end_top, 0, speed_coefficient, _name );
   }
}


///////////////////////////////////////////////////////////////////////////////
//
// Function:         __Layer__Distance
//
// Description:      Gets the distance between two numbers
//
// Parameters:       start    - the start number
//                   end      - the end number
//
// Returns:          the distance (an absolute value)
//
///////////////////////////////////////////////////////////////////////////////
function __Layer__Distance( start, end )
{
   if ( start > 0 && end > 0 ) {
      return Math.abs( end - start );
   }
   
   return Math.abs( start ) + Math.abs( end );
}

function __Layer__Sign( start, end )
{
   if ( start < end ) 
      return 1;
   
   if ( start == end ) 
      return 0;
      
   return -1;
}

///////////////////////////////////////////////////////////////////////////////
//
// Function:         Layer__SetLayerVisible
//
// Description:      Sets the layer visibility
//
// Parameters:       visible     - a boolean variable
//
// Returns:          (nothing)
//
///////////////////////////////////////////////////////////////////////////////
function Layer__SetLayerVisible(visible)
{
   this.LayerStyle.visibility = visible ? VISIBLE : HIDDEN;
}

///////////////////////////////////////////////////////////////////////////////
//
// Function:         Layer__IsLayerVisible
//
// Description:      Checks if a layer is visible
//
// Parameters:       (none)
//
// Returns:          boolean value
//
///////////////////////////////////////////////////////////////////////////////
function Layer__IsLayerVisible( )
{
   return this.LayerStyle.visibility == VISIBLE;
}


///////////////////////////////////////////////////////////////////////////////
//
// Function:         Layer__SetLayerDisplay
//
// Description:      Sets the layer display to (on|off)
//
// Parameters:       visible     - a boolean variable
//
// Returns:          (nothing)
//
///////////////////////////////////////////////////////////////////////////////
function Layer__SetLayerDisplay( visible )
{
   this.LayerStyle.display       = visible ? DISPLAY_ON : DISPLAY_OFF;
}

///////////////////////////////////////////////////////////////////////////////
//
// Function:         Layer__HTML
//
// Description:      Sets an HTML body for the layer (IE version)
//
// Parameters:       code     - the HTML code to be set
//
// Returns:          (nothing)
//
///////////////////////////////////////////////////////////////////////////////
function Layer__HTML( code )
{
   this.Layer.innerHTML = code;
}

///////////////////////////////////////////////////////////////////////////////
//
// Function:         Layer__HTML_NN
//
// Description:      Sets an HTML body for the layer (Netscape version)
//
// Parameters:       code     - the HTML code to be set
//
// Returns:          (nothing)
//
///////////////////////////////////////////////////////////////////////////////
function Layer__HTML_NN( code )
{
   this.Document.open();
   this.Document.write( code );
   this.Document.close();
}


///////////////////////////////////////////////////////////////////////////////
//
// Function:         Layer__GetDocumentMargins
//
// Description:      Gets the current document mangins (for IE )and sets them into
//                   the `DocumentWidth' and `DocumentHeight' properties
//
// Parameters:       (none)
//
// Returns:          (nothing)
//
///////////////////////////////////////////////////////////////////////////////
function Layer__GetDocumentMargins()
{
   this.DocumentWidth            = document.body.clientWidth + document.body.scrollLeft;
   this.DocumentHeight           = document.body.clientHeight + document.body.scrollTop;
   this.FullDocumentWidth        = document.body.scrollWidth;
   this.FullDocumentHeight       = document.body.scrollHeight;
   this.ScrollLeft               = document.body.scrollLeft;
   this.ScrollTop                = document.body.scrollTop;
   this.WindowWidth              = document.body.clientWidth;
   this.WindowHeight             = document.body.clientHeight;
}


///////////////////////////////////////////////////////////////////////////////
//
// Function:         Layer__GetDocumentMargins_NN
//
// Description:      Gets the current document mangins (for Netscape) and sets
//                   them into the `DocumentWidth' and `DocumentHeight' properties
//
// Parameters:       (none)
//
// Returns:          (nothing)
//
///////////////////////////////////////////////////////////////////////////////
function Layer__GetDocumentMargins_NN()
{
   this.DocumentWidth            = window.innerWidth + window.pageXOffset;
   this.DocumentHeight           = window.innerHeight + window.pageYOffset;
   this.FullDocumentWidth        = this.DocumentWidth;
   this.FullDocumentHeight       = this.DocumentHeight;
   this.ScrollLeft               = window.pageXOffset;
   this.ScrollTop                = window.pageYOffset;
   this.WindowWidth              = window.innerWidth;
   this.WindowHeight             = window.innerHeight;
}



///////////////////////////////////////////////////////////////////////////////
//
// Function:         Layer__Maximize
//
// Description:      Makes the layer's width and height dimentions as wide as
//                   the window is
//
// Parameters:       (none)
//
// Returns:          (nothing)
//
///////////////////////////////////////////////////////////////////////////////
function Layer__Maximize()
{
   this.DocumentMargins( );
   this.SetDimentions( this.WindowWidth, this.WindowHeight );
}

///////////////////////////////////////////////////////////////////////////////
//
// Function:         Layer__Center
//
// Description:      Positions a layer in the center {horizontally or vertically}
//
// Parameters:       horizontally         - boolean value
//                   vertically           - boolean value
//
// Returns:          (nothing)
//
///////////////////////////////////////////////////////////////////////////////
function Layer__Center( horizontally, vertically )
{
   var pos           = this.GetPosition( );
   var dimentions    = this.GetDimentions( );

   this.DocumentMargins( );

   if ( horizontally )
      pos.left    = this.WindowWidth  / 2  - dimentions.width  / 2;
   if ( vertically )
      pos.top     = this.WindowHeight / 2  - dimentions.height / 2;

   this.SetPosition( pos.left, pos.top );
}


///////////////////////////////////////////////////////////////////////////////
//
// Function:         Layer__InitDrag
//
// Description:      Initializes the `onmousemove', 'onmousedown', 'onmouseup'
//                   functions (if they are not initialized yet) and adds the
//                   current layer to the list of draggable layers
//
// Parameters:       (none)
//
// Returns:          (nothing)
//
///////////////////////////////////////////////////////////////////////////////
function Layer__InitDrag( )
{
   if ( !inited_mouse_actions ) {

      if ( IE ) {
         document.onmousedown    = Layer__System__MOUSEDOWN;
         document.onclick        = Layer__System__MOUSEUP;
         document.onmousemove    = Layer__System__MOUSEMOVE;
      } else {
         document.onmousedown    = Layer__System__MOUSEDOWN;
         document.captureEvents(Event.MOUSEDOWN);

         document.onmouseup      = Layer__System__MOUSEUP;
         document.captureEvents(Event.MOUSEUP);

         document.onmousemove    = Layer__System__MOUSEMOVE;
         document.captureEvents(Event.MOUSEMOVE);
      }

      inited_mouse_actions       = true;
   }

   LAYERS_HASH[ this.LayerName ].Draggable = true;
}

///////////////////////////////////////////////////////////////////////////////
//
// Function:         Layer__ReleaseDrag
//
// Description:      Locks the layer for dragging. This is made because if the
//                   layer contains some link, after clicking on the link the
//                   layer may be dragged in Netscape.
//
// Parameters:       (none)
//
// Returns:          (nothing)
//
///////////////////////////////////////////////////////////////////////////////
function Layer__ReleaseDrag( )
{
   LAYERS_HASH[ this.LayerName ].Dragging = false;
}



///////////////////////////////////////////////////////////////////////////////
//
// Function:         Layer__System__MOUSEDOWN
//
// Description:      Mousedown handler
//
// Parameters:       event_obj      - event object, needed by Netscape
//
// Returns:          (nothing)
//
///////////////////////////////////////////////////////////////////////////////
function Layer__System__MOUSEDOWN( event_obj )
{
   var dragged_some        = false;
   for ( var key in LAYERS_HASH ) {
      if ( LAYERS_HASH[ key ].Draggable && Layer__System__ClickedOverLayer( LAYERS_HASH[ key ], event_obj ) ) {
         //
         // Yes this is a click over our layer... Set the `Dragging' to `true'
         // so that the `MOUSEMOVE' handle will move the layer while the mouse
         // is moving...
         //
         if ( IE )
            LAYERS_HASH[ key ].Dragging   = true;
         else
            LAYERS_HASH[ key ].Dragging   = !LAYERS_HASH[ key ].Dragging;

         dragged_some   = true;
      }
   }

   if ( !dragged_some && allow_default_dragging ) {
      var current_pos   = Layer__System__CurrentMousePosition( event_obj );
      default_mousedown( current_pos );
   }
}


///////////////////////////////////////////////////////////////////////////////
//
// Function:         Layer__System__MOUSEMOVE
//
// Description:      Mousemove handler
//
// Parameters:       event_obj      - event object, needed by Netscape
//
// Returns:          (nothing)
//
///////////////////////////////////////////////////////////////////////////////
function Layer__System__MOUSEMOVE( event_obj )
{
   var old_pos       = old_mouse_pos;  // because `Layer__System__CurrentMousePosition'
                                       // will reset the `old_mouse_pos' value
   var current_pos   = Layer__System__CurrentMousePosition( event_obj );
   var dragged_some  = false;

   for ( var key in LAYERS_HASH ) {
      if ( LAYERS_HASH[ key ].Draggable && LAYERS_HASH[ key ].Dragging ) {
         //
         // This layer has been started for dragging... Move it according
         // to the `old_mouse_pos' and the current position
         //
         LAYERS_HASH[ key ].LayerStyle.left     = parseInt( LAYERS_HASH[ key ].LayerStyle.left ) + ( current_pos.left - old_pos.left );
         LAYERS_HASH[ key ].LayerStyle.top      = parseInt( LAYERS_HASH[ key ].LayerStyle.top  ) + ( current_pos.top  - old_pos.top  );
         dragged_some = true;
      }
   }

   if ( !dragged_some && allow_default_dragging ) {
      default_mousemove( old_pos, current_pos );
   }
}


///////////////////////////////////////////////////////////////////////////////
//
// Function:         Layer__System__MOUSEUP
//
// Description:      Mouseup handler
//
// Parameters:       event_obj      - event object, needed by Netscape
//
// Returns:          (nothing)
//
///////////////////////////////////////////////////////////////////////////////
function Layer__System__MOUSEUP( event_obj )
{
   var dragged_some     = false;
   for ( var key in LAYERS_HASH ) {
      if ( LAYERS_HASH[ key ].Draggable &&
           LAYERS_HASH[ key ].Dragging ) {
         //
         // Our layer is released... Set the `Dragging' to `false' ONLY if
         // the browser is IE. In case of `Netscape' the layer will be
         // released on the next `MouseDown' event...
         //
         if ( IE )
            LAYERS_HASH[ key ].Dragging = false;

         dragged_some   = true;
      }
   }

   if ( !dragged_some && allow_default_dragging ) {
      var current_pos   = Layer__System__CurrentMousePosition( event_obj );
      default_mouseup( current_pos );
   }
}


///////////////////////////////////////////////////////////////////////////////
//
// Function:         Layer__System__ClickedOverLayer
//
// Description:      Checks if the current mouse position is over a certain
//                   layer
//
// Parameters:       layer       - a handle to a Layer object
//                   event_obj   - an event object, needed by Netscape
//
// Returns:          boolean value
//
///////////////////////////////////////////////////////////////////////////////
function Layer__System__ClickedOverLayer( layer, event_obj )
{
   var pos        = Layer__System__CurrentMousePosition( event_obj );

   //
   // For a more beautiful code...
   //
   var layer_pos     = layer.GetDimentions( );
   layer_pos.right   = layer_pos.left + layer_pos.width;
   layer_pos.bottom  = layer_pos.top  + layer_pos.height;

   //alert("(" + pos.left + "x" + pos.top + ") vs. (" + layer_pos.left + ", " + layer_pos.right + ", " + layer_pos.top + ", " + layer_pos.bottom + ")" );

   return ( pos.left >= layer_pos.left && pos.left <= layer_pos.right &&
            pos.top  >= layer_pos.top  && pos.top  <= layer_pos.bottom );
}


///////////////////////////////////////////////////////////////////////////////
//
// Function:         Layer__System__CurrentMousePosition
//
// Description:      Gets the current mouse position
//
// Parameters:       event_obj         - event object, needed by Netscape
//
// Returns:          an object with `.left' and `.top' properties
//
///////////////////////////////////////////////////////////////////////////////
function Layer__System__CurrentMousePosition( event_obj )
{
   var pos     = new Object( );
   if ( IE ) {
      pos.left           = event.clientX  + document.body.scrollLeft;
      pos.top            = event.clientY  + document.body.scrollTop;
   } else {
      pos.left           = event_obj.pageX + window.pageXOffset;
      pos.top            = event_obj.pageY + window.pageYOffset;;
   }

   old_mouse_pos         = pos;

   return pos;
}

