/*
  # treeview.js                             Version 0.2
  # Copyright (c) 2003 Luca Borrione        write@tiscali.no-spam.it
  # Created 15 May 2003                     Last Modified 02 July 2003
  # _________________
  # COPYRIGHT NOTICE:
  # Copyright (c) 2003 Luca Borrione  All Rights Reserved.
  # Permission granted to use and modify free of charge this script so long as this
  # copyright notice above is maintained, modifications are documented,
  # and credit is given for any use of the script.
  # By using this code you agree to indemnify Luca Borrione from any liability that
  # might arise from its use.
  # Selling the code contained in this script without prior written consent is
  # expressly forbidden.
  # Obtain permission before redistributing this script over the Internet or
  # in any other medium.
  # In all cases copyright and header must remain intact.
  #
  # _____________
  # CONFIGURATION:
*/

//  _____________
//  Public  Vars:
//

//
//  String
//  Default target of any tree link.
//
var TW_TARGET       = '_blank';

//
//  Boolean
//  Determines whetever items text must be hyperlinks
//  (Icon images will always be hyperlinks)
//
var TW_TEXTONLY     = false;

//
//  Boolean
//  Defines if delay the construction of nodes
//  (if the browser allows it)
//
var TW_USEDEFERRAL     = true;

//
//  Boolean
//  Determines whetever to use icon images.
// (Node icons will always be shown)
//
var TW_USEICONS        = true;

//
//  String
//  Class name of the highlighted status
//
var TW_HIGHLIGHT       = '';

//
//  String
//  Path to the folder in which the icon images are located
//  (When setted must finish with a trailing slash) 
//
var TW_ICONPATH = '';

//
//  String
//  First part of the id given to links:
//  TW_TEXTIDPFX + linkNumber
//  
//  Purpose:
//  To know how to reach a link by id,
//  to know its linkNumer tou can move your mouse
//  over an icon and read the status bar.
//  
//  It's better to use only alphadigits.
//
var TW_TEXTIDPFX = "TWTextLink";

//
//  Boolean
//  Defines if all the folders of the tree start opened.
//
//  Apply to tree
//
var TW_STARTALLOPEN  = true;

//
//  Numeric
//  Defines the starting opened level of the tree.
//  If STARTALLOPEN is set on true, 
//  this becomes meaningless and so all the levels will start opened.
//
//  Apply to tree
//
var TW_STARTINGDEEP = 1;

//
//  Numeric
//
//  Apply to tree
//
var TW_TOP  = 0;
var TW_LEFT = 0;

//  Array
//  Icons image filenames.
//
TW_ICONS                  = [];
// Node Icons
TW_ICONS['lastNode']      = "lastNode.gif";
TW_ICONS['minusLastNode'] = "minusLastNode.gif";
TW_ICONS['plusLastNode']  = "plusLastNode.gif";
TW_ICONS['node']          = "node.gif";
TW_ICONS['minusNode']     = "minusNode.gif";
TW_ICONS['plusNode']      = "plusNode.gif";
TW_ICONS['verLine']       = "verLine.gif";
TW_ICONS['verLineBg']     = "verLineBg.gif";
// Icons
TW_ICONS['opened']        = "folderOpen.gif";
TW_ICONS['closed']        = "folderClosed.gif";
TW_ICONS['link']          = "item.gif";
// Special
TW_ICONS['blank']         = "blank.gif";

//
// This one seems not to have any influence
// var NOWRAP          = false;

/*
  # ____________
  # SCRIPT CODE:
*/

//
//  Private Vars:
//
TW = [];
TW['usedeferral']   = false;
TW['nn4Top']        = 0;
TW['browserType']   = 0;
TW['items']         = [];
TW['undoHighlight'] = '';
TW['trees']         = [];

//
//  BROWSER COMPATIBILITY
//
if (is.nn4) {
  TW['browserType'] = 1;
  TW['usedeferral'] = false;
} else if (is.ie4up || is.opera7up) {
  TW['usedeferral'] = !(is.mac && is.ie4);
  TW['browserType'] = 2;
} else if (is.nn5up) {
  TW['browserType'] = 3;
  TW['usedeferral'] = true;
}


/////////////////////////////
// Class Constructor: Item //
/////////////////////////////

function Item(text, href, target) {
  //
  // Public Vars (Globally configurable)
  //
  this.target      = (target) ? target : TW_TARGET;
  this.textonly    = TW_TEXTONLY;
  this.usedeferral = (TW_USEDEFERRAL) ? (TW['usedeferral']) : false;
  this.useicons    = TW_USEICONS;
  this.highlight   = TW_HIGHLIGHT;
  this.iconpath    = (TW_ICONPATH != '' && TW_ICONPATH.charAt(TW_ICONPATH.length-1) != '/') ? TW_ICONPATH + '/' : TW_ICONPATH;
  //
  // Public Vars
  //
  this.text          = text || ''; 
  this.href          = href || null;
  this.id            = null; // Pseudo-public (see initItem)
  this.xId           = '';   // Debugging purpose
  this.icon          = this.iconpath + TW_ICONS['link'];
  this.idPrefix      = 'item';
  this.onclick       = null;
  //
  // Private Vars
  //
  this.deep          = 0;
  this.leftSide      = "";
  this.parent        = null;
  this.object        = null;
  this.iconImgTag    = null;
  this.children      = [];
  this.className     = '';
  this.rendered      = false;
  this.isLastNode    = false;
  //
  // Method: initItem
  //
  this.initItem = function (deep, lastNode, leftSide) {
    if (typeof deep     == "undefined") {deep     = 0;}
    if (typeof lastNode == "undefined") {lastNode = true;}
    if (typeof leftSide == "undefined") {leftSide = "";}
    
    // Pseudo-public id
    if (this.id && this.id.constructor == String) {
      TW['items'][this.id] = TW['items'].length;
      this.xId = this.id;
    }
    this.id = TW['items'].length;
    TW['items'][TW['items'].length] = this;

    this.deep       = deep;
    this.isLastNode = lastNode;
    this.leftSide   = leftSide;
    
    if (this.isFolder) {
      if (TW['browserType'] == 0 || TW_STARTALLOPEN || deep < TW_STARTINGDEEP)
        this.opened = true;
  
      if (this.children.length > 0) { 
        if (deep > 0)
          leftSide += (lastNode) ? "0" : "1";
        deep++;
        for (var i=0 ; i<this.children.length; i++) {
          lastNode = (i == this.children.length-1);
          this.children[i].initItem(deep, lastNode, leftSide);
        } 
      }
    }
  }
  //
  // Method: render
  //
  this.render = function (insertAtObj) {
    var html = this.getHTML();  
    if (typeof insertAtObj == 'undefined' || insertAtObj == null) {
      if (this.usedeferral && this.isFolder && !TW_STARTALLOPEN && !TW_STARTINGDEEP) {
        // Switch from regular flow HTML to node-insert DOM DHTML
        document.write('<div id="domRoot'+ this.id +'"></div>'); 
        insertAtObj = getElById("domRoot"+ this.id);
        insertAtObj.insertAdjacentHTML("beforeEnd", html);
      } else document.write(html);
    } else insertAtObj.insertAdjacentHTML("afterEnd", html);
    
    this.object = getElById(this.idPrefix + this.id);
    if (this.useicons)
      this.iconImgTag = getElById(this.idPrefix + "Icon" + this.id);
    this.nodeImg = getElById("nodeIcon" + this.id);
    if (TW['browserType'] == 1)
      TW['nn4Top'] += this.object.clip.height;
    this.rendered = true;
  }
  //
  // Method: show
  //
  this.show   = function (object) {
    if (!this.rendered)
       this.render(object);
    else if (TW['browserType'] >= 2) 
      this.object.style.display = "block";
    else if (TW['browserType'] == 1)
      this.object.visibility = "show";
  }
  //
  // Method: hide
  //
  this.hide   = function () {
    if (this.isFolder)
      this.setOpened(0);
    if (TW['browserType'] >= 2) 
      this.object.style.display = "none";
    else if (TW['browserType'] == 1)
      this.object.visibility = "hide";
  }
  //
  // Method: openParentFolders
  //
  this.openParentFolders = function () {
    if (this.parent == null || this.parent.opened)
      return;
    else {
      this.parent.openParentFolders();
      // TW_clickOnNode (this.parent.id);
      this.parent.setOpened(true);
    }
  }
  //
  // Method: totalHeight
  // TW['browserType'] == 1
  // Purpose:
  //   Returns the total height
  //   of all opened subItems
  //
  this.totalHeight = function () { 
    var height = this.object.clip.height;
    if (this.opened)
      for (var i=0 ; i<this.children.length; i++)  
        height += this.children[i].totalHeight();
    return height;
  }
  //
  //  Method: expandAll
  //  Purpose:
  //  Expand all the sub folders of a given folder
  //
  this.expandAll = function () {
    var child;
    this.openParentFolders();
    if (!this.opened)
      this.setOpened(true);
    for (var i=0 ; i<this.children.length; i++) {
      child = this.children[i];
      if (child.isFolder && !child.opened)
        child.expandAll();
    }
  }
  
  /* ****************
     * OUTPUT HTML: *
     **************** */
     
  //
  //  Method: getHTML
  //
  this.getHTML = function () {
    NOWRAP          = false;
    var nowrap = (NOWRAP) ? ' nowrap' : '';
    var html = "";
    if (TW['browserType'] == 1) {
      var html = '<layer id="'+ this.idPrefix + this.id +'" visibility="show" top="'+ TW['nn4Top'] +'">';
    } else if (TW['browserType'] > 0) {
      var html = "<div id='"+ this.idPrefix + this.id +"' style='display:block; position:block;'>";
    }
    html += '<table border="0" cellspacing="0" cellpadding="0" background="'+ this.iconpath + TW_ICONS['blank'] +'" width="140">'+
              '<tr>'+
                this.getNodeHTML()+
                //'<td valign="top">'+ this.getIconHTML() +'</td>'+
                '<td valign="middle" '+ nowrap +'>'+ this.getTextHTML() +'</td>'+
            '</table>';
   
    if (TW['browserType'] == 1) html += "</layer>";
    else if (TW['browserType'] > 0) html += "</div>";
    //alert(html)
    return html;
  }
  //
  //  Method: getNodeHTML
  //
  this.getNodeHTML = function () {
    var html = this.getLeftSideHTML(this.leftSide);
    if (this.deep > 0) {
      var nodeTag   = "<img name='nodeIcon"+ this.id + "' id='nodeIcon" + this.id + "' src='"+ this.getNodeIconSrc() +"' width=12 height=22 border=0>";
      if (TW['browserType'] > 0 && this.constructor != Item)
        nodeTag = "<a href='javascript:TW_clickOnNode(\""+ this.id +"\");' onClick='TW_clickOnNode(\""+ this.id +"\");return false;'>"+ nodeTag +"</a>";
      var background = (this.isLastNode) ? '' : "background='"+ this.iconpath + TW_ICONS['verLineBg'] +"'";
      html += "<td valign=top "+ background +" width=12>"+ nodeTag +"</td>";
    }
    return html;
  }
  //
  // Method: getLeftSideHTML
  //
  this.getLeftSideHTML = function () {
    var html = "";
    for (i=0; i<this.leftSide.length; i++) {
      if (this.leftSide.charAt(i) == "1")
        html += "<td valign=top background="+ this.iconpath + TW_ICONS['verLineBg'] +" width=12>"+
                  "<img src='" + this.iconpath + TW_ICONS['verLine'] +"' width=12 height=22></td>";
      else if (this.leftSide.charAt(i) == "0")
        html += "<td valign=top width=12><img src='"+ this.iconpath + TW_ICONS['blank'] +"' width=12 height=22></td>";
    }
    return html;
  }
  //
  // Method: getIconHTML
  //
  this.getIconHTML = function () {
    if (this.useicons) {
      var html = "<img id='"+ this.idPrefix +"Icon"+ this.id +"' name='"+ this.idPrefix +"Icon"+ this.id +"' src='"+ this.getIconSrc() +"' border=0>";
      if (this.href || TW['browserType'] > 0) {
        var a = '<a';
        // a += (this.href) ? " href='"+ this.href +"' target='"+ this.target +"'" : " href='javascript:void(0);'";
        a += ' href="javascript: TW_clickOn('+ this.id +');"';
        if (TW['browserType'] > 0) {
          a += " onClick='TW_clickOn(\""+ this.id +"\");return false;'";
        }
        html = a +'>'+ html +'</a>';
      }
      return html;
    } else return "<img src=" + this.iconpath + TW_ICONS['blank'] +" height=2 width=2>";
  }
  //
  // Method: getTextHTML
  //
  this.getTextHTML = function () {
    var html = this.text;
    if (!this.textonly && (this.href || TW['browserType'] > 0)) {
      var a = '<a id="'+ TW_TEXTIDPFX + this.id +'"';
      a += (this.href) ? " href='"+ this.href +"' target='"+ this.target +"'" : " href='javascript:void(0);'";
      if (TW['browserType'] > 0) {
        a += " onClick='TW_clickOn(\""+ this.id +"\");return false;'";
      }
      html = a +'>'+ html /*+ "||"+ this.id*/ +'</a>';
    } else if (this.textonly) {
      html = '<span class="treeviewText" id="'+ TW_TEXTIDPFX + this.id +'">'+ this.text +'</span>';
    }
    return html;
  }
  //
  // Method: getNodeIconSrc
  //
  this.getNodeIconSrc = function () {
    var src = "";
    if (this.isLastNode) { 
      if (this.children.length == 0) {
        src = 'lastNode';
      } else {
        if (this.opened)
          src = 'minusLastNode';
        else
          src = 'plusLastNode';
      }
    } else { 
      if (this.children.length == 0) {
        src = 'node';
      } else {
        if (this.opened)
          src = 'minusNode';
        else
          src = 'plusNode';
      }
    }   
    return this.iconpath + TW_ICONS[src];
  }
  //
  // Method: getIconSrc
  //            
  this.getIconSrc = function () {
    if (typeof this.opened != 'undefined' && !this.opened)
      return this.iconClosed;
    else if (this.isFolder)
      return this.iconOpened;
    else
      return this.icon;
  }
}

///////////////////////////////
// Class Constructor: Folder //
///////////////////////////////

function Folder(text, href, target) {
  //
  // Inheritance:
  //
  this.base = Item;
  this.base(text, href, target);
  //
  // Public Vars:
  //
  this.iconOpened   = this.iconpath + TW_ICONS['opened'];
  this.iconClosed   = this.iconpath + TW_ICONS['closed'];
  this.idPrefix  = 'folder';
  //
  // Private Vars:
  //
  this.isFolder  = true;
  this.opened = false
  //
  // Method: setOpened
  //
  this.setOpened = function (opened) {
    if (opened == this.opened) 
      return;
    if (TW['browserType'] == 1) {
      var totalHeight = 0;
      for (var i=0; i<this.children.length; i++) 
        totalHeight += this.children[i].object.clip.height;
      var subItemsLength = this.getSubItemsLength();
      if (this.opened) 
        totalHeight = 0-totalHeight;
      if (opened)
        for (var i=this.id + subItemsLength + 1; i<TW['items'].length; i++) 
          TW['items'][i].object.moveBy(0, totalHeight);
     }  
    this.opened = opened;
    // Change node icon
    if (this.children.length > 0 && this.deep > 0)
      this.nodeImg.src = this.getNodeIconSrc();
    // Change icon
    if (this.useicons)
      this.iconImgTag.src = this.getIconSrc();
    // Propagate through children
    for (var i=this.children.length-1; i>=0; i--) 
      if (this.opened) 
        this.children[i].show(this.object);
      else 
        this.children[i].hide();
    if (TW['browserType'] == 1 && !opened) {
      for (var i = this.id + subItemsLength + 1; i < TW['items'].length; i++) 
        TW['items'][i].object.moveBy(0, totalHeight);
    }
  }
  //
  // Method: folder
  // Public
  //
  this.folder = function (text, href, target) {
    return this.addChild (new Folder(text, href, target));
  }
  //
  // Method: link
  // Public
  //             
  this.link = function (text, href, target) {
    return this.addChild (new Item(text, href, target));
  }
  //
  // Method: addChild
  // Public
  //       
  this.addChild = function (childNode) {
   this.children[this.children.length] = childNode;
   childNode.parent = this;
   return childNode;
  }
  //
  // Method: getSubItemsLength
  //
  this.getSubItemsLength = function () { 
    var subItemsLength = this.children.length;
    for (var i = 0; i < this.children.length; i++) 
      if (this.children[i].isFolder)
        subItemsLength += this.children[i].getSubItemsLength();
    return subItemsLength;
  } 
}

/////////////////////////////
// Class Constructor: Tree //
/////////////////////////////

function Tree (text, href, target) {
  //
  // Inheritance:
  //
  this.base = Folder;
  this.base(text, href, target);
  //
  // Public Vars (Globally configurable)
  //
  this.left = TW_LEFT || 0;
  this.top  = TW_TOP  || 0;
  //
  // Private Vars
  //
  // this.ref    = '';
  this.inited = false;
  // 
  // Method: init
  // Public
  //  Purpose:
  //  Sometimes you can experience problems working with nn4 and relative position.
  //  So the best way I found is to write all the code on the window.document
  //  using init() and then use build() between the tags which will be the final
  //  position of the tree.
  // 
  //  eg in a cell table.
  //  Use init() outside the table, then use build() between the TD tags you prefer.
  //
  //  Keep in mind that this method use a function called by the onLoad event.
  //  So if you want to call other functions during this event, please use
  //  my support function addOnLoad() below, otherwise any tree under nn4
  //  will be positioned where you fired init(), that is the window.document.
  //
  this.init = function () {
    if (TW['browserType'] == 1) {
      this.build();
      this.inited = true;
    }
  }
  // 
  // Method: build
  // Public
  //
  this.build = function () {
    // if (TW['browserType'] >= 2 || (TW['browserType'] == 1 && !this.inited)) {
    if (TW['browserType'] >= 2 || (TW['browserType'] == 1 && !this.inited) || TW['browserType'] == 0) {
      // Simply Write the tree code
      // Preload icons:
      var img = new Image();
      for (var i in TW_ICONS) {
        img.src = this.iconpath + TW_ICONS[i];
      }
      this.initItem();
      // Write HTML
      if (TW['browserType'] >= 2)
        document.write('<div id="treeBox'+ this.id +'" style="display:block; position:block; left:'+ this.LEFT +'; top:'+ this.TOP +'">');
      if (this.usedeferral && !TW_STARTALLOPEN && !TW_STARTINGDEEP) {
         // Delay construction of nodes
        this.render();
      } else {
        if (TW['browserType'] == 1) {
          document.write ('<layer name="treeBox'+ this.id +'" left="'+ TW_LEFT +'" top="'+ TW_TOP +'">');
        }
        TW_renderWholeTree(this);
        if (TW['browserType'] == 1) {
          document.write ('</layer>');
          TW['trees'][TW['trees'].length] = this;
          this.object = getElById('treeBox'+ this.id);
          // Force the scrollbar to have enough scollable area
          document.write("<layer top=" + TW['items'][TW['items'].length-1].object.top + ">&nbsp;</layer>");
        }
        if (TW['browserType'] > 0 && !TW_STARTALLOPEN)
          TW_closeStartingClosedFolders(this);
      }
      document.write ('</div>');
    } else if (TW['browserType'] == 1 && this.inited) {
      //  Add a relative layer, which acts as marker,
      //  and move the absolute layer containing the tree code
      //  to its position.
      var treeBox = getElById('treeBox'+this.id);
      document.write('<ilayer name="treeBoxRef'+this.id+'" width="'+ (treeBox.clip.width + TW_LEFT) +'" height="'+ (treeBox.clip.height + TW_TOP) +'" visibility="hide" bgcolor="pink" left="'+ TW_LEFT +'" top="'+ TW_TOP +'"></ilayer>');
      function initTrees() {
        var tree, ref;
        for (var i=0; i<TW['trees'].length; i++) {
          tree = TW['trees'][i];
          ref = getElById('treeBoxRef'+tree.id);
          if (ref)
            tree.object.moveTo(getAbsoluteX(ref), getAbsoluteY(ref));
        }
      }
      addOnLoad(initTrees);
    }
  }
    
}
  
/* ***********
   * EVENTS: *
   *********** */

function TW_clickOn (id) {
  var item = TW_getItemById(id);
  if (typeof item == 'undefined')
    return false;
  if (item.isFolder && !item.opened) {
    item.openParentFolders();
    // Switch open<->close
    item.setOpened(!item.opened);
  }
  TW_highlight(id);
  if (item.onclick && (item.onclick.constructor == Function || (typeof Closure != 'undefined' && item.onclick.constructor == Closure)))
    item.onclick();
  else if (item.href)
    window.open (item.href, item.target);
}
 
function TW_clickOnNode (id) {
  var item = TW_getItemById(id);
  if (typeof item == 'undefined')
    return false;
  item.openParentFolders();
  // Switch open<->close
  item.setOpened(!item.opened);
}

function TW_highlight(id, className) {
  var item = TW_getItemById(id);
  if (!item.highlight || item == null || TW['browserType'] <= 1)
    return false;
  var link = getElById(TW_TEXTIDPFX + id);
  if (typeof className != 'undefined') {
    link.className = className;
  } else {
    if (TW['undoHighlight']) eval(TW['undoHighlight']);
    TW['undoHighlight'] = "TW_highlight('"+ id +"','"+ link.className +"')";
    link.className = item.highlight;
  }
}

//
//  Function: TW_expandAll
//  Purposes:
//  Expands all the sub folders of a given folder.
//
function TW_expandAll(id) {
  var item = TW_getItemById(id);
  if (typeof item == 'undefined' || !item.isFolder)
    return false;
  item.expandAll();
}


// Auxiliary Functions 
// *******************

function TW_getItemById(id) {
  if (typeof TW['items'][id] == 'undefined') {
    alert("Failed to find \""+ id +"\"");
    return;
  }
  if (TW['items'][id].constructor == Number)
    return TW['items'][TW['items'][id]];
  else
    return TW['items'][id];
}

function TW_renderWholeTree(node, parent) {
  if (typeof parent == 'undefined') {parent = null;}
  node.render(parent);
  if (this.usedeferral)
    for (var i=node.children.length-1; i>=0; i--) 
      TW_renderWholeTree(node.children[i], node.object);
  else
    for (var i=0 ; i<node.children.length; i++) 
      TW_renderWholeTree(node.children[i]);
}

function TW_closeStartingClosedFolders (item, delta) {
  // delta: total height of closed folders.
  if (typeof delta == 'undefined')
    delta = 0;
  var height = 0, child;
  for (var i=0 ; i<item.children.length; i++) {
    child = item.children[i];
    if (TW['browserType'] == 1 && delta > 0)
      child.object.moveBy(0, 0-delta);
    if (!TW_STARTINGDEEP || child.deep > TW_STARTINGDEEP)
      child.hide();
    if (child.isFolder)
      delta = TW_closeStartingClosedFolders (child, delta);
    if (TW['browserType'] == 1 && !child.parent.opened)
      height += child.object.clip.height;
  }
  delta += height;
  return delta;
}

/* **********************
   *   CROSS-BROWSER    *
   * SUPPORT FUNCTIONS: *
   ********************** */

//
//  You are free to use the following functions.
//  If you do so, please give credit.
//

//
//  getElById() and nn4_scanLayers(),
//  getAbsoluteX() and getAbsoluteY(),
//  addOnLoad()
//  by Luca Borrione write@tiscali.no-spam.it
//
function getElById(id) {
  curleft = 0;
  curtop  = 0;
  if (document.getElementById)
    return document.getElementById(id);
  else if (document.all)
    return document.all[id];
  else if (document.layers)
    return nn4_scanLayers (id);
}

function nn4_scanLayers (id, obj) {
  var layers = (obj) ? obj.document.layers : document.layers;
  if (layers[id]) return layers[id]; // Added
  var layer, r, i;
  for (i=0; i<layers.length; i++) {
    layer = layers[i];
    if (layer.document.layers[id])
      return (layer.document.layers[id]);
    else if (layer.document.images[id])
      return (layer.document.images[id]);
    else if (layer.document.anchors[id])
      return (layer.document.anchors[id]);
    else if (layer.document.layers.length>0 )
      r = nn4_scanLayers (id, layer);
    curleft += layer.pageX;
    curtop  += layer.pageY;
    if (r)
      return r;
  }
  return r;
}

function getAbsoluteX (obj) {
	if (document.getElementById || document.all) {
		while (obj.offsetParent) {
			curleft += obj.offsetLeft;
			obj = obj.offsetParent;
		}
	} else if (document.layers) {
    if (typeof obj.pageX == 'undefined')
      curleft += obj.x;
    else
      curleft = obj.pageX;
  }
  return curleft;    
}
  
function getAbsoluteY(obj) {
	if (document.getElementById || document.all) {
		while (obj.offsetParent) {
			curtop += obj.offsetTop;
			obj = obj.offsetParent;
		}
	} else if (document.layers) {
    if (typeof obj.pageY == 'undefined')
      curtop += obj.y;
    else
      curtop = obj.pageY;
  }
  return curtop;
}

function addOnLoad (funObj) {
  var prev = (window.onload) ? window.onload.toString() : "";
  prev = prev.substring( prev.indexOf("{")+1, prev.lastIndexOf("}") );
  var curr = funObj.toString();
  curr = curr.substring( curr.indexOf("{")+1, curr.lastIndexOf("}") );
  window.onload = new Function( prev + curr );
} 

/*
  Usage Example
  function test () {
    alert ("Hello world");
  }
  addToFun('TW_clickOnNode', test);
*/
function addToFun (funName, funObj) {
  if (!funName || !funObj) {return false;}
  eval ('var prev = ('+ funName +') ? '+ funName +'.toString() : "";');
  var re = /[^\(]\(([^\)]*)\)[^\{]*\{/;
  var params = prev.match(re);
  var p = "";
  for (var i=1; i<params.length; i++) {
    p += "'"+ params[i] +"'";
    if (p < params.length-1) {p += ",";}
  }
  prev = prev.substring( prev.indexOf("{")+1, prev.lastIndexOf("}") );
  var curr = funObj.toString();
  curr = curr.substring( curr.indexOf("{")+1, curr.lastIndexOf("}") );
  eval (funName +" = new Function ("+ p +", prev + curr);");
}

// insertAdjacentHTML(), insertAdjacentText() and insertAdjacentElement()
// for Netscape 6/Mozilla by Thor Larholm thor@jscript.dk
// Usage: include this code segment at the beginning of your document
// before any other Javascript contents.

if(typeof HTMLElement!="undefined" && !HTMLElement.prototype.insertAdjacentElement){
	HTMLElement.prototype.insertAdjacentElement = function (where, parsedNode) {
		switch (where) {
		case 'beforeBegin':
			this.parentNode.insertBefore(parsedNode, this);
			break;
      
		case 'afterBegin':
			this.insertBefore(parsedNode, this.firstChild);
			break;
      
		case 'beforeEnd':
			this.appendChild(parsedNode);
			break;
      
		case 'afterEnd':
			if (this.nextSibling) this.parentNode.insertBefore(parsedNode, this.nextSibling);
			else this.parentNode.appendChild(parsedNode);
			break;
		}
	}

	HTMLElement.prototype.insertAdjacentHTML = function (where, htmlStr) {
		var r = this.ownerDocument.createRange();
		r.setStartBefore(this);
		var parsedHTML = r.createContextualFragment(htmlStr);
		this.insertAdjacentElement(where, parsedHTML);
	}


	HTMLElement.prototype.insertAdjacentText = function(where, txtStr) {
		var parsedText = document.createTextNode(txtStr);
		this.insertAdjacentElement(where,parsedText);
	}
}