/*
 * $Log: xbLibrary.js,v $
 * Revision 1.2  2002/07/23 13:43:03  bc6ix
 * Opera is downlevel and fix conditional in constructor
 *
 * Revision 1.1  2002/07/22 14:01:10  bc6ix
 * Initial check in
 *
 */

/* ***** BEGIN LICENSE BLOCK *****
 * Licensed under Version: MPL 1.1/GPL 2.0/LGPL 2.1
 * Full Terms at /lib/js/license/mpl-tri-license.txt
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Bob Clary code.
 *
 * The Initial Developer of the Original Code is
 * Bob Clary.
 * Portions created by the Initial Developer are Copyright (C) 2000
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s): Bob Clary <bc@bclary.com>
 *
 * ***** END LICENSE BLOCK ***** */

if (!document.getElementById || navigator.userAgent.indexOf('Opera') != -1)
{
  // assign error handler for downlevel browsers
  // Note until Opera improves it's overall support
  // for JavaScript and the DOM, it must be considered downlevel

  window.onerror = defaultOnError;
  
  function defaultOnError(msg, url, line)
  {
    // handle bug in NS6.1, N6.2
    // where an Event is passed to error handlers
    if (typeof(msg) != 'string')
    {
        msg = 'unknown error';
    }
    if (typeof(url) != 'string')
    {
        url = document.location;
    }

    // customize this for your site
    if (top.location.href.indexOf(xblibrary.path + '/errors/') == -1)
      top.location = xblibrary.path + '/errors.html?msg=' + escape(msg) + '&url=' + escape(url) + '&line=' + escape(line);
  }
}

function xbLibrary(path)
{
  if (path.charAt(path.length-1) == '/')
  {
    path = path.substr(0, path.length-1)
  }
  this.path = path;
}

// dynamically loaded scripts
//
// it is an error to reference anything from the dynamically loaded file inside the
// same script block.  This means that a file can not check its dependencies and
// load the files for it's own use.  someone else must do this.  
  
xbLibrary.prototype.loadScript = 
function (scriptName)
{
  document.write('<script language="javascript" src="' + this.path + '/' + scriptName + '"><\/script>');
};

// default xbLibrary

xblibrary = new xbLibrary('.');


/*
 * $Log: xbDOM.js,v $
 * Revision 1.6  2002/07/22 14:25:08  bc6ix
 * fix license path, remove old change log, reformat...
 *
 * Revision 1.5  2002/06/17 04:08:37  bc6ix
 * add get/set ScrollTop
 *
 * Revision 1.4  2002/05/14 16:52:52  bc6ix
 * use CVS Log for revision history
 *
 */

/* ***** BEGIN LICENSE BLOCK *****
 * Licensed under Version: MPL 1.1/GPL 2.0/LGPL 2.1
 * Full Terms at /lib/js/license/mpl-tri-license.txt
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Netscape code.
 *
 * The Initial Developer of the Original Code is
 * Netscape Corporation.
 * Portions created by the Initial Developer are Copyright (C) 2001
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s): Bob Clary <bclary@netscape.com>
 *
 * ***** END LICENSE BLOCK ***** */

function xbToInt(s)
{
  var i = parseInt(s, 10);
  if (isNaN(i))
    i = 0;

  return i;
}

function xbGetWindowWidth(windowRef)
{
  var width = 0;

  if (!windowRef)
  {
    windowRef = window;
  }
  
  if (typeof(windowRef.innerWidth) == 'number')
  {
    width = windowRef.innerWidth;
  }
  else if (windowRef.document.body && typeof(windowRef.document.body.clientWidth) == 'number')
  {
    width = windowRef.document.body.clientWidth;  
  }
    
  return width;
}

function xbGetWindowHeight(windowRef)
{
  var height = 0;
  
  if (!windowRef)
  {
    windowRef = window;
  }

  if (typeof(windowRef.innerWidth) == 'number')
  {
    height = windowRef.innerHeight;
  }
  else if (windowRef.document.body && typeof(windowRef.document.body.clientWidth) == 'number')
  {
    height = windowRef.document.body.clientHeight;    
  }
  return height;
}

function xbGetElementsByNameAndType(name, type, windowRef)
{
  if (!windowRef)
    windowRef = window;

  var elmlist = new Array();

  xbFindElementsByNameAndType(windowRef.document, name, type, elmlist);

  return elmlist;
}

function xbFindElementsByNameAndType(doc, name, type, elmlist)
{
  var i;
  var subdoc;
  
  for (i = 0; i < doc[type].length; ++i)
  {
    if (doc[type][i].name && name == doc[type][i].name)
    {
      elmlist[elmlist.length] = doc[type][i];
    }
  }

  if (doc.layers)
  {
    for (i = 0; i < doc.layers.length; ++i)
    {
      subdoc = doc.layers[i].document;
      xbFindElementsByNameAndType(subdoc, name, type, elmlist);
    }
  }
}

if (document.layers)
{
  nav4FindLayer =
  function (doc, id)
  {
    var i;
    var subdoc;
    var obj;
    
    for (i = 0; i < doc.layers.length; ++i)
    {
      if (doc.layers[i].id && id == doc.layers[i].id)
        return doc.layers[i];
        
      subdoc = doc.layers[i].document;
      obj    = nav4FindLayer(subdoc, id);
      if (obj != null)
        return obj;
    }
    return null;
  }

  nav4FindElementsByName = 
  function (doc, name, elmlist)
  {
    var i;
    var j;
    var subdoc;
    
    for (i = 0; i < doc.images.length; ++i)
    {
      if (doc.images[i].name && name == doc.images[i].name)
      {
        elmlist[elmlist.length] = doc.images[i];
      }
    }

    for (i = 0; i < doc.forms.length; ++i)
    {
      for (j = 0; j < doc.forms[i].elements.length; j++)
      {
        if (doc.forms[i].elements[j].name && name == doc.forms[i].elements[j].name)
        {
          elmlist[elmlist.length] = doc.forms[i].elements[j];
        }
      }

      if (doc.forms[i].name && name == doc.forms[i].name)
      {
        elmlist[elmlist.length] = doc.forms[i];
      }
    }

    for (i = 0; i < doc.anchors.length; ++i)
    {
      if (doc.anchors[i].name && name == doc.anchors[i].name)
      {
        elmlist[elmlist.length] = doc.anchors[i];
      }
    }

    for (i = 0; i < doc.links.length; ++i)
    {
      if (doc.links[i].name && name == doc.links[i].name)
      {
        elmlist[elmlist.length] = doc.links[i];
      }
    }

    for (i = 0; i < doc.applets.length; ++i)
    {
      if (doc.applets[i].name && name == doc.applets[i].name)
      {
        elmlist[elmlist.length] = doc.applets[i];
      }
    }

    for (i = 0; i < doc.embeds.length; ++i)
    {
      if (doc.embeds[i].name && name == doc.embeds[i].name)
      {
        elmlist[elmlist.length] = doc.embeds[i];
      }
    }

    for (i = 0; i < doc.layers.length; ++i)
    {
      if (doc.layers[i].name && name == doc.layers[i].name)
      {
        elmlist[elmlist.length] = doc.layers[i];
      }
        
      subdoc = doc.layers[i].document;
      nav4FindElementsByName(subdoc, name, elmlist);
    }
  }

  xbGetElementById = function (id, windowRef)
  {
    if (!windowRef)
      windowRef = window;

    return nav4FindLayer(windowRef.document, id);
  };

  xbGetElementsByName = function (name, windowRef)
  {
    if (!windowRef)
      windowRef = window;

    var elmlist = new Array();

    nav4FindElementsByName(windowRef.document, name, elmlist);

    return elmlist;
  };

}
else if (document.all)
{
  xbGetElementById = 
  function (id, windowRef) 
  { 
    if (!windowRef) 
    {
      windowRef = window; 
    }
    var elm = windowRef.document.all[id]; 
    if (!elm) 
    {
      elm = null; 
    }
    return elm; 
  };

  xbGetElementsByName = function (name, windowRef)
  {
    if (!windowRef)
      windowRef = window;

    var i;
    var idnamelist = windowRef.document.all[name];
    var elmlist = new Array();

    if (!idnamelist.length || idnamelist.name == name)
    {
      if (idnamelist)
        elmlist[elmlist.length] = idnamelist;
    }
    else
    {
      for (i = 0; i < idnamelist.length; i++)
      {
        if (idnamelist[i].name == name)
          elmlist[elmlist.length] = idnamelist[i];
      }
    }

    return elmlist;
  }

}
else if (document.getElementById)
{
  xbGetElementById = 
  function (id, windowRef) 
  { 
    if (!windowRef) 
    {
      windowRef = window; 
    }
    return windowRef.document.getElementById(id); 
  };

  xbGetElementsByName = 
  function (name, windowRef) 
  { 
    if (!windowRef) 
    {
      windowRef = window; 
    }
    return windowRef.document.getElementsByName(name); 
  };
}
else 
{
  xbGetElementById = 
  function (id, windowRef) 
  { 
    return null; 
  };

  xbGetElementsByName = 
  function (name, windowRef) 
  { 
    return new Array(); 
  };
}

function xbGetPageScrollX(windowRef)
{
  if (!windowRef) 
  {
    windowRef = window; 
  }

  if (typeof(windowRef.pageXOffset) == 'number')
  {
    return windowRef.pageXOffset;
  }

  if (typeof(windowRef.document.body && windowRef.document.body.scrollLeft) == 'number')
  {
    return windowRef.document.body.scrollLeft;
  }

  return 0;
}

function xbGetPageScrollY(windowRef)
{
  if (!windowRef) 
  {
    windowRef = window; 
  }

  if (typeof(windowRef.pageYOffset) == 'number')
  {
    return windowRef.pageYOffset;
  }

  if (typeof(windowRef.document.body && windowRef.document.body.scrollTop) == 'number')
  {
    return windowRef.document.body.scrollTop;
  }

  return 0;
}

if (document.layers)
{
  xbSetInnerHTML = 
  function (element, str) 
  { 
    element.document.write(str); 
    element.document.close(); 
  };
}
else 
{
  xbSetInnerHTML = function (element, str) 
  { 
    if (typeof(element.innerHTML) != 'undefined') 
    {
      element.innerHTML = str; 
    }
  };
}

// eof: xbDOM.js
/*
 * $Log: xbDebug.js,v $
 * Revision 1.7  2002/07/22 14:19:42  bc6ix
 * fix license path
 *
 * Revision 1.6  2002/07/01 15:36:56  bc6ix
 * remove window.title in xbDebug.open and unused var p in xbDebugPersistToString
 *
 * Revision 1.5  2002/05/14 16:52:53  bc6ix
 * use CVS Log for revision history
 *
 */

/* ***** BEGIN LICENSE BLOCK *****
 * Licensed under Version: MPL 1.1/GPL 2.0/LGPL 2.1
 * Full Terms at /lib/js/license/mpl-tri-license.txt
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Netscape code.
 *
 * The Initial Developer of the Original Code is
 * Netscape Corporation.
 * Portions created by the Initial Developer are Copyright (C) 2001
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s): Bob Clary <bclary@netscape.com>
 *
 * ***** END LICENSE BLOCK ***** */

/*
ChangeLog:

2002-02-25: bclary - modified xbDebugTraceOject to make sure 
            that original versions of wrapped functions were not
            rewrapped. This had caused an infinite loop in IE.

2002-02-07: bclary - modified xbDebug.prototype.close to not null
            the debug window reference. This can cause problems with
	          Internet Explorer if the page is refreshed. These issues will
	          be addressed at a later date.
*/

function xbDebug()
{
  this.on = false;
  this.stack = new Array();
  this.debugwindow = null;
  this.execprofile = new Object();
}

xbDebug.prototype.push = function ()
{
  this.stack[this.stack.length] = this.on;
  this.on = true;
}

xbDebug.prototype.pop = function ()
{
  this.on = this.stack[this.stack.length - 1];
  --this.stack.length;
}

xbDebug.prototype.open =  function ()
{
  if (this.debugwindow && !this.debugwindow.closed)
    this.close();
    
  this.debugwindow = window.open('about:blank', 'DEBUGWINDOW', 'height=400,width=600,resizable=yes,scrollbars=yes');

  this.debugwindow.document.write('<html><head><title>xbDebug Window</title></head><body><h3>Javascript Debug Window</h3></body></html>');
  this.debugwindow.focus();
}

xbDebug.prototype.close = function ()
{
  if (!this.debugwindow)
    return;
    
  if (!this.debugwindow.closed)
    this.debugwindow.close();

  // bc 2002-02-07, other windows may still hold a reference to this: this.debugwindow = null;
}

xbDebug.prototype.dump = function (msg)
{
  if (!this.on)
    return;
    
  if (!this.debugwindow || this.debugwindow.closed)
    this.open();
    
  this.debugwindow.document.write(msg + '<br>');
  
  return;
}

var xbDEBUG = new xbDebug();

window.onunload = function () { xbDEBUG.close(); }

function xbDebugGetFunctionName(funcref)
{

  if (!funcref)
  {
    return '';
  }

  if (funcref.name)
    return funcref.name;

  var name = funcref + '';
  name = name.substring(name.indexOf(' ') + 1, name.indexOf('('));
  funcref.name = name;

  if (!name) alert('name not defined');
  return name;
}


// emulate functionref.apply for IE mac and IE win < 5.5
function xbDebugApplyFunction(funcname, funcref, thisref, argumentsref)
{
  var rv;

  if (!funcref)
  {
    alert('xbDebugApplyFunction: funcref is null');
  }

  if (typeof(funcref.apply) != 'undefined')
      return funcref.apply(thisref, argumentsref);

  var applyexpr = 'thisref.xbDebug_orig_' + funcname + '(';
  var i;

  for (i = 0; i < argumentsref.length; i++)
  {
    applyexpr += 'argumentsref[' + i + '],';
  }

  if (argumentsref.length > 0)
  {
    applyexpr = applyexpr.substring(0, applyexpr.length - 1);
  }

  applyexpr += ')';

  return eval(applyexpr);
}

function xbDebugCreateFunctionWrapper(scopename, funcname, precall, postcall)
{
  var wrappedfunc;
  var scopeobject = eval(scopename);
  var funcref = scopeobject[funcname];

  scopeobject['xbDebug_orig_' + funcname] = funcref;

  wrappedfunc = function () 
  {
    var rv;

    precall(scopename, funcname, arguments);
    rv = xbDebugApplyFunction(funcname, funcref, scopeobject, arguments);
    postcall(scopename, funcname, arguments, rv);
    return rv;
  };

  if (typeof(funcref.constructor) != 'undefined')
    wrappedfunc.constructor = funcref.constuctor;

  if (typeof(funcref.prototype) != 'undefined')
    wrappedfunc.prototype = funcref.prototype;

  scopeobject[funcname] = wrappedfunc;
}

function xbDebugCreateMethodWrapper(contextname, classname, methodname, precall, postcall)
{
  var context = eval(contextname);
  var methodref = context[classname].prototype[methodname];

  context[classname].prototype['xbDebug_orig_' + methodname] = methodref;

  var wrappedmethod = function () 
  {
    var rv;
    // eval 'this' at method run time to pick up reference to the object's instance
    var thisref = eval('this');
    // eval 'arguments' at method run time to pick up method's arguments
    var argsref = arguments;

    precall(contextname + '.' + classname, methodname, argsref);
    rv = xbDebugApplyFunction(methodname, methodref, thisref, argsref);
    postcall(contextname + '.' + classname, methodname, argsref, rv);
    return rv;
  };

  return wrappedmethod;
}

function xbDebugPersistToString(obj)
{
  var s = '';

  if (obj == null)
     return 'null';

  switch(typeof(obj))
  {
    case 'number':
       return obj;
    case 'string':
       return '"' + obj + '"';
    case 'undefined':
       return 'undefined';
    case 'boolean':
       return obj + '';
  }

  if (obj.constructor)
    return '[' + xbDebugGetFunctionName(obj.constructor) + ']';

  return null;
}

function xbDebugTraceBefore(scopename, funcname, funcarguments) 
{
  var i;
  var s = '';
  var execprofile = xbDEBUG.execprofile[scopename + '.' + funcname];
  if (!execprofile)
    execprofile = xbDEBUG.execprofile[scopename + '.' + funcname] = { started: 0, time: 0, count: 0 };

  for (i = 0; i < funcarguments.length; i++)
  {
    s += xbDebugPersistToString(funcarguments[i]);
    if (i < funcarguments.length - 1)
      s += ', ';
  }

  xbDEBUG.dump('enter ' + scopename + '.' + funcname + '(' + s + ')');
  execprofile.started = (new Date()).getTime();
}

function xbDebugTraceAfter(scopename, funcname, funcarguments, rv) 
{
  var i;
  var s = '';
  var execprofile = xbDEBUG.execprofile[scopename + '.' + funcname];
  if (!execprofile)
    xbDEBUG.dump('xbDebugTraceAfter: execprofile not created for ' + scopename + '.' + funcname);
  else if (execprofile.started == 0)
    xbDEBUG.dump('xbDebugTraceAfter: execprofile.started == 0 for ' + scopename + '.' + funcname);
  else 
  {
    execprofile.time += (new Date()).getTime() - execprofile.started;
    execprofile.count++;
    execprofile.started = 0;
  }

  for (i = 0; i < funcarguments.length; i++)
  {
    s += xbDebugPersistToString(funcarguments[i]);
    if (i < funcarguments.length - 1)
      s += ', ';
  }

  xbDEBUG.dump('exit  ' + scopename + '.' + funcname + '(' + s + ')==' + xbDebugPersistToString(rv));
}

function xbDebugTraceFunction(scopename, funcname)
{
  xbDebugCreateFunctionWrapper(scopename, funcname, xbDebugTraceBefore, xbDebugTraceAfter);
}

function xbDebugTraceObject(contextname, classname)
{
  var classref = eval(contextname + '.' + classname);
  var p;
  var sp;

  if (!classref || !classref.prototype)
     return;

  for (p in classref.prototype)
  {
    sp = p + '';
    if (typeof(classref.prototype[sp]) == 'function' && (sp).indexOf('xbDebug_orig') == -1)
    {
      classref.prototype[sp] = xbDebugCreateMethodWrapper(contextname, classname, sp, xbDebugTraceBefore, xbDebugTraceAfter);
    }
  }
}

function xbDebugDumpProfile()
{
  var p;
  var execprofile;
  var avg;

  for (p in xbDEBUG.execprofile)
  {
    execprofile = xbDEBUG.execprofile[p];
    avg = Math.round ( 100 * execprofile.time/execprofile.count) /100;
    xbDEBUG.dump('Execution profile ' + p + ' called ' + execprofile.count + ' times. Total time=' + execprofile.time + 'ms. Avg Time=' + avg + 'ms.');
  }
}
/*
 * $Log: xbDebug.js,v $
 * Revision 1.7  2002/07/22 14:19:42  bc6ix
 * fix license path
 *
 * Revision 1.6  2002/07/01 15:36:56  bc6ix
 * remove window.title in xbDebug.open and unused var p in xbDebugPersistToString
 *
 * Revision 1.5  2002/05/14 16:52:53  bc6ix
 * use CVS Log for revision history
 *
 */

/* ***** BEGIN LICENSE BLOCK *****
 * Licensed under Version: MPL 1.1/GPL 2.0/LGPL 2.1
 * Full Terms at /lib/js/license/mpl-tri-license.txt
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Netscape code.
 *
 * The Initial Developer of the Original Code is
 * Netscape Corporation.
 * Portions created by the Initial Developer are Copyright (C) 2001
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s): Bob Clary <bclary@netscape.com>
 *
 * ***** END LICENSE BLOCK ***** */

/*
ChangeLog:

2002-02-25: bclary - modified xbDebugTraceOject to make sure 
            that original versions of wrapped functions were not
            rewrapped. This had caused an infinite loop in IE.

2002-02-07: bclary - modified xbDebug.prototype.close to not null
            the debug window reference. This can cause problems with
	          Internet Explorer if the page is refreshed. These issues will
	          be addressed at a later date.
*/

function xbDebug()
{
  this.on = false;
  this.stack = new Array();
  this.debugwindow = null;
  this.execprofile = new Object();
}

xbDebug.prototype.push = function ()
{
  this.stack[this.stack.length] = this.on;
  this.on = true;
}

xbDebug.prototype.pop = function ()
{
  this.on = this.stack[this.stack.length - 1];
  --this.stack.length;
}

xbDebug.prototype.open =  function ()
{
  if (this.debugwindow && !this.debugwindow.closed)
    this.close();
    
  this.debugwindow = window.open('about:blank', 'DEBUGWINDOW', 'height=400,width=600,resizable=yes,scrollbars=yes');

  this.debugwindow.document.write('<html><head><title>xbDebug Window</title></head><body><h3>Javascript Debug Window</h3></body></html>');
  this.debugwindow.focus();
}

xbDebug.prototype.close = function ()
{
  if (!this.debugwindow)
    return;
    
  if (!this.debugwindow.closed)
    this.debugwindow.close();

  // bc 2002-02-07, other windows may still hold a reference to this: this.debugwindow = null;
}

xbDebug.prototype.dump = function (msg)
{
  if (!this.on)
    return;
    
  if (!this.debugwindow || this.debugwindow.closed)
    this.open();
    
  this.debugwindow.document.write(msg + '<br>');
  
  return;
}

var xbDEBUG = new xbDebug();

window.onunload = function () { xbDEBUG.close(); }

function xbDebugGetFunctionName(funcref)
{

  if (!funcref)
  {
    return '';
  }

  if (funcref.name)
    return funcref.name;

  var name = funcref + '';
  name = name.substring(name.indexOf(' ') + 1, name.indexOf('('));
  funcref.name = name;

  if (!name) alert('name not defined');
  return name;
}


// emulate functionref.apply for IE mac and IE win < 5.5
function xbDebugApplyFunction(funcname, funcref, thisref, argumentsref)
{
  var rv;

  if (!funcref)
  {
    alert('xbDebugApplyFunction: funcref is null');
  }

  if (typeof(funcref.apply) != 'undefined')
      return funcref.apply(thisref, argumentsref);

  var applyexpr = 'thisref.xbDebug_orig_' + funcname + '(';
  var i;

  for (i = 0; i < argumentsref.length; i++)
  {
    applyexpr += 'argumentsref[' + i + '],';
  }

  if (argumentsref.length > 0)
  {
    applyexpr = applyexpr.substring(0, applyexpr.length - 1);
  }

  applyexpr += ')';

  return eval(applyexpr);
}

function xbDebugCreateFunctionWrapper(scopename, funcname, precall, postcall)
{
  var wrappedfunc;
  var scopeobject = eval(scopename);
  var funcref = scopeobject[funcname];

  scopeobject['xbDebug_orig_' + funcname] = funcref;

  wrappedfunc = function () 
  {
    var rv;

    precall(scopename, funcname, arguments);
    rv = xbDebugApplyFunction(funcname, funcref, scopeobject, arguments);
    postcall(scopename, funcname, arguments, rv);
    return rv;
  };

  if (typeof(funcref.constructor) != 'undefined')
    wrappedfunc.constructor = funcref.constuctor;

  if (typeof(funcref.prototype) != 'undefined')
    wrappedfunc.prototype = funcref.prototype;

  scopeobject[funcname] = wrappedfunc;
}

function xbDebugCreateMethodWrapper(contextname, classname, methodname, precall, postcall)
{
  var context = eval(contextname);
  var methodref = context[classname].prototype[methodname];

  context[classname].prototype['xbDebug_orig_' + methodname] = methodref;

  var wrappedmethod = function () 
  {
    var rv;
    // eval 'this' at method run time to pick up reference to the object's instance
    var thisref = eval('this');
    // eval 'arguments' at method run time to pick up method's arguments
    var argsref = arguments;

    precall(contextname + '.' + classname, methodname, argsref);
    rv = xbDebugApplyFunction(methodname, methodref, thisref, argsref);
    postcall(contextname + '.' + classname, methodname, argsref, rv);
    return rv;
  };

  return wrappedmethod;
}

function xbDebugPersistToString(obj)
{
  var s = '';

  if (obj == null)
     return 'null';

  switch(typeof(obj))
  {
    case 'number':
       return obj;
    case 'string':
       return '"' + obj + '"';
    case 'undefined':
       return 'undefined';
    case 'boolean':
       return obj + '';
  }

  if (obj.constructor)
    return '[' + xbDebugGetFunctionName(obj.constructor) + ']';

  return null;
}

function xbDebugTraceBefore(scopename, funcname, funcarguments) 
{
  var i;
  var s = '';
  var execprofile = xbDEBUG.execprofile[scopename + '.' + funcname];
  if (!execprofile)
    execprofile = xbDEBUG.execprofile[scopename + '.' + funcname] = { started: 0, time: 0, count: 0 };

  for (i = 0; i < funcarguments.length; i++)
  {
    s += xbDebugPersistToString(funcarguments[i]);
    if (i < funcarguments.length - 1)
      s += ', ';
  }

  xbDEBUG.dump('enter ' + scopename + '.' + funcname + '(' + s + ')');
  execprofile.started = (new Date()).getTime();
}

function xbDebugTraceAfter(scopename, funcname, funcarguments, rv) 
{
  var i;
  var s = '';
  var execprofile = xbDEBUG.execprofile[scopename + '.' + funcname];
  if (!execprofile)
    xbDEBUG.dump('xbDebugTraceAfter: execprofile not created for ' + scopename + '.' + funcname);
  else if (execprofile.started == 0)
    xbDEBUG.dump('xbDebugTraceAfter: execprofile.started == 0 for ' + scopename + '.' + funcname);
  else 
  {
    execprofile.time += (new Date()).getTime() - execprofile.started;
    execprofile.count++;
    execprofile.started = 0;
  }

  for (i = 0; i < funcarguments.length; i++)
  {
    s += xbDebugPersistToString(funcarguments[i]);
    if (i < funcarguments.length - 1)
      s += ', ';
  }

  xbDEBUG.dump('exit  ' + scopename + '.' + funcname + '(' + s + ')==' + xbDebugPersistToString(rv));
}

function xbDebugTraceFunction(scopename, funcname)
{
  xbDebugCreateFunctionWrapper(scopename, funcname, xbDebugTraceBefore, xbDebugTraceAfter);
}

function xbDebugTraceObject(contextname, classname)
{
  var classref = eval(contextname + '.' + classname);
  var p;
  var sp;

  if (!classref || !classref.prototype)
     return;

  for (p in classref.prototype)
  {
    sp = p + '';
    if (typeof(classref.prototype[sp]) == 'function' && (sp).indexOf('xbDebug_orig') == -1)
    {
      classref.prototype[sp] = xbDebugCreateMethodWrapper(contextname, classname, sp, xbDebugTraceBefore, xbDebugTraceAfter);
    }
  }
}

function xbDebugDumpProfile()
{
  var p;
  var execprofile;
  var avg;

  for (p in xbDEBUG.execprofile)
  {
    execprofile = xbDEBUG.execprofile[p];
    avg = Math.round ( 100 * execprofile.time/execprofile.count) /100;
    xbDEBUG.dump('Execution profile ' + p + ' called ' + execprofile.count + ' times. Total time=' + execprofile.time + 'ms. Avg Time=' + avg + 'ms.');
  }
}
/*
 * $Log: xbStyle-css.js,v $
 * Revision 1.4  2002/07/22 14:30:49  bc6ix
 * fix license path, remove ua.js detection
 *
 * Revision 1.3  2002/07/11 11:29:44  bc6ix
 * xbStyle.js:
 *
 * getEffectiveValue - special case IE's clip retrieval. Note IE6 still has clip
 *                     bug where it will return auto for explicitly set clip values
 * 		    in Standards mode.
 *
 * xbStyle-css.js:
 *
 * getClip           - explicitly set clip to elements dimensions if auto
 * getHeight         - if effective height is null string, auto or percentage use
 *                     offsetHeight if available or scrollHeight if available
 * getWidth          - if effective width is null string, auto or percentage use
 *                     offsetWidth if available or scrollWidth if available.
 * getClientHeight   - height + padding
 * getClientWidth    - width + padding
 *
 * Revision 1.2  2002/05/18 01:22:02  bc6ix
 * remove getClientTop/Left since they are not supported in anything but IE
 *
 * Revision 1.1  2002/05/16 15:02:49  bc6ix
 * split xbStyle.js into browser specific files
 *
 */

/* ***** BEGIN LICENSE BLOCK *****
 * Licensed under Version: MPL 1.1/GPL 2.0/LGPL 2.1
 * Full Terms at /lib/js/license/mpl-tri-license.txt
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Netscape code.
 *
 * The Initial Developer of the Original Code is
 * Netscape Corporation.
 * Portions created by the Initial Developer are Copyright (C) 2001
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s): Bob Clary <bclary@netscape.com>
 *
 * ***** END LICENSE BLOCK ***** */

// xbStyle.getClip()

function cssStyleGetClip()
{
  var clip = this.getEffectiveValue('clip');

  // hack opera
  if (clip == 'rect()')
    clip = '';

  if (clip == '' || clip == 'auto')
  {
    clip = 'rect(0px, ' + this.getWidth() + 'px, ' + this.getHeight() + 'px, 0px)';
  }
  else
  { 
    clip = clip.replace(/px /g, 'px, ');
  }

  return clip;
}

// xbStyle.setClip()

function cssStyleSetClip(sClipString)
{
  this.styleObj.clip = sClipString;
}

// xbStyle.getClipTop()

function cssStyleGetClipTop()
{
  var clip = this.getClip();
  var rect = new xbClipRect(clip);
  return rect.top;
}

// xbStyle.setClipTop()

function cssStyleSetClipTop(top)
{
  var clip = this.getClip();
  var rect         = new xbClipRect(clip);
  rect.top         = top;
  this.styleObj.clip = rect.toString();
}

// xbStyle.getClipRight()

function cssStyleGetClipRight()
{
  var clip = this.getClip();
  var rect = new xbClipRect(clip);
  return rect.right;
}

// xbStyle.setClipRight()

function cssStyleSetClipRight(right)
{
  var clip = this.getClip();
  var rect          = new xbClipRect(clip);
  rect.right        = right;
  this.styleObj.clip  = rect.toString();
}

// xbStyle.getClipBottom()

function cssStyleGetClipBottom()
{
  var clip = this.getClip();
  var rect = new xbClipRect(clip);
  return rect.bottom;
}

// xbStyle.setClipBottom()

function cssStyleSetClipBottom(bottom)
{
  var clip = this.getClip();
  var rect           = new xbClipRect(clip);
  rect.bottom        = bottom;
  this.styleObj.clip   = rect.toString();
}

// xbStyle.getClipLeft()

function cssStyleGetClipLeft()
{
  var clip = this.getClip();
  var rect = new xbClipRect(clip);
  return rect.left;
}

// xbStyle.setClipLeft()

function cssStyleSetClipLeft(left)
{
  var clip = this.getClip();
  var rect = new xbClipRect(clip);
  rect.left = left;
  this.styleObj.clip = rect.toString();
}

// xbStyle.getClipWidth()

function cssStyleGetClipWidth()
{
  var clip = this.getClip();
  var rect = new xbClipRect(clip);
  return rect.getWidth();
}

// xbStyle.setClipWidth()

function cssStyleSetClipWidth(width)
{
  var clip = this.getClip();
  var rect = new xbClipRect(clip);
  rect.setWidth(width);
  this.styleObj.clip = rect.toString();
}

// xbStyle.getClipHeight()

function cssStyleGetClipHeight()
{
  var clip = this.getClip();
  var rect = new xbClipRect(clip);
  return rect.getHeight();
}

// xbStyle.setClipHeight()

function cssStyleSetClipHeight(height)
{
  var clip = this.getClip();
  var rect = new xbClipRect(clip);
  rect.setHeight(height);
  this.styleObj.clip = rect.toString();
}

// the CSS attributes left,top are for absolutely positioned elements
// measured relative to the containing element.  for relatively positioned
// elements, left,top are measured from the element's normal inline position.
// getLeft(), setLeft() operate on this type of coordinate.
//
// to allow dynamic positioning the getOffsetXXX and setOffsetXXX methods are
// defined to return and set the position of either an absolutely or relatively
// positioned element relative to the containing element.
//
//

// xbStyle.getLeft()

function cssStyleGetLeft()
{
  var left = this.getEffectiveValue('left');
  if (typeof(left) == 'number')
     return left;

  if (left != '' && left.indexOf('px') == -1)
  {
    xbDEBUG.dump('xbStyle.getLeft: Element ID=' + this.object.id + ' does not use pixels as units. left=' + left + ' Click Ok to continue, Cancel to Abort');
    return 0;
  }

  if (top == 'auto' && this.object && typeof(this.object.offsetTop) == 'number')
  {
    left = this.object.offsetTop + 'px';
  }

  if (left == '')
    left = '0px';
      
  return xbToInt(left);
}

// xbStyle.setLeft()

function cssStyleSetLeft(left)
{
  if (typeof(this.styleObj.left) == 'number')
    this.styleObj.left = left;
  else
    this.styleObj.left = left + 'px';
}

// xbStyle.getTop()

function cssStyleGetTop()
{
  var top = this.getEffectiveValue('top');
  if (typeof(top) == 'number')
     return top;

  if (top != '' && top.indexOf('px') == -1)
  {
    xbDEBUG.dump('xbStyle.getTop: Element ID=' + this.object.id + ' does not use pixels as units. top=' + top + ' Click Ok to continue, Cancel to Abort');
    return 0;
  }

  if (top == 'auto' && this.object && typeof(this.object.offsetTop) == 'number')
  {
    top = this.object.offsetTop + 'px';
  }

  if (top == '')
    top = '0px';
      
  return xbToInt(top);
}

// xbStyle.setTop()

function cssStyleSetTop(top)
{
  if (typeof(this.styleObj.top) == 'number')
    this.styleObj.top = top;
  else
    this.styleObj.top = top + 'px';
}

// xbStyle.getPageX()

function cssStyleGetPageX()
{
  var x = 0;
  var elm = this.object;
  var elmstyle;
  var position;
  
  //xxxHack: Due to limitations in Gecko's (0.9.6) ability to determine the 
  // effective position attribute , attempt to use offsetXXX

  if (typeof(elm.offsetLeft) == 'number')
  {
    while (elm)
    {
      x += elm.offsetLeft;
      elm = elm.offsetParent;
    }
  }
  else
  {
    while (elm)
    {
      if (elm.style)
      {
        elmstyle = new xbStyle(elm);
        position = elmstyle.getEffectiveValue('position');
        if (position != '' && position != 'static')
          x += elmstyle.getLeft();
      }
      elm = elm.parentNode;
    }
  }
  
  return x;
}

// xbStyle.setPageX()

function cssStyleSetPageX(x)
{
  var xParent = 0;
  var elm = this.object.parentNode;
  var elmstyle;
  var position;
  
  //xxxHack: Due to limitations in Gecko's (0.9.6) ability to determine the 
  // effective position attribute , attempt to use offsetXXX

  if (elm && typeof(elm.offsetLeft) == 'number')
  {
    while (elm)
    {
      xParent += elm.offsetLeft;
      elm = elm.offsetParent;
    }
  }
  else
  {
    while (elm)
    {
      if (elm.style)
      {
        elmstyle = new xbStyle(elm);
        position = elmstyle.getEffectiveValue('position');
        if (position != '' && position != 'static')
          xParent += elmstyle.getLeft();
      }
      elm = elm.parentNode;
    }
  }
  
  x -= xParent;

  this.setLeft(x);
}
    
// xbStyle.getPageY()

function cssStyleGetPageY()
{
  var y = 0;
  var elm = this.object;
  var elmstyle;
  var position;
  
  //xxxHack: Due to limitations in Gecko's (0.9.6) ability to determine the 
  // effective position attribute , attempt to use offsetXXX

  if (typeof(elm.offsetTop) == 'number')
  {
    while (elm)
    {
      y += elm.offsetTop;
      elm = elm.offsetParent;
    }
  }
  else
  {
    while (elm)
    {
      if (elm.style)
      {
        elmstyle = new xbStyle(elm);
        position = elmstyle.getEffectiveValue('position');
        if (position != '' && position != 'static')
          y += elmstyle.getTop();
      }
      elm = elm.parentNode;
    }
  }
  
  return y;
}

// xbStyle.setPageY()

function cssStyleSetPageY(y)
{
  var yParent = 0;
  var elm = this.object.parentNode;
  var elmstyle;
  var position;
  
  //xxxHack: Due to limitations in Gecko's (0.9.6) ability to determine the 
  // effective position attribute , attempt to use offsetXXX

  if (elm && typeof(elm.offsetTop) == 'number')
  {
    while (elm)
    {
      yParent += elm.offsetTop;
      elm = elm.offsetParent;
    }
  }
  else
  {
    while (elm)
    {
      if (elm.style)
      {
        elmstyle = new xbStyle(elm);
        position = elmstyle.getEffectiveValue('position');
        if (position != '' && position != 'static')
          yParent += elmstyle.getTop();
      }
      elm = elm.parentNode;
    }
  }
  
  y -= yParent;

  this.setTop(y);
}
    
// xbStyle.getHeight()

function cssStyleGetHeight()
{
  var display = this.getEffectiveValue('display');
  var height = this.getEffectiveValue('height');

  if (typeof(height) == 'number')
  {
     // Opera
     return height;
  }

  if (height == '' || height == 'auto' || height.indexOf('%') != -1)
  {
    if (typeof(this.object.offsetHeight) == 'number')
    {
      height = this.object.offsetHeight + 'px';
    }
    else if (typeof(this.object.scrollHeight) == 'number')
    {
      height = this.object.scrollHeight + 'px';
    }
  }

  if (height.indexOf('px') == -1)
  {
    xbDEBUG.dump('xbStyle.getHeight: Element ID=' + this.object.id + ' does not use pixels as units. height=' + height + ' Click Ok to continue, Cancel to Abort');
    return 0;
  }

  height = xbToInt(height);

  return height;
}

// xbStyle.setHeight()

function cssStyleSetHeight(height)
{
  if (typeof(this.styleObj.height) == 'number')
    this.styleObj.height = height;
  else
    this.styleObj.height = height + 'px';
}

// xbStyle.getWidth()

function cssStyleGetWidth()
{
  var display = this.getEffectiveValue('display');
  var width = this.getEffectiveValue('width');

  if (typeof(width) == 'number')
  {
     // note Opera 6 has a bug in width and offsetWidth where 
     // it returns the page width. Use clientWidth instead.
     if (navigator.userAgent.indexOf('Opera') != -1)
       return this.object.clientWidth;
     else
       return width;
  }

  if (width == '' || width == 'auto' || width.indexOf('%') != -1)
  {
    if (typeof(this.object.offsetWidth) == 'number')
    {
      width = this.object.offsetWidth + 'px';
    }
    else if (typeof(this.object.scrollHeight) == 'number')
    {
      width = this.object.scrollWidth + 'px';
    }
  }

  if (width.indexOf('px') == -1)
  {
    xbDEBUG.dump('xbStyle.getWidth: Element ID=' + this.object.id + ' does not use pixels as units. width=' + width + ' Click Ok to continue, Cancel to Abort');
    return 0;
  }

  width = xbToInt(width);

  return width;
}

// xbStyle.setWidth()

function cssStyleSetWidth(width)
{
  if (typeof(this.styleObj.width) == 'number')
    this.styleObj.width = width;
  else
    this.styleObj.width = width + 'px';
}

// xbStyle.getVisibility()

function cssStyleGetVisibility()
{
  return this.getEffectiveValue('visibility');
}

// xbStyle.setVisibility()

function cssStyleSetVisibility(visibility)
{
  this.styleObj.visibility = visibility;
}

// xbStyle.getzIndex()

function cssStyleGetzIndex()
{
  return xbToInt(this.getEffectiveValue('zIndex'));
}

// xbStyle.setzIndex()

function cssStyleSetzIndex(zIndex)
{
  this.styleObj.zIndex = zIndex;
}

// xbStyle.getBackgroundColor()

function cssStyleGetBackgroundColor()
{
  return this.getEffectiveValue('backgroundColor');
}

// xbStyle.setBackgroundColor()

function cssStyleSetBackgroundColor(color)
{
  this.styleObj.backgroundColor = color;
}

// xbStyle.getColor()

function cssStyleGetColor()
{
  return this.getEffectiveValue('color');
}

// xbStyle.setColor()

function cssStyleSetColor(color)
{
  this.styleObj.color = color;
}

// xbStyle.moveAbove()

function xbStyleMoveAbove(cont)
{
  this.setzIndex(cont.getzIndex()+1);
}

// xbStyle.moveBelow()

function xbStyleMoveBelow(cont)
{
  var zindex = cont.getzIndex() - 1;
            
  this.setzIndex(zindex);
}

// xbStyle.moveBy()

function xbStyleMoveBy(deltaX, deltaY)
{
  this.moveTo(this.getLeft() + deltaX, this.getTop() + deltaY);
}

// xbStyle.moveTo()

function xbStyleMoveTo(x, y)
{
  this.setLeft(x);
  this.setTop(y);
}

// xbStyle.moveToAbsolute()

function xbStyleMoveToAbsolute(x, y)
{
  this.setPageX(x);
  this.setPageY(y);
}

// xbStyle.resizeBy()

function xbStyleResizeBy(deltaX, deltaY)
{
  this.setWidth( this.getWidth() + deltaX );
  this.setHeight( this.getHeight() + deltaY );
}

// xbStyle.resizeTo()

function xbStyleResizeTo(x, y)
{
  this.setWidth(x);
  this.setHeight(y);
}

// xbStyle.setInnerHTML()

function xbSetInnerHTML(str)
{
  if (typeof(this.object.innerHTML) != 'undefined')
    this.object.innerHTML = str;
}


// Extensions to xbStyle that are not supported by Netscape Navigator 4
// but that provide cross browser implementations of properties for 
// Mozilla, Gecko, Netscape 6.x and Opera

// xbStyle.getBorderTopWidth()

function cssStyleGetBorderTopWidth()
{
  return xbToInt(this.getEffectiveValue('borderTopWidth'));
}

// xbStyle.getBorderRightWidth()

function cssStyleGetBorderRightWidth()
{
  return xbToInt(this.getEffectiveValue('borderRightWidth'));
}

// xbStyle.getBorderBottomWidth()

function cssStyleGetBorderBottomWidth()
{
  return xbToInt(this.getEffectiveValue('borderBottomWidth'));
}

// xbStyle.getBorderLeftWidth()

function cssStyleGetBorderLeftWidth()
{
  return xbToInt(this.getEffectiveValue('borderLeftWidth'));
}

// xbStyle.getMarginTop()

function cssStyleGetMarginTop()
{
  return xbToInt(this.getEffectiveValue('marginTop'));
}

// xbStyle.getMarginRight()

function cssStyleGetMarginRight()
{
  return xbToInt(this.getEffectiveValue('marginRight'));
}

// xbStyle.getMarginBottom()

function cssStyleGetMarginBottom()
{
  return xbToInt(this.getEffectiveValue('marginBottom'));
}

// xbStyle.getMarginLeft()

function cssStyleGetMarginLeft()
{
  return xbToInt(this.getEffectiveValue('marginLeft'));
}

// xbStyle.getPaddingTop()

function cssStyleGetPaddingTop()
{
  return xbToInt(this.getEffectiveValue('paddingTop'));
}

// xbStyle.getPaddingRight()

function cssStyleGetPaddingRight()
{
  return xbToInt(this.getEffectiveValue('paddingRight'));
}

// xbStyle.getPaddingBottom()

function cssStyleGetPaddingBottom()
{
  return xbToInt(this.getEffectiveValue('paddingBottom'));
}

// xbStyle.getPaddingLeft()

function cssStyleGetPaddingLeft()
{
  return xbToInt(this.getEffectiveValue('paddingLeft'));
}

// xbStyle.getClientWidth()

function cssStyleGetClientWidth()
{
  return this.getWidth() + this.getPaddingLeft() + this.getPaddingRight();
  /*
  if (typeof(this.object.clientWidth) == 'number')
    return this.object.clientWidth;

  return null;
    */
}

// xbStyle.getClientHeight()

function cssStyleGetClientHeight()
{
  return this.getHeight() + this.getPaddingTop() + this.getPaddingBottom();
  /*
  if (typeof(this.object.clientHeight) == 'number')
    return this.object.clientHeight;

  return null;
  */
}

 // Function assignments moved to end of xbStyle.js block.

/*
 * $Log: xbStyle-nn4.js,v $
 * Revision 1.3  2002/07/22 14:19:42  bc6ix
 * fix license path
 *
 * Revision 1.2  2002/05/18 01:22:02  bc6ix
 * remove getClientTop/Left since they are not supported in anything but IE
 *
 * Revision 1.1  2002/05/16 15:02:50  bc6ix
 * split xbStyle.js into browser specific files
 *
 */

/* ***** BEGIN LICENSE BLOCK *****
 * Licensed under Version: MPL 1.1/GPL 2.0/LGPL 2.1
 * Full Terms at /lib/js/license/mpl-tri-license.txt
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Netscape code.
 *
 * The Initial Developer of the Original Code is
 * Netscape Corporation.
 * Portions created by the Initial Developer are Copyright (C) 2001
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s): Bob Clary <bclary@netscape.com>
 *
 * ***** END LICENSE BLOCK ***** */

/////////////////////////////////////////////////////////////
// xbStyle.getClip()

function nsxbStyleGetClip()
{
  var clip = this.styleObj.clip;
  var rect = new xbClipRect(clip.top, clip.right, clip.bottom, clip.left);
  return rect.toString();
}

/////////////////////////////////////////////////////////////
// xbStyle.setClip()

function nsxbStyleSetClip(sClipString)
{
  var rect          = new xbClipRect(sClipString);
  this.styleObj.clip.top    = rect.top;
  this.styleObj.clip.right  = rect.right;
  this.styleObj.clip.bottom  = rect.bottom;
  this.styleObj.clip.left    = rect.left;
}

/////////////////////////////////////////////////////////////
// xbStyle.getClipTop()

function nsxbStyleGetClipTop()
{
  return this.styleObj.clip.top;
}

/////////////////////////////////////////////////////////////
// xbStyle.setClipTop()

function nsxbStyleSetClipTop(top)
{
  return this.styleObj.clip.top = top;
}

/////////////////////////////////////////////////////////////
// xbStyle.getClipRight()

function nsxbStyleGetClipRight()
{
  return this.styleObj.clip.right;
}

/////////////////////////////////////////////////////////////
// xbStyle.setClipRight()

function nsxbStyleSetClipRight(right)
{
  return this.styleObj.clip.right = right;
}

/////////////////////////////////////////////////////////////
// xbStyle.getClipBottom()

function nsxbStyleGetClipBottom()
{
  return this.styleObj.clip.bottom;
}

/////////////////////////////////////////////////////////////
// xbStyle.setClipBottom()

function nsxbStyleSetClipBottom(bottom)
{
  return this.styleObj.clip.bottom = bottom;
}

/////////////////////////////////////////////////////////////
// xbStyle.getClipLeft()

function nsxbStyleGetClipLeft()
{
  return this.styleObj.clip.left;
}

/////////////////////////////////////////////////////////////
// xbStyle.setClipLeft()

function nsxbStyleSetClipLeft(left)
{
  return this.styleObj.clip.left = left;
}

/////////////////////////////////////////////////////////////
// xbStyle.getClipWidth()

function nsxbStyleGetClipWidth()
{
  return this.styleObj.clip.width;
}

/////////////////////////////////////////////////////////////
// xbStyle.setClipWidth()

function nsxbStyleSetClipWidth(width)
{
  return this.styleObj.clip.width = width;
}

/////////////////////////////////////////////////////////////
// xbStyle.getClipHeight()

function nsxbStyleGetClipHeight()
{
  return this.styleObj.clip.height;
}

/////////////////////////////////////////////////////////////
// xbStyle.setClipHeight()

function nsxbStyleSetClipHeight(height)
{
  return this.styleObj.clip.height = height;
}

/////////////////////////////////////////////////////////////////////////////
// xbStyle.getLeft()

function nsxbStyleGetLeft()
{
  return this.styleObj.left;
}

/////////////////////////////////////////////////////////////////////////////
// xbStyle.setLeft()

function nsxbStyleSetLeft(left)
{
  this.styleObj.left = left;
}

/////////////////////////////////////////////////////////////////////////////
// xbStyle.getTop()

function nsxbStyleGetTop()
{
  return this.styleObj.top;
}

/////////////////////////////////////////////////////////////////////////////
// xbStyle.setTop()

function nsxbStyleSetTop(top)
{
  this.styleObj.top = top;
}


/////////////////////////////////////////////////////////////////////////////
// xbStyle.getPageX()

function nsxbStyleGetPageX()
{
  return this.styleObj.pageX;
}

/////////////////////////////////////////////////////////////////////////////
// xbStyle.setPageX()

function nsxbStyleSetPageX(x)
{
  this.styleObj.x = this.styleObj.x  + x - this.styleObj.pageX;
}

/////////////////////////////////////////////////////////////////////////////
// xbStyle.getPageY()


function nsxbStyleGetPageY()
{
  return this.styleObj.pageY;
}

/////////////////////////////////////////////////////////////////////////////
// xbStyle.setPageY()

function nsxbStyleSetPageY(y)
{
  this.styleObj.y = this.styleObj.y  + y - this.styleObj.pageY;
}

/////////////////////////////////////////////////////////////////////////////
// xbStyle.getHeight()

function nsxbStyleGetHeight()
{
  //if (this.styleObj.document && this.styleObj.document.height)
  //  return this.styleObj.document.height;
    
  return this.styleObj.clip.height;
}

/////////////////////////////////////////////////////////////////////////////
// xbStyle.setHeight()

function nsxbStyleSetHeight(height)
{
  this.styleObj.clip.height = height;
}

/////////////////////////////////////////////////////////////////////////////
// xbStyle.getWidth()

function nsxbStyleGetWidth()
{
  //if (this.styleObj.document && this.styleObj.document.width)
  //  return this.styleObj.document.width;
    
  return this.styleObj.clip.width;
}

/////////////////////////////////////////////////////////////////////////////
// xbStyle.setWidth()

// netscape will not dynamically change the width of a 
// layer. It will only happen upon a refresh.
function nsxbStyleSetWidth(width)
{
  this.styleObj.clip.width = width;
}

/////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////
// xbStyle.getVisibility()

function nsxbStyleGetVisibility()
{
  switch(this.styleObj.visibility)
  {
  case 'hide':
    return 'hidden';
  case 'show':
    return 'visible';
  }
  return '';
}

/////////////////////////////////////////////////////////////////////////////
// xbStyle.setVisibility()

function nsxbStyleSetVisibility(visibility)
{
  switch(visibility)
  {
  case 'hidden':
    visibility = 'hide';
    break;
  case 'visible':
    visibility = 'show';
    break;
  case 'inherit':
    break;
  default:
    visibility = 'show';
    break;
  }
  this.styleObj.visibility = visibility;
}

/////////////////////////////////////////////////////////////////////////////
// xbStyle.getzIndex()

function nsxbStyleGetzIndex()
{
  return this.styleObj.zIndex;
}

/////////////////////////////////////////////////////////////////////////////
// xbStyle.setzIndex()

function nsxbStyleSetzIndex(zIndex)
{
  this.styleObj.zIndex = zIndex;
}

/////////////////////////////////////////////////////////////////////////////
// xbStyle.getBackgroundColor()

function nsxbStyleGetBackgroundColor()
{
  return this.styleObj.bgColor;
}

/////////////////////////////////////////////////////////////////////////////
// xbStyle.setBackgroundColor()

function nsxbStyleSetBackgroundColor(color)
{
  if (color)
  {
    this.styleObj.bgColor = color;
    this.object.document.bgColor = color;
    this.resizeTo(this.getWidth(), this.getHeight());
  }
}

/////////////////////////////////////////////////////////////////////////////
// xbStyle.getColor()

function nsxbStyleGetColor()
{
  return '#ffffff';
}

/////////////////////////////////////////////////////////////////////////////
// xbStyle.setColor()

function nsxbStyleSetColor(color)
{
  this.object.document.fgColor = color;
}


/////////////////////////////////////////////////////////////////////////////
// xbStyle.moveAbove()

function xbStyleMoveAbove(cont)
{
  this.setzIndex(cont.getzIndex()+1);
}

/////////////////////////////////////////////////////////////////////////////
// xbStyle.moveBelow()

function xbStyleMoveBelow(cont)
{
  var zindex = cont.getzIndex() - 1;
            
  this.setzIndex(zindex);
}

/////////////////////////////////////////////////////////////////////////////
// xbStyle.moveBy()

function xbStyleMoveBy(deltaX, deltaY)
{
  this.moveTo(this.getLeft() + deltaX, this.getTop() + deltaY);
}

/////////////////////////////////////////////////////////////////////////////
// xbStyle.moveTo()

function xbStyleMoveTo(x, y)
{
  this.setLeft(x);
  this.setTop(y);
}

/////////////////////////////////////////////////////////////////////////////
// xbStyle.moveToAbsolute()

function xbStyleMoveToAbsolute(x, y)
{
  this.setPageX(x);
  this.setPageY(y);
}

/////////////////////////////////////////////////////////////////////////////
// xbStyle.resizeBy()

function xbStyleResizeBy(deltaX, deltaY)
{
  this.setWidth( this.getWidth() + deltaX );
  this.setHeight( this.getHeight() + deltaY );
}

/////////////////////////////////////////////////////////////////////////////
// xbStyle.resizeTo()

function xbStyleResizeTo(x, y)
{
  this.setWidth(x);
  this.setHeight(y);
}

////////////////////////////////////////////////////////////////////////
// Navigator 4.x resizing...

function nsxbStyleOnresize()
{
    if (saveInnerWidth != xbGetWindowWidth() || saveInnerHeight != xbGetWindowHeight())
    location.reload();

  return false;
}

/////////////////////////////////////////////////////////////////////////////
// xbStyle.setInnerHTML()

function nsxbSetInnerHTML(str)
{
  this.object.document.open('text/html');
  this.object.document.write(str);
  this.object.document.close();
}

 // Function assignments moved to end of xbStyle.js block.


/*
 * $Log: xbStyle-not-supported.js,v $
 * Revision 1.3  2002/07/22 14:19:42  bc6ix
 * fix license path
 *
 * Revision 1.2  2002/05/18 01:22:02  bc6ix
 * remove getClientTop/Left since they are not supported in anything but IE
 *
 * Revision 1.1  2002/05/16 15:02:50  bc6ix
 * split xbStyle.js into browser specific files
 *
 */

 // Function assignments moved to end of xbStyle.js block.

/* ***** BEGIN LICENSE BLOCK *****
 * Licensed under Version: MPL 1.1/GPL 2.0/LGPL 2.1
 * Full Terms at /lib/js/license/mpl-tri-license.txt
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Netscape code.
 *
 * The Initial Developer of the Original Code is
 * Netscape Corporation.
 * Portions created by the Initial Developer are Copyright (C) 2001
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s): Bob Clary <bclary@netscape.com>
 *
 * ***** END LICENSE BLOCK ***** */

/*
 * $Log: xbStyle.js,v $
 * Revision 1.9  2002/07/22 14:31:51  bc6ix
 * fix license path, remove ua.js detection, use xbLibrary to load scripts
 *
 * Revision 1.8  2002/07/11 11:30:52  bc6ix
 * getEffectiveValue - Special Case IE's Clip retrieval
 *
 * Revision 1.7  2002/05/16 15:02:50  bc6ix
 * split xbStyle.js into browser specific files
 *
 * Revision 1.6  2002/05/16 04:49:49  bc6ix
 *
 * xbStyle constructor - added window argument to allow getComputedStyle to
 * use the correct document.
 *
 * xbStyleGetEffectiveValue - qualified document references using window added
 * to xbStyle constructor. fixed DOM Style property name to CSS2 property
 * name conversion. Disable gecko work arounds (at least temporarily).
 *
 * cssStyleGetClip - return comma separated values.
 *
 * cssStyleGetClientXXX - return element.clientXXX temporarily while bugs
 * worked out.
 *
 * TODO: split into 3 files, fix Client properties (or remove them).
 *
 * Revision 1.5  2002/05/14 16:52:53  bc6ix
 * use CVS Log for revision history
 *
 */

/* ***** BEGIN LICENSE BLOCK *****
 * Licensed under Version: MPL 1.1/GPL 2.0/LGPL 2.1
 * Full Terms at /lib/js/license/mpl-tri-license.txt
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Netscape code.
 *
 * The Initial Developer of the Original Code is
 * Netscape Corporation.
 * Portions created by the Initial Developer are Copyright (C) 2001
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s): Bob Clary <bclary@netscape.com>
 *
 * ***** END LICENSE BLOCK ***** */

function xbStyleNotSupported() {}

function xbStyleNotSupportStringValue(propname) { xbDEBUG.dump(propname + ' is not supported in this browser'); return '';};

/////////////////////////////////////////////////////////////
// xbClipRect

function xbClipRect(a1, a2, a3, a4)
{
  this.top  = 0;
  this.right  = 0;
  this.bottom  = 0;
  this.left  = 0;

  if (typeof(a1) == 'string')
  {
    var val;
    var ca;
    var i;
      
    if (a1.indexOf('rect(') == 0)
    {
      // I would have preferred [0-9]+[a-zA-Z]+ for a regexp
      // but NN4 returns null for that. 
      ca = a1.substring(5, a1.length-1).match(/-?[0-9a-zA-Z]+/g);
      for (i = 0; i < 4; ++i)
      {
        val = xbToInt(ca[i]);
        if (val != 0 && ca[i].indexOf('px') == -1)
        {
          xbDEBUG.dump('xbClipRect: A clipping region ' + a1 + ' was detected that did not use pixels as units.  Click Ok to continue, Cancel to Abort');
          return;
        }
        ca[i] = val;
      }
      this.top    = ca[0];
      this.right  = ca[1];
      this.bottom = ca[2];
      this.left   = ca[3];
    }
  }    
  else if (typeof(a1) == 'number' && typeof(a2) == 'number' && typeof(a3) == 'number' && typeof(a4) == 'number')
  {
    this.top    = a1;
    this.right  = a2;
    this.bottom = a3;
    this.left   = a4;
  }
}

xbClipRect.prototype.top = 0;
xbClipRect.prototype.right = 0;
xbClipRect.prototype.bottom = 0;
xbClipRect.prototype.left = 0;


function xbClipRectGetWidth()
{
    return this.right - this.left;
}
xbClipRect.prototype.getWidth = xbClipRectGetWidth; 

function xbClipRectSetWidth(width)
{
  this.right = this.left + width;
}
xbClipRect.prototype.setWidth = xbClipRectSetWidth;

function xbClipRectGetHeight()
{
    return this.bottom - this.top;
}
xbClipRect.prototype.getHeight = xbClipRectGetHeight; 

function xbClipRectSetHeight(height)
{
  this.bottom = this.top + height;
}
xbClipRect.prototype.setHeight = xbClipRectSetHeight;

function xbClipRectToString()
{
  return 'rect(' + this.top + 'px ' + this.right + 'px ' + this.bottom + 'px ' + this.left + 'px )' ;
}
xbClipRect.prototype.toString = xbClipRectToString;

/////////////////////////////////////////////////////////////
// xbStyle
//
// Note Opera violates the standard by cascading the effective values
// into the HTMLElement.style object. We can use IE's HTMLElement.currentStyle
// to get the effective values. In Gecko we will use the W3 DOM Style Standard getComputedStyle

function xbStyle(obj, win, position)
{
  if (typeof(obj) == 'object' && typeof(obj.style) != 'undefined') 
    this.styleObj = obj.style;
  else if (document.layers) // NN4
  {
    if (typeof(position) == 'undefined')
      position = '';
        
    this.styleObj = obj;
    this.styleObj.position = position;
  }
  this.object = obj;
  this.window = win ? win : window;
}

xbStyle.prototype.styleObj = null;
xbStyle.prototype.object = null;

/////////////////////////////////////////////////////////////
// xbStyle.getEffectiveValue()
// note that xbStyle's constructor uses the currentStyle object 
// for IE5+ and that Opera's style object contains computed values
// already. Netscape Navigator's layer object also contains the 
// computed values as well. Note that IE4 will not return the 
// computed values.

function xbStyleGetEffectiveValue(propname)
{
  var value = null;

  if (this.window.document.defaultView && this.window.document.defaultView.getComputedStyle)
  {
    // W3
    // Note that propname is the name of the property in the CSS Style
    // Object. However the W3 method getPropertyValue takes the actual
    // property name from the CSS Style rule, i.e., propname is 
    // 'backgroundColor' but getPropertyValue expects 'background-color'.

     var capIndex;
     var cappropname = propname;

     while ( (capIndex = cappropname.search(/[A-Z]/)) != -1)
     {
       if (capIndex != -1)
       {
         cappropname = cappropname.substring(0, capIndex) + '-' + cappropname.substring(capIndex, capIndex+1).toLowerCase() + cappropname.substr(capIndex+1);
       }
     }

     value = this.window.document.defaultView.getComputedStyle(this.object, '').getPropertyValue(cappropname);

     // xxxHack for Gecko:
     if (!value && this.styleObj[propname])
     {
       value = this.styleObj[propname];
     }
  }
  else if (typeof(this.styleObj[propname]) == 'undefined') 
  {
    value = xbStyleNotSupportStringValue(propname);
  }
  else if (typeof(this.object.currentStyle) != 'undefined')
  {
    // IE5+
    value = this.object.currentStyle[propname];
    if (!value)
    {
      value = this.styleObj[propname];
    }

    if (propname == 'clip' && !value)
    {
      // clip is not stored in IE5/6 handle separately
      value = 'rect(' + this.object.currentStyle.clipTop + ', ' + this.object.currentStyle.clipRight + ', ' + this.object.currentStyle.clipBottom + ', ' + this.object.currentStyle.clipLeft + ')';
    }
  }
  else
  {
    // IE4+, Opera, NN4
    value = this.styleObj[propname];
  }

  return value;
}

/////////////////////////////////////////////////////////////////////////////
// xbStyle.moveAbove()

function xbStyleMoveAbove(cont)
{
  this.setzIndex(cont.getzIndex()+1);
}

/////////////////////////////////////////////////////////////////////////////
// xbStyle.moveBelow()

function xbStyleMoveBelow(cont)
{
  var zindex = cont.getzIndex() - 1;
            
  this.setzIndex(zindex);
}

/////////////////////////////////////////////////////////////////////////////
// xbStyle.moveBy()

function xbStyleMoveBy(deltaX, deltaY)
{
  this.moveTo(this.getLeft() + deltaX, this.getTop() + deltaY);
}

/////////////////////////////////////////////////////////////////////////////
// xbStyle.moveTo()

function xbStyleMoveTo(x, y)
{
  this.setLeft(x);
  this.setTop(y);
}

/////////////////////////////////////////////////////////////////////////////
// xbStyle.moveToAbsolute()

function xbStyleMoveToAbsolute(x, y)
{
  this.setPageX(x);
  this.setPageY(y);
}

/////////////////////////////////////////////////////////////////////////////
// xbStyle.resizeBy()

function xbStyleResizeBy(deltaX, deltaY)
{
  this.setWidth( this.getWidth() + deltaX );
  this.setHeight( this.getHeight() + deltaY );
}

/////////////////////////////////////////////////////////////////////////////
// xbStyle.resizeTo()

function xbStyleResizeTo(x, y)
{
  this.setWidth(x);
  this.setHeight(y);
}

////////////////////////////////////////////////////////////////////////

xbStyle.prototype.getEffectiveValue     = xbStyleGetEffectiveValue;
xbStyle.prototype.moveAbove             = xbStyleMoveAbove;
xbStyle.prototype.moveBelow             = xbStyleMoveBelow;
xbStyle.prototype.moveBy                = xbStyleMoveBy;
xbStyle.prototype.moveTo                = xbStyleMoveTo;
xbStyle.prototype.moveToAbsolute        = xbStyleMoveToAbsolute;
xbStyle.prototype.resizeBy              = xbStyleResizeBy;
xbStyle.prototype.resizeTo              = xbStyleResizeTo;

if (document.all || document.getElementsByName)
{
  //xblibrary.loadScript('xbStyle-css.js');

  xbStyle.prototype.getClip            = cssStyleGetClip;
  xbStyle.prototype.setClip            = cssStyleSetClip;  
  xbStyle.prototype.getClipTop         = cssStyleGetClipTop;
  xbStyle.prototype.setClipTop         = cssStyleSetClipTop;  
  xbStyle.prototype.getClipRight       = cssStyleGetClipRight;
  xbStyle.prototype.setClipRight       = cssStyleSetClipRight;  
  xbStyle.prototype.getClipBottom      = cssStyleGetClipBottom;
  xbStyle.prototype.setClipBottom      = cssStyleSetClipBottom;  
  xbStyle.prototype.getClipLeft        = cssStyleGetClipLeft;
  xbStyle.prototype.setClipLeft        = cssStyleSetClipLeft;  
  xbStyle.prototype.getClipWidth       = cssStyleGetClipWidth;
  xbStyle.prototype.setClipWidth       = cssStyleSetClipWidth;  
  xbStyle.prototype.getClipHeight      = cssStyleGetClipHeight;
  xbStyle.prototype.setClipHeight      = cssStyleSetClipHeight;  
  xbStyle.prototype.getLeft            = cssStyleGetLeft;
  xbStyle.prototype.setLeft            = cssStyleSetLeft;
  xbStyle.prototype.getTop             = cssStyleGetTop;
  xbStyle.prototype.setTop             = cssStyleSetTop;
  xbStyle.prototype.getPageX           = cssStyleGetPageX;
  xbStyle.prototype.setPageX           = cssStyleSetPageX;
  xbStyle.prototype.getPageY           = cssStyleGetPageY;
  xbStyle.prototype.setPageY           = cssStyleSetPageY;
  xbStyle.prototype.getVisibility      = cssStyleGetVisibility;
  xbStyle.prototype.setVisibility      = cssStyleSetVisibility;
  xbStyle.prototype.getzIndex          = cssStyleGetzIndex;
  xbStyle.prototype.setzIndex          = cssStyleSetzIndex;            
  xbStyle.prototype.getHeight          = cssStyleGetHeight;
  xbStyle.prototype.setHeight          = cssStyleSetHeight;
  xbStyle.prototype.getWidth           = cssStyleGetWidth;
  xbStyle.prototype.setWidth           = cssStyleSetWidth;
  xbStyle.prototype.getBackgroundColor = cssStyleGetBackgroundColor;
  xbStyle.prototype.setBackgroundColor = cssStyleSetBackgroundColor;
  xbStyle.prototype.getColor           = cssStyleGetColor;
  xbStyle.prototype.setColor           = cssStyleSetColor;
  xbStyle.prototype.setInnerHTML       = xbSetInnerHTML;
  xbStyle.prototype.getBorderTopWidth    = cssStyleGetBorderTopWidth;
  xbStyle.prototype.getBorderRightWidth  = cssStyleGetBorderRightWidth;
  xbStyle.prototype.getBorderBottomWidth = cssStyleGetBorderBottomWidth;
  xbStyle.prototype.getBorderLeftWidth   = cssStyleGetBorderLeftWidth;
  xbStyle.prototype.getMarginLeft        = cssStyleGetMarginLeft;
  xbStyle.prototype.getMarginTop         = cssStyleGetMarginTop;
  xbStyle.prototype.getMarginRight       = cssStyleGetMarginRight;
  xbStyle.prototype.getMarginBottom      = cssStyleGetMarginBottom;
  xbStyle.prototype.getMarginLeft        = cssStyleGetMarginLeft;
  xbStyle.prototype.getPaddingTop        = cssStyleGetPaddingTop;
  xbStyle.prototype.getPaddingRight      = cssStyleGetPaddingRight;
  xbStyle.prototype.getPaddingBottom     = cssStyleGetPaddingBottom;
  xbStyle.prototype.getPaddingLeft       = cssStyleGetPaddingLeft;
  xbStyle.prototype.getClientWidth       = cssStyleGetClientWidth;
  xbStyle.prototype.getClientHeight      = cssStyleGetClientHeight;
}
else if (document.layers)
{
  //xblibrary.loadScript('xbStyle-nn4.js');

  xbStyle.prototype.getClip            = nsxbStyleGetClip;
  xbStyle.prototype.setClip            = nsxbStyleSetClip;  
  xbStyle.prototype.getClipTop         = nsxbStyleGetClipTop;
  xbStyle.prototype.setClipTop         = nsxbStyleSetClipTop;  
  xbStyle.prototype.getClipRight       = nsxbStyleGetClipRight;
  xbStyle.prototype.setClipRight       = nsxbStyleSetClipRight;  
  xbStyle.prototype.getClipBottom      = nsxbStyleGetClipBottom;
  xbStyle.prototype.setClipBottom      = nsxbStyleSetClipBottom;  
  xbStyle.prototype.getClipLeft        = nsxbStyleGetClipLeft;
  xbStyle.prototype.setClipLeft        = nsxbStyleSetClipLeft;  
  xbStyle.prototype.getClipWidth       = nsxbStyleGetClipWidth;
  xbStyle.prototype.setClipWidth       = nsxbStyleSetClipWidth;  
  xbStyle.prototype.getClipHeight      = nsxbStyleGetClipHeight;
  xbStyle.prototype.setClipHeight      = nsxbStyleSetClipHeight;  
  xbStyle.prototype.getLeft            = nsxbStyleGetLeft;
  xbStyle.prototype.setLeft            = nsxbStyleSetLeft;
  xbStyle.prototype.getTop             = nsxbStyleGetTop;
  xbStyle.prototype.setTop             = nsxbStyleSetTop;
  xbStyle.prototype.getPageX           = nsxbStyleGetPageX;
  xbStyle.prototype.setPageX           = nsxbStyleSetPageX;
  xbStyle.prototype.getPageY           = nsxbStyleGetPageY;
  xbStyle.prototype.setPageY           = nsxbStyleSetPageY;
  xbStyle.prototype.getVisibility      = nsxbStyleGetVisibility;
  xbStyle.prototype.setVisibility      = nsxbStyleSetVisibility;
  xbStyle.prototype.getzIndex          = nsxbStyleGetzIndex;
  xbStyle.prototype.setzIndex          = nsxbStyleSetzIndex;            
  xbStyle.prototype.getHeight          = nsxbStyleGetHeight;
  xbStyle.prototype.setHeight          = nsxbStyleSetHeight;
  xbStyle.prototype.getWidth           = nsxbStyleGetWidth;
  xbStyle.prototype.setWidth           = nsxbStyleSetWidth;
  xbStyle.prototype.getBackgroundColor = nsxbStyleGetBackgroundColor;
  xbStyle.prototype.setBackgroundColor = nsxbStyleSetBackgroundColor;
  xbStyle.prototype.getColor           = nsxbStyleGetColor;
  xbStyle.prototype.setColor           = nsxbStyleSetColor;
  xbStyle.prototype.setInnerHTML       = nsxbSetInnerHTML;
  xbStyle.prototype.getBorderTopWidth    = xbStyleNotSupported;
  xbStyle.prototype.getBorderRightWidth  = xbStyleNotSupported;
  xbStyle.prototype.getBorderBottomWidth = xbStyleNotSupported;
  xbStyle.prototype.getBorderLeftWidth   = xbStyleNotSupported;
  xbStyle.prototype.getMarginLeft        = xbStyleNotSupported;
  xbStyle.prototype.getMarginTop         = xbStyleNotSupported;
  xbStyle.prototype.getMarginRight       = xbStyleNotSupported;
  xbStyle.prototype.getMarginBottom      = xbStyleNotSupported;
  xbStyle.prototype.getMarginLeft        = xbStyleNotSupported;
  xbStyle.prototype.getPaddingTop        = xbStyleNotSupported;
  xbStyle.prototype.getPaddingRight      = xbStyleNotSupported;
  xbStyle.prototype.getPaddingBottom     = xbStyleNotSupported;
  xbStyle.prototype.getPaddingLeft       = xbStyleNotSupported;
  xbStyle.prototype.getClientWidth       = xbStyleNotSupported;
  xbStyle.prototype.getClientHeight      = xbStyleNotSupported;

  window.saveInnerWidth = window.innerWidth;
  window.saveInnerHeight = window.innerHeight;

  window.onresize = nsxbStyleOnresize;
}
else 
{
  //xblibrary.loadScript('xbStyle-not-supported.js');

  xbStyle.prototype.toString           = xbStyleNotSupported;
  xbStyle.prototype.getClip            = xbStyleNotSupported;
  xbStyle.prototype.setClip            = xbStyleNotSupported;
  xbStyle.prototype.getClipTop         = xbStyleNotSupported;
  xbStyle.prototype.setClipTop         = xbStyleNotSupported;
  xbStyle.prototype.getClipRight       = xbStyleNotSupported;
  xbStyle.prototype.setClipRight       = xbStyleNotSupported;
  xbStyle.prototype.getClipBottom      = xbStyleNotSupported;
  xbStyle.prototype.setClipBottom      = xbStyleNotSupported;
  xbStyle.prototype.getClipLeft        = xbStyleNotSupported;
  xbStyle.prototype.setClipLeft        = xbStyleNotSupported;
  xbStyle.prototype.getClipWidth       = xbStyleNotSupported;
  xbStyle.prototype.setClipWidth       = xbStyleNotSupported;
  xbStyle.prototype.getClipHeight      = xbStyleNotSupported;
  xbStyle.prototype.setClipHeight      = xbStyleNotSupported;
  xbStyle.prototype.getLeft            = xbStyleNotSupported;
  xbStyle.prototype.setLeft            = xbStyleNotSupported;
  xbStyle.prototype.getTop             = xbStyleNotSupported;
  xbStyle.prototype.setTop             = xbStyleNotSupported;
  xbStyle.prototype.getVisibility      = xbStyleNotSupported;
  xbStyle.prototype.setVisibility      = xbStyleNotSupported;
  xbStyle.prototype.getzIndex          = xbStyleNotSupported;
  xbStyle.prototype.setzIndex          = xbStyleNotSupported;
  xbStyle.prototype.getHeight          = xbStyleNotSupported;
  xbStyle.prototype.setHeight          = xbStyleNotSupported;
  xbStyle.prototype.getWidth           = xbStyleNotSupported;
  xbStyle.prototype.setWidth           = xbStyleNotSupported;
  xbStyle.prototype.getBackgroundColor = xbStyleNotSupported;
  xbStyle.prototype.setBackgroundColor = xbStyleNotSupported;
  xbStyle.prototype.getColor           = xbStyleNotSupported;
  xbStyle.prototype.setColor           = xbStyleNotSupported;
  xbStyle.prototype.setInnerHTML       = xbStyleNotSupported;
  xbStyle.prototype.getBorderTopWidth    = xbStyleNotSupported;
  xbStyle.prototype.getBorderRightWidth  = xbStyleNotSupported;
  xbStyle.prototype.getBorderBottomWidth = xbStyleNotSupported;
  xbStyle.prototype.getBorderLeftWidth   = xbStyleNotSupported;
  xbStyle.prototype.getMarginLeft        = xbStyleNotSupported;
  xbStyle.prototype.getMarginTop         = xbStyleNotSupported;
  xbStyle.prototype.getMarginRight       = xbStyleNotSupported;
  xbStyle.prototype.getMarginBottom      = xbStyleNotSupported;
  xbStyle.prototype.getMarginLeft        = xbStyleNotSupported;
  xbStyle.prototype.getPaddingTop        = xbStyleNotSupported;
  xbStyle.prototype.getPaddingRight      = xbStyleNotSupported;
  xbStyle.prototype.getPaddingBottom     = xbStyleNotSupported;
  xbStyle.prototype.getPaddingLeft       = xbStyleNotSupported;
  xbStyle.prototype.getClientWidth       = xbStyleNotSupported;
  xbStyle.prototype.getClientHeight      = xbStyleNotSupported;

}


/* xbMapIcon.js
 *
 * Each icon for Gateway Guides needed a place to store related information.
 * xbMapIcon provides a nice object to store most values for mapping icons 
 * on each <div> layer to their respective counterparts.
 *
 * Date:    	24 Sept 2002
 *
 */

/** Constructor */
function MapIcon(id, index, x, y, left, top, right, bottom, content) {

  // Create a new MapIcon object.
  this.id 	= id;				// object id
  this.index  	= index;			// object index
  this.x 	= x;				// x-coord of MapIcon on map
  this.y 	= y;				// y-coord of MapIcon on map
  this.left 	= left;
  this.top 	= top;
  this.right 	= right;
  this.bottom 	= bottom;
  this.content	= content;

  // private
  this.divid	= this.id			// correlating div id
  this.zIndex 	= this.index;			// layer number (immutable)
  this.zCurrent = this.zIndex;			// current layer assignment

}

function MapIcon_getzIndexById(id) {
  var elem = xbGetElementById(id);

  if (elem) {
    var elemstyle = new xbStyle(elem);
    return elemstyle.getzIndex();
  } else {
    return -1;
  }

}

/*
 * Map private functions to public functions
 *
 */
MapIcon.getzIndexById = MapIcon_getzIndexById;

/* xbSupport.js
 *
 * Contains all DHTML and Event Handler information for Gateway Guide 
 * St. Louis.  Works with Netscape 4, IE 4+, IE 5/6, and all Gecko-based 
 * browsers (Netscape 6/7, Mozilla).  Does not work with any Opera browsers.
 *
 * Requires: 	xbLibrary.js
 *		xbDebug.js
 *		xbDOM.js
 *		xbStyle.js
 *		xbStyle-css.js
 *		xbStyle-nn4.js
 *		xbStyle-not-supported.js
 *		xbMapIcon.js
 *		errors.html
 *
 * Note:	With the exception of xbMapIcon.js and xbSupport.js, all .js
 *		files can be obtained from http://devedge.netscape.com/
 *
 *		xbLibrary also has minor modifications reflecting a change
 *		in the default script location.  The default location should be 
 *		changed from '/lib/js/' to 'lib/js/'.  
 *
 *		Also, there is a change in where the debugging page for 
 *		downlevel browsers is located.  There is an HTML page which 
 *		has been created for that purpose.  This error page is called 
 *		errors.html.
 *
 *
 * Author:  	Paul Nues
 * Date:    	24 Sept 2002
 *
 */

var MapIconInfo		= new Array();
var layerList 		= new Array();
var clickedObjects 	= new Array();
var num_layers 		= 0;

function printDiv(id, left, top, width, height, visible, content, desc, moused, iNe) {

  var z = num_layers;

  var elem = xbGetElementById(id);
  var tmp = null;

  if (!elem) {
    num_layers++;

    if (document.layers) {
      document.writeln('<layer name="' + id + '" left=' + left + ' top=' + top + ' width=' + width + ' height=' + height +  ' visibility=' + (visible ? '"show"' : '"hide"') + ' z-index=' + z + '>');
      document.writeln(content);
      document.writeln('</layer>');
    } else {
      // IE and Gecko
      var divbegin = '<div id="' + id + '">';
      if (typeof(document.bgColor) == 'string') {
	divbegin = '<div id="' + id + '" style="position:absolute; overflow:none; left:' + left + 'px; top:' + top + 'px; width:' + width + 'px; height:' + height + 'px;' + ' visibility:' + (visible ? 'visible;' : 'hidden;') + ' z-index=' + z + '">';
	document.writeln(divbegin);
	document.writeln(content);
	document.writeln('</div>');

	// print div description
	//divbegin = '<div id="' + id + '-desc" style="position:absolute; overflow:auto; width: 300px; height: 100px;' + ' border: thin solid black; background-color: #ffffcc; font-size: 8pt; visibility: hidden;">';
	//document.writeln(divbegin);
	//document.writeln(desc);
	//document.writeln('</div>');
      } else {
	// Opera 5/6 does not implement bgColor and such
	//divbegin = '<div id="' + id + '" style="position: absolute; overflow: none; height: ' + height + 'px; width: ' + width + 'px; visibility: ' + (visible ? 'visible;' : 'hidden;') + ' z-index= ' + z + '">';
	//alert("divbegin: " + divbegin);
	//document.writeln(divbegin);
	//document.writeln(content);
	//document.writeln('</div>');

	//tmp = xbGetElementById(id);
	//if (tmp) {
	//  alert("found tmp");
	//  var tmpelemstyle = new xbStyle(tmp);
	//  tmpelemstyle.setLeft(left);
	//  tmpelemstyle.setTop(top);
	  //tmpelemstyle.moveToAbsolute(left, top);
	//}
	//alert("after");
	  
      }

    }

    // get element again to set background image
    tmp = xbGetElementById(id);
    if (tmp) {
      if (iNe) {
	setBackgroundImage(id, iNe);
      }

      if (moused) {
      }
    }

  } else { 
    //set properties to what was passed in
    //construct an xbStyle object
    var elemstyle = new xbStyle(elem);
    var visibility = (visible ? "visible" : "hidden");

    elemstyle.setVisibility(visibility);
    elemstyle.setLeft(left);
    elemstyle.setTop(top);
    elemstyle.setHeight(height);
    elemstyle.setWidth(width);
    elemstyle.setBackgroundImage(id, iNe);
    elemstyle.moveToAbsolute(left, top);
  }

  if (elemstyle) {
    elemstyle = new xbStyle(elem);
    clipString = "rect(0px, 0px, " + width + "px, " + height + "px)";
    elemstyle.setClip(clipString);
  }
}

function setBackgroundImage(elem, src) {

  if (document.getElementById) {
    elem.setAttribute("SRC", src);
  } else if (document.all) {
    elem.backgroundImage = "url(" + src + ")";
  } else if (document.layers) {
    elem.background.src = src;
  } else {
    // do nothing
  }

}

function moveDiv(id, x, y) {
  var elem = xbGetElementById(id);

  if (elem) {
    //construct an xbStyle object
    var elemstyle = new xbStyle(elem);
    elemstyle.moveToAbsolute(x, y);
  }

}
////////////////////////////////////////////////////////////////////////////////
//
// Event handlers
//
////////////////////////////////////////////////////////////////////////////////
function getMousePosition(e) {
  if (!e) e = window.event;	// IE Event Model

  var depth = MapIconInfo.length;

  if (document.getElementById) { 
    if (typeof(window.pageXOffset) == "number") { // Netscape 6/7
      mouseX = e.clientX + window.pageXOffset;
      mouseY = e.clientY + window.pageYOffset;
    } else { // IE 5+
      mouseX = e.clientX + document.body.scrollLeft;
      mouseY = e.clientY + document.body.scrollTop;
    }

  } else if (document.all) {
    mouseX = e.clientX + document.body.scrollLeft;
    mouseY = e.clientY + document.body.scrollTop;

  } else if (document.layers) {
    mouseX = e.pageX;
    mouseY = e.pageY;

  } else {
    mouseX = -1;
    mouseY = -1;
  }

  //check to see if mouse is within confines of graphic map
  if ((mouseX >= MapIconInfo[0].left && mouseX < MapIconInfo[0].right) &&
      (mouseY >= MapIconInfo[0].top && mouseY < MapIconInfo[0].bottom)) {

    window.status = mouseX + "," + mouseY; 
    setLayerDepth(e, mouseX, mouseY, depth);

  }


  return false;
}

function handleMouseDown(e) {
  if (!e) e = window.event;	// IE Event Model
  
  if (document.getElementById) { 
    if (typeof(window.pageXOffset) == "number") { // Netscape 6/7
      mouseX = e.clientX + window.pageXOffset;
      mouseY = e.clientY + window.pageYOffset;
    } else { // IE 5+ 
      mouseX = e.clientX + document.body.scrollLeft;
      mouseY = e.clientY + document.body.scrollTop;
    }
  } else if (document.all) {
    mouseX = e.clientX + document.body.scrollLeft;
    mouseY = e.clientY + document.body.scrollTop;

  } else if (document.layers) {
    mouseX = e.pageX;
    mouseY = e.pageY;

  } else {
    mouseX = -1;
    mouseY = -1;
  }

  //alert(mouseX + ", " + mouseY);
  clickedObjects = getIncidentDescFromCoordinates(mouseX, mouseY);

  if(clickedObjects.length > 0) {
    clickOnIcon(clickedObjects); 
  }


  return true;
}

// there might be multiple incidents associated with coordinates.  this 
// provides an array of objects connected with x- & y-coordinates
function getIncidentDescFromCoordinates(mouseX, mouseY) {

  var objects = new Array();
  var depth = MapIconInfo.length-1;
  var j=0;

  //alert("depth = " + depth);
  for(i=depth; i > 0; i--) {

    // for each object, if mouse lies in between x and y-coordinates 
    if ((mouseX >= MapIconInfo[i].x + MapIconInfo[i].left && 
	 mouseX < MapIconInfo[i].x + MapIconInfo[i].right) &&
        (mouseY >= MapIconInfo[i].y + MapIconInfo[i].top && 
         mouseY < MapIconInfo[i].y + MapIconInfo[i].bottom)
       ) {
	    objects[j] = MapIconInfo[i];
	    j++;      
    }
  }

  return objects;
}

// depending if mouse travels into sweet spot, layer depth levels will be 
// adjusted
function setLayerDepth(e, mouseX, mouseY, layer_depth) {
  
  // for each object, 
  // if mouse lies in between x and y-coordinates, place layer at the top
  //   of the stack
  // else 
  //   place layer back in the stack in it's original level
  for (var i=layer_depth-1; i >= 1; i--) {

    if ((mouseX >= MapIconInfo[i].x + MapIconInfo[i].left && 
	 mouseX < MapIconInfo[i].x + MapIconInfo[i].right) &&
        (mouseY >= MapIconInfo[i].y + MapIconInfo[i].top && 
         mouseY < MapIconInfo[i].y + MapIconInfo[i].bottom)
       ) {

	 if (MapIconInfo[i].zCurrent == layer_depth+1) {
	   break;
	 }

	 setDivzIndex(MapIconInfo[i].id, layer_depth+1);
	 MapIconInfo[i].zCurrent = layer_depth+1;

	 //if (document.getElementById) {
	 // var elem = xbGetElementById(MapIconInfo[i].divid+"-desc");
	 // if (elem) {
	 //   var elemstyle = new xbStyle(elem);
	 //   elemstyle.setVisibility("visible");
	 //   elemstyle.setzIndex(MapIconInfo[i].zCurrent);
	 //   elemstyle.moveToAbsolute(MapIconInfo[i].x+40, MapIconInfo[i].y+40);
	 // }
	 //}

	 //alert("placing layer "+i+" at depth "+(layer_depth+1));
	 //alert("yes: " + mouseX + "," + mouseY + "  Current layer " + i 
		//+ "  CurrentZ " + layer_depth + " MapIconInfo["+i+"].zCurrent = " + MapIconInfo[i].zCurrent);

    } else {
	 if (MapIconInfo[i].zCurrent == layer_depth+1) {
	   setDivzIndex(MapIconInfo[i].id, MapIconInfo[i].zIndex);
	   MapIconInfo[i].zCurrent = MapIconInfo[i].zIndex; 
	   //alert("placing layer "+i+" at depth "+MapIconInfo[i].zIndex);
	   //alert("no: " + mouseX + "," + mouseY + "  Current layer " + i 
		//+ "  CurrentZ " + layer_depth + " MapIconInfo["+i+"].zCurrent = " + MapIconInfo[i].zCurrent);

	   //if (document.getElementById) {
	   // var elem = xbGetElementById(MapIconInfo[i].divid+"-desc");
	   // if (elem) {
	   //   var elemstyle = new xbStyle(elem);
	   //   elemstyle.setVisibility("hidden");
	   // }
	   //}

	 }

	 /*
	 if (e.stopPropagation) {
	   e.stopPropagation();
	 } else if (e.cancelBubble) {
	   e.cancelBubble = true;
	 } else {
	   // do nothing
	 }
	 */

    }

  }

  return;
}

function getDivzIndex(id) {

  var elem = xbGetElementById(id);

  if (elem) {
    var elemstyle = new xbStyle(elem);
    return elemstyle.getzIndex();
  } else {
    return -1;
  }

}

function setDivzIndex(id, index) {

  var elem = xbGetElementById(id);

  if (elem) {
    var elemstyle = new xbStyle(elem);
    elemstyle.setzIndex(index);
  }

}

function start() {
  //alert("in Start");

  if (document.addEventListener) { // DOM Level 2 Event Model
    document.addEventListener("mousemove", getMousePosition, true);
    document.addEventListener("mousedown", handleMouseDown, true);

  } else if (document.attachEvent) { // IE 5+ Event Model
    document.attachEvent("onmousemove", getMousePosition);
    document.attachEvent("onmousedown", handleMouseDown);

  } else if (document.layers) { // NS 4 Event Model
    document.captureEvents(Event.MOUSEMOVE |
			   Event.MOUSEDOWN);

    document.onmousemove = getMousePosition;
    document.onmousedown = handleMouseDown;

  } else if (document.all) { // IE 4 Event Model
    document.onmousemove = getMousePosition;
    document.onmousedown = handleMouseDown;

  } else {
    //not supported
  }
  
   
  loop();

}

function loop() {

  var i, j;

  // Repeat this loop after a set interval.
  animateID = setTimeout("loop()", 1000);
}
