// Functions for 'mymenu' object

// Adds a new window to this menu
function addWindow(id, x, y, width, height)
{
  argString = "";
  for (arg_i = 0; arg_i < addWindow.arguments.length; arg_i++) {
    if (arg_i > 0)
      argString += ', ';
    if (arg_i == 0 || arg_i == 5 || arg_i == 8 || arg_i == 9)  // Quote these arguments
      argString += '"' + addWindow.arguments[arg_i] + '"';
    else
      argString += addWindow.arguments[arg_i];
  }
  eval('this.windows[this.numWindows] = new myWindow(this, ' + argString + ');');
  return this.windows[this.numWindows++];
}

// Returns a reference to this window
function getWindow(window)
{
   gw_i = this.getWindowByID(window);
   if (gw_i != -1)
     return this.windows[gw_i];
   else
     return null;
}

// Create stylesheet classes for these windows
function createWindows()
{
  document.write("<STYLE>\n<!--\n");
  for (create_i = 0; create_i < this.numWindows; create_i++) {
    win = this.windows[create_i];
    document.write("  #" + win.id + "   { position:absolute; left:" + win.x + "px; top:" + win.y + "px; width:" + win.width + "px; height:" + win.height + "px; background-color:" + win.bgColour + "; layer-background-color:" + win.bgColour + "; z-index:" + win.z_index + "; visibility:" + win.visible + "; font-family:Arial, sans-serif; font-size:12px; line-height:16px; }\n");
  }
  document.write('-->\n</STYLE>');
}

// Mouse down on a window
function startDrag(event, window)
{
  old = this.dragWindow;
  this.dragWindow = window;

  if (this.dragWindow.draggable == 1) {
    if (this.dragWindow != old)
      this.dragWindow.bringToFront(); // Bring to front if not already
    if (NN4) {
      this.mouseOffX = event.pageX - this.dragWindow.x;
      this.mouseOffY = event.pageY - this.dragWindow.y;
    } else {
      this.mouseOffX = event.clientX - this.dragWindow.x;
      this.mouseOffY = event.clientY - this.dragWindow.y;
    }
    if (inRect(3, 3, 15, 15, this.mouseOffX, this.mouseOffY)) { // Close window
      this.dragWindow.closeWin(1);
      this.dragWindow = null;
    } else
      if (this.dragWindow.numScrollbars) { // Check if on scrollbar
        result = 0;
        for (sbc_i = 0; sbc_i < this.dragWindow.numScrollbars; sbc_i++) {
          if (this.dragWindow.scrollbar[sbc_i].scrollWindow) {   // Only proceed if a pane attached to this scrollbar
            result = this.dragWindow.scrollbar[sbc_i].onScrollBar(this.mouseOffX, this.mouseOffY);
            if (result == 1) {
              this.dragWindow.currentScrollbar = sbc_i;
              this.scrolling = 1;
              this.dragWindow.scrollbar[sbc_i].scrollUp();
              this.dragWindow = null;
            } else
              if (result == 2) {
                this.dragWindow.currentScrollbar = sbc_i;
                this.scrolling = 1;
                this.dragWindow.scrollbar[sbc_i].scrollDown();
                this.dragWindow = null;
              }
          }
          if (result)
            break;
        }
        if (result)
          return false;
      }
  } else
    this.dragWindow = null;
  return true;
}

// Mouse released on a window
function endDrag()
{
  this.scrolling = 0;
  this.dragWindow = null;
  return true;
}

// Mouse moving in a window
function dragW(event)
{
  if (this.dragWindow) {
    if (NN4) {
      if (this.dragWindow.dragHorz)
        this.dragWindow.moveTo(event.pageX - this.mouseOffX, event.pageY - this.mouseOffY);
      else
        this.dragWindow.moveTo(this.dragWindow.x, event.pageY - this.mouseOffY);
    } else {
      if (this.dragWindow.dragHorz)
        this.dragWindow.moveTo(event.clientX - this.mouseOffX, event.clientY - this.mouseOffY);
      else
        this.dragWindow.moveTo(this.dragWindow.x, event.clientY - this.mouseOffY);
    }
    return false;
  }
  return true;
}

// Gets the index of a window by its ID
function getWindowByID(name, stack)
{
  var num;
  
  if (stack)
    num = this.visibleWindows;
  else
    num = this.numWindows;
  for (id_i = 0; id_i < num; id_i++) {
    if (stack) {
      //alert(num + " " + this.windowsStack[id_i].id);
      if (this.windowsStack[id_i].id == name)
        return(id_i)
    } else
      if (this.windows[id_i].id == name)
        return(id_i)
  }
  return -1;
}

function frontOfStack(name)
{
  var temp;
  
  stackOrder = this.getWindowByID(name, 1);
  if (stackOrder == -1) {   // Not yet there
    this.windowsStack[this.visibleWindows++] = this.getWindow(name);
    //alert(this.getWindow(name).id);
  } else {
    temp = this.windowsStack[stackOrder];
    for (fos_i = stackOrder; fos_i < (this.visibleWindows - 1); fos_i++)
      this.windowsStack[fos_i] = this.windowsStack[fos_i + 1]; 
    this.windowsStack[this.visibleWindows - 1] = temp;
  }
  //alert("Order: " + stackOrder + " Windows: " + this.visibleWindows + " Name: " + name);
}

function removeFromStack(name)
{
  stackOrder = this.getWindowByID(name, 1);
  if (stackOrder != -1) {   // Doesn't exist
    for (rfs_i = stackOrder; rfs_i < (this.visibleWindows - 1); rfs_i++)
      this.windowsStack[rfs_i] = this.windowsStack[rfs_i + 1]; 
    this.windowsStack[this.visibleWindows--] = null;
  }
}

function mouseDown(e)
{  
  mouseX = (NN4) ? e.pageX : e.clientX;
  mouseY = (NN4) ? e.pageY : e.clientY;

  for (md_i = this.visibleWindows - 1; md_i >=0; md_i--)
    if (inRect(this.windowsStack[md_i].x, this.windowsStack[md_i].y, this.windowsStack[md_i].width, this.windowsStack[md_i].height, mouseX, mouseY))
      return this.startDrag(e, this.getWindow(this.windowsStack[md_i].id));
    
  return true;
}

function mouseUp(e)
{  
  return this.endDrag();
}

function mouseMove(e)
{ 
  if (this.dragWindow) 
    return this.dragW(e);
  else {  // Check if we are near a magnetic window
    if (NN4) {
      x = e.pageX;
  	  y = e.pageY;
    } else {
      x = e.clientX;
  	  y = e.clientY;
    }
    for (m_i = 0; m_i < this.numWindows; m_i++)
      if (this.windows[m_i].magnetic) {
        winToCheck = this.windows[m_i];
        distance = Math.sqrt((x - (winToCheck.orig_x + winToCheck.width / 2)) * (x - (winToCheck.orig_x + winToCheck.width / 2)) + (y - (winToCheck.orig_y + winToCheck.height / 2)) * (y - (winToCheck.orig_y + winToCheck.height / 2)));
        if (distance > 100) {
          if (winToCheck.orig_x < winToCheck.dest_x) {
            if (winToCheck.x > winToCheck.orig_x) {
              winToCheck.velocity = -1;
              winToCheck.magneticMoveFlag = 1;
            }
          } else
            if (winToCheck.x < winToCheck.orig_x) {
              winToCheck.velocity = 1;
              winToCheck.magneticMoveFlag = 1;
            }
        } else
          if (winToCheck.orig_x < winToCheck.dest_x) {
            if (winToCheck.x < winToCheck.dest_x) {
              winToCheck.velocity = 1;
              winToCheck.magneticMoveFlag = 1;
            }
          } else
            if (winToCheck.x > winToCheck.dest_x) {
              winToCheck.velocity = -1;
              winToCheck.magneticMoveFlag = 1;
            }
        if (winToCheck.magneticMoveFlag)
          winToCheck.moveMagneticLayer();
      }
  }
  return true;
}

function doWatermark()
{
  newPageXoffset = (NN4) ? parent.window.pageXOffset : document.body.scrollLeft;
  newPageYoffset = (NN4) ? parent.window.pageYOffset : document.body.scrollTop;
  if (newPageXoffset != this.prevPageXoffset || newPageYoffset != this.prevPageYoffset) {
    for (w_i = 0; w_i < this.numWindows; w_i++) {
      if (this.windows[w_i].watermark) {
        offsetX = this.prevPageXoffset - newPageXoffset;
        offsetY = this.prevPageYoffset - newPageYoffset;
        this.windows[w_i].x -= offsetX;
        this.windows[w_i].y -= offsetY;
        this.windows[w_i].orig_x -= offsetX;
        this.windows[w_i].orig_y -= offsetY;
        if (this.windows[w_i].dest_x)
          this.windows[w_i].dest_x -= offsetX;
        this.windows[w_i].moveTo(this.windows[w_i].x, this.windows[w_i].y);
      }
    }
    this.prevPageXoffset = newPageXoffset;
    this.prevPageYoffset = newPageYoffset;
  }
  checkScroll = this;
  setTimeout("eval('checkScroll.doWatermark();')", 20);
}

// Constructor function for menu
function mymenu(front)
{
  // Properties
  this.numWindows = 0;
  this.visibleWindows = 0;
  this.dragWindow = null;
  this.old = null;
  this.mouseOffX = 0;
  this.mouseOffY = 0;
  this.front = front;
  this.windows = new Array();
  this.windowsStack = new Array();
  this.scrolling = 0;
  this.prevPageXoffset = 0;
  this.prevPageYoffset = 0;
  // Methods
  this.addWindow = addWindow;
  this.getWindow = getWindow;
  this.createWindows = createWindows;
  this.startDrag = startDrag;
  this.endDrag = endDrag;
  this.dragW = dragW;
  this.getWindowByID = getWindowByID;
  this.frontOfStack = frontOfStack;
  this.removeFromStack = removeFromStack;
  this.mouseDown = mouseDown;
  this.mouseUp = mouseUp;
  this.mouseMove = mouseMove;
  this.doWatermark = doWatermark;  
}

// **********************************
// Functions for 'window' class

// Adds a scroll bar object to window
function addScrollBar(id, x, y, width, height, step)
{
  this.scrollbar[this.numScrollbars] = new scrollbar(this.ifaceObj, this, id, x, y, width, height, step);
  return this.scrollbar[this.numScrollbars++];
}

function addContentPane(pane)
{
  this.contentPanes[this.numPanes++] = pane;
  pane.parent = this;
  pane.grandparent = this.parent;
  return pane;
}

// Displays a specified pane within a window
function showPane(noanim)
{
  if (this.parent.visiblePane)
    this.parent.visiblePane.hidePane();
  this.parent.visiblePane = this;
  return this.showScrollPane(noanim);
} 

// Hides a pane within a window if any visible
function hidePane()
{
  this.parent.visiblePane = null;
  return this.hideScrollPane();  
}

// Displays a specified pane within a window
function showScrollPane(noanim)
{
  if (!noanim) {
    anim = 1;
    this.delay = 50;
  } else
    anim = 0;
  this.openWin(anim);
  return false;
} 

// Hides a pane within a window if any visible
function hideScrollPane()
{
  return this.closeWin();  
}

// Gets a pane object by its ID
function getPaneByID(name)
{
  for (pid_i = 0; pid_i < this.numPanes; pid_i++) {
    if (this.contentPanes[pid_i].id == name)
      return(this.contentPanes[pid_i]);
  }
  return null;
}

// Show this window
function openWin(anim)
{ 
  //loader.getLayerObj().visibility = "hidden"; // Just in case
  if (!loaded)
    return 0;
  if (!this.alreadyLoaded) {
    globalWindowToOpen = this;
    if (NN4)
      this.getLayerObj().load(this.externalFile + ".htm", this.width);
    else
      bufferFrame.document.location = this.externalFile + "_ie.htm";
    // Display Loading animation
    //loader.getLayerObj().visibility = "visible";
    return 0;
  } else {
      // Any window initialisation goes here
      if (this.id == "profWindL")
        profileTextSB.setScrollWindow(introPPane, 1);
      if (this.id == "servWindL")
        servicesTextSB.setScrollWindow(introSPane, 1);
      if (this.id == "thoughtsWindowL")
        thoughtTextSB.setScrollWindow(introTPane, 1);
      if (this.id == "WindowL") {
        mediaMenuSB.setScrollWindow(menuPane, 1);
        //introPane.showPane(1);
      }
      if (this.id == "clientWindowL")
        clientListSB.setScrollWindow(clientListWindow, 1);
    }
  this.moveTo(this.orig_x, this.orig_y);
  if (anim) {
    this.wipeFinished = 0;
    this.clipWidth = 0;
    this.clipHeight = this.viewHeight;
    this.clipX = Math.round(this.viewWidth / 2);
    this.clipY = 0;
    this.animObj = new animobject(this.id, this, 10); 
  } else {
    this.clipWidth = this.viewWidth;
    this.clipHeight = this.viewHeight;
    this.clipX = 0;
    this.clipY = 0;
  }
  this.bringToFront();
  this.setClip();
  this.getLayerObj().visibility = "visible";

  if (anim)
    this.animObj.revealHorz();
  return false;
}

// Close this window
function closeWin(anim)
{ 
  if (this.parent == null)
    this.ifaceObj.removeFromStack(this.id);
  if (anim) {
    this.wipeFinished = 0;
    this.delay = 10;
    this.animObj = new animobject(this.id, this, 10);
    this.animObj.hideVert();
  } else {  
    if (this.visiblePane)
      this.visiblePane.hidePane();
    this.getLayerObj().visibility = "hidden";
  }
  return false;
}

function bringToFront()
{
  this.ifaceObj.front++;
  this.getLayerObj().zIndex = this.ifaceObj.front;
  if (this.parent == null)
    this.ifaceObj.frontOfStack(this.id);
}

// Move window to absolute position
function moveTo(x, y)
{
  this.x = x;
  this.y = y;
  if (NN4)
    this.getLayerObj().moveTo(x, y);
  else {
    this.getLayerObj().pixelLeft = x;
    this.getLayerObj().pixelTop = y;
  }
}

// Move window up
function moveUp(dy)
{
  this.y -= dy;
  if (NN4)
    this.getLayerObj().moveBy(0, -dy);
  else
    this.getLayerObj().pixelTop = this.y;
}

// Move window down
function moveDown(dy)
{
  this.y += dy;
  if (NN4)
    this.getLayerObj().moveBy(0, dy);
  else
    this.getLayerObj().pixelTop = this.y;
}

// Move window left
function moveLeft(dx)
{
  this.x -= dx;
  if (NN4)
    this.getLayerObj().moveBy(-dx, 0);
  else
    this.getLayerObj().pixelLeft = this.x;
}

// Move window right
function moveRight(dx)
{
  this.x += dx;
  if (NN4)
    this.getLayerObj().moveBy(dx, 0);
  else
    this.getLayerObj().pixelLeft = this.x;
}

// Change clipping of window
function setClip()
{
  if (NN4) {
    scrollWin = this.getLayerObj()
    scrollWin.clip.left = this.clipX;
    scrollWin.clip.right = this.clipX + this.clipWidth;
    scrollWin.clip.top = this.clipY;
    scrollWin.clip.bottom = this.clipY + this.clipHeight;
  } else
    this.getLayerObj().clip = 'rect(' + this.clipY + 'px, ' + (this.clipX + this.clipWidth) + 'px, ' + (this.clipY + this.clipHeight)+ 'px, ' + this.clipX + 'px)';
}

function getLayerObj()
{
  if (NN4) {
    if (this.grandparent)
      eval('retVal = document.layers["' + this.grandparent.id + '"].document.layers["' + this.parent.id + '"].document.layers["' + this.id + '"];');
    else
      if (this.parent)
        eval('retVal = document.layers["' + this.parent.id + '"].document.layers["' + this.id + '"];');
      else
        eval('retVal = document.layers["' + this.id + '"];');
  } else
    eval('retVal = document.all.' + this.id + '.style;');
  return retVal;
}

function moveMagneticLayer()
{
  start_x = (this.orig_x < this.dest_x) ? this.orig_x : this.dest_x;
  end_x = (this.orig_x < this.dest_x) ? this.dest_x : this.orig_x;
  if (this.magneticMoveFlag) {
    this.x += this.velocity;
    if (this.velocity < 0 && this.x <= start_x) { 
      this.magneticMoveFlag = 0;
      this.x = start_x;
    }
    
    if (this.velocity > 0 && this.x >= end_x) { 
      this.magneticMoveFlag = 0;
      this.x = end_x;
    }  
    this.moveTo(this.x, this.y);
  //alert(this.x + " " + this.y);
  }
  
  if (this.magneticMoveFlag) {
    eval("magMove" + this.id + " = this;");
    setTimeout("eval('magMove" + this.id + ".moveMagneticLayer();')", 10);
  }
}	

// Constructor function for window
function myWindow(iface, id, x, y, width, height, externalFile, draggable, dragHorz, visible, bgColour, z_index)
{
  // Properties
  this.id = id;
  this.x = x;
  this.y = y;
  this.orig_x = x;
  this.orig_y = y;
  this.width = width;
  this.height = height;
  this.numScrollbars = 0;
  this.currentScrollbar = -1;
  this.scrollbar = new Array();
  this.ifaceObj = iface;
  this.delay = 10;
  this.numPanes = 0;
  this.contentPanes = new Array();
  this.visiblePane = null;
  this.parent = null;
  this.grandparent = null;
  this.draggable = (draggable) ? draggable : 0;
  this.dragHorz = (dragHorz) ? dragHorz : 0;
  this.bgColour = (bgColour) ? bgColour : "transparent";
  this.z_index  = (z_index) ? z_index : 0;
  this.visible  = (visible) ? visible : "hidden";
  this.clipX = 0;
  this.clipY = 0;
  this.clipWidth = width;
  this.clipHeight = height;
  this.wipeFinished = 0;
  this.menuSlide = 0;
  this.animObj = null;
  this.watermark = false;
  this.magnetic = false;
  this.dest_x = this.x;
  this.velocity = 0;
  this.magneticMoveFlag = false;
  
  this.externalFile = externalFile;
  this.alreadyLoaded = (externalFile == "none") ? 1 : 0;
  
  this.viewX = 0;
  this.viewY = 0;
  this.viewWidth = width;
  this.viewHeight = height;
  // Methods
  this.addScrollBar = addScrollBar;
  this.addContentPane = addContentPane;
  this.showPane = showPane;
  this.hidePane = hidePane;
  this.showScrollPane = showScrollPane;
  this.hideScrollPane = hideScrollPane;
  this.getPaneByID = getPaneByID;
  this.closeWin = closeWin;
  this.openWin = openWin;
  this.bringToFront = bringToFront;
  this.moveTo = moveTo;
  this.moveUp = moveUp;
  this.moveDown = moveDown;
  this.moveLeft = moveLeft;
  this.moveRight = moveRight;
  this.setClip = setClip;
  this.getLayerObj = getLayerObj;
  this.moveMagneticLayer = moveMagneticLayer;
}

// **********************************
// Functions for 'scrollbar' class

// Return a value if pointer of scrollbar arrow
// 0 - not over arrow, 1 - over up arrow, 2 over down arrow
function onScrollBar(x, y)
{
  if (inRect(this.x, this.y, 16, 20, x, y))
    return 1;
  if (inRect(this.x, this.y + this.height - 16, 16, 20, x, y))
    return 2;
  return 0;
}

// Sets/changes window to be controlled by this scrollbar
function setScrollWindow(window, noanim)
{
  if (!noanim)
    noanim = 0;
  if (this.scrollWindow)
    this.scrollWindow.hideScrollPane();  // Hide existing pane
  this.scrollWindow = window;
  window.clipX = this.viewX;
  window.clipY = this.viewY;
  window.clipWidth = this.viewWidth;
  window.clipHeight = this.viewHeight;
  window.viewX = this.viewX;
  window.viewY = this.viewY;
  window.viewWidth = this.viewWidth;
  window.viewHeight = this.viewHeight;
  window.showScrollPane(noanim);
  return false;
}

function setViewPort(vx, vy, vw, vh)
{
  this.viewX = vx;
  this.viewY = vy;
  this.viewWidth = vw;
  this.viewHeight = vh;
}

// Scroll area down
function scrollDown()
{
  if (this.scrollWindow.height > (this.scrollWindow.clipY + this.scrollWindow.clipHeight) && this.ifaceObj.scrolling) {
    this.scrollWindow.clipY += this.step;
    this.scrollWindow.setClip();
    this.scrollWindow.moveUp(this.step);
    temp = this.parent;
    setTimeout("eval('temp.scrollbar[temp.currentScrollbar].scrollDown();')", 20);
  }
}

// Scroll area up
function scrollUp()
{
  if (this.scrollWindow.clipY > 0 && this.ifaceObj.scrolling) {
    this.scrollWindow.clipY -= this.step;
    this.scrollWindow.setClip();
    this.scrollWindow.moveDown(this.step);
    temp = this.parent;
    setTimeout("eval('temp.scrollbar[temp.currentScrollbar].scrollUp();')", 20);
  }
}

// Constructor function for scrollbar
function scrollbar(iface, parent, id, x, y, width, height, step)
{
  // Properties
  this.id = id;
  this.x = x;
  this.y = y;

  this.width = width;
  this.height = height;
  this.step = step;
  this.scrollWindow = null;
  this.parent = parent;
  this.ifaceObj = iface;
  
  this.viewX = 0;
  this.viewY = 0;
  this.viewWidth = 0;
  this.viewHeight = 0;
  // Methods
  this.onScrollBar = onScrollBar;
  this.setScrollWindow = setScrollWindow;
  this.scrollUp = scrollUp;
  this.scrollDown = scrollDown;
  this.setViewPort = setViewPort;
}

// **********************************
// Functions for tree view

// Adds a new node to the tree
function addNode(id, layerObj, lines, openState, leaf)
{
  argString = "";
  for (arg_i = 2; arg_i < addNode.arguments.length; arg_i++) {
    argString += ', ';
    argString += addNode.arguments[arg_i];
  }
  eval('this.nodes[this.numNodes] = new treenode(id, layerObj' + argString + ');');
  layerObj.height = this.nodes[this.numNodes].lines * this.lineHeight;
  layerObj.moveheight = this.nodes[this.numNodes].lines * this.subHeight;
  layerObj.viewHeight = this.nodes[this.numNodes].lines * this.lineHeight;
  if (this.numNodes == 0) {   // If this is first node, set x,y coordinates of tree
    this.x = layerObj.x;
    this.y = layerObj.y;
    this.treeHeight += layerObj.height;
  } else {
    if (this.nodes[this.numNodes - 1].leaf && this.nodes[this.numNodes - 1].openState)
      layerObj.y = this.nodes[this.numNodes - 1].layerObj.y + this.nodes[this.numNodes - 1].layerObj.height;
    if (this.nodes[this.numNodes - 1].leaf && !this.nodes[this.numNodes - 1].openState)      
      layerObj.y = this.nodes[this.numNodes - 1].layerObj.y;
    if (!this.nodes[this.numNodes - 1].leaf)
      layerObj.y = this.nodes[this.numNodes - 1].layerObj.y + this.nodes[this.numNodes - 1].layerObj.height;  
    if (!this.nodes[this.numNodes].leaf)
      this.treeHeight += layerObj.height;
    else
      if (this.nodes[this.numNodes].openState)        
        this.treeHeight += layerObj.height;
  }
  layerObj.orig_x = layerObj.x;
  layerObj.orig_y = layerObj.y;
  this.numNodes++;
  this.parentPane.height = this.treeHeight + 5;
}

// Toggle open/close state of a node
function togNode(node)
{
  if ((globalObj && !globalObj.finished) || globalMenuCount != 0)
    return false;

  nodeToTog = this.getNodeByID(node);
  amountToMove = this.nodes[nodeToTog].layerObj.moveheight;
  if (this.nodes[nodeToTog].openState)
    this.closeNode(nodeToTog, amountToMove);
  else
    this.openNode(nodeToTog, amountToMove);
  this.nodes[nodeToTog].openState = 1 - this.nodes[nodeToTog].openState;  
  return false    
}

// Open a node of the tree
function openNode(nodeToOpen, amountToMove)
{ 
  var count = 0;
  globalObj = new animobject(this.nodes[nodeToOpen].layerObj.id, this.nodes[nodeToOpen].layerObj, 1, 'true;');
  globalObj.amountToMove = globalObj.windowObj.width;
  globalObj.windowObj.x -= globalObj.windowObj.width;
  globalObj.windowObj.clipX = globalObj.windowObj.width;
  globalObj.windowObj.clipWidth = 0;
  globalObj.windowObj.moveTo(globalObj.windowObj.x, globalObj.windowObj.y);
  this.treeHeight += globalObj.windowObj.height + 1;
  this.parentPane.height = this.treeHeight;
  //alert(this.treeHeight);
  for (o_i = this.numNodes - 1; o_i > nodeToOpen; o_i--) {
    globalMenuCount++;
    this.nodes[o_i].layerObj.animObj = new animobject(this.nodes[o_i].layerObj.id, this.nodes[o_i].layerObj, 1, 'globalObj.windowObj.getLayerObj().visibility = "visible";globalObj.clip_n_slideRight();', amountToMove);
    this.nodes[o_i].layerObj.animObj.slideDown();
  }
  if ((this.numNodes - 1) == nodeToOpen) {
    globalObj.windowObj.getLayerObj().visibility = "visible";
    globalObj.clip_n_slideRight();
  }
}

// Close a node of the tree
function closeNode(nodeToClose, amountToMove)
{
  globalObj = new animobject(this.nodes[nodeToClose].layerObj.id, this.nodes[nodeToClose].layerObj, 1, 'globalObj.windowObj.getLayerObj().visibility = "hidden";');
  globalObj.amountToMove = globalObj.windowObj.width;
  globalObj.clip_n_slideLeft();
  this.treeHeight -= globalObj.windowObj.height + 1;
  this.parentPane.height = this.treeHeight;
  //alert(this.treeHeight);
  for (c_i = nodeToClose + 1; c_i < this.numNodes; c_i++) {
    globalMenuCount++;
    this.nodes[c_i].layerObj.animObj = new animobject(this.nodes[c_i].layerObj.id, this.nodes[c_i].layerObj, 1, 'true;', amountToMove);
    this.nodes[c_i].layerObj.animObj.slideUp();
  }
}

// Gets the index of a node by its ID
function getNodeByID(node)
{
  for (id_i = 0; id_i < this.numNodes; id_i++)
    if (this.nodes[id_i].id == node)
      return(id_i)
  return -1;
}

// Constructor function for treeview
function treeview(id, parentPane, lineHeight)
{
  // Properties
  this.parentPane = parentPane;
  this.id = id;
  this.x = 0;
  this.y = 0;
  this.lineHeight = 18;
  this.subHeight = 15;
  this.numNodes = 0;
  this.treeHeight = 0;
  this.nodes = new Array();
  // Methods
  this.addNode = addNode;
  //this.removeNode = removeNode;
  this.togNode = togNode;
  this.openNode = openNode;
  this.closeNode = closeNode;
  this.getNodeByID = getNodeByID;
}

// **********************************
// Functions for tree view node items
// Constructor function for tree view node items
function treenode(id, layerObj, lines, openState, leaf)
{
  // Properties
  this.id = id;
  this.openState = openState;
  this.prevState = 0;
  this.leaf = leaf;
  this.lines = lines;
  this.layerObj = layerObj;
  // Methods

}

// **********************************
// Functions for animated items

function revealHorz()
{
  if (this.windowObj.clipX > 0) {
    this.windowObj.clipX -= 20;
    this.windowObj.clipWidth += 40;
  } else {
    this.windowObj.clipX = 0;
    this.windowObj.clipWidth = this.windowObj.width;
    //this.wipeFinished += 1;
  }
  this.windowObj.setClip();
  eval('temp' + this.id + 'a = this;');
  if (this.windowObj.clipWidth != this.windowObj.width)
    setTimeout("eval('temp" + this.id + "a.revealHorz();')", this.delay);
  else
    this.windowObj.bringToFront();
}

function hideVert()
{
  if (this.windowObj.clipY < this.windowObj.height / 2) {
    this.windowObj.clipY += 20;
    this.windowObj.clipHeight -= 40;
  } else 
    this.finished += 1;

  this.windowObj.setClip();
  eval('temp' + this.id + 'a = this;');
  if (this.finished < 1)
    setTimeout("eval('temp" + this.id + "a.hideVert();')", this.delay); 
  else {
    if (this.windowObj.visiblePane)
      this.windowObj.visiblePane.hidePane();
    this.windowObj.getLayerObj.visibility = "hidden";
  }
}

// Slide window down
function slideDown()
{ 
  this.windowObj.moveDown(3);
  this.amountToMove -= 3
  eval('temp' + this.id + 's = this;');
  if (this.amountToMove > 0) {
    setTimeout("eval('temp" + this.id + "s.slideDown();')", this.delay);
  } else {
    globalMenuCount--;
    if (globalMenuCount == 0) {
      eval(this.callBack);
    }
  }
}

// Slide window up
function slideUp()
{ 
  this.windowObj.moveUp(3);
  this.amountToMove -= 3;
  eval('temp' + this.id + 's = this;');
  if (this.amountToMove > 0) {
    setTimeout("eval('temp" + this.id + "s.slideUp();')", this.delay);
  } else {
    globalMenuCount--;
  }
}

// Reveal window right within a clipping layer
function clip_n_slideRight()
{ 
  this.windowObj.moveRight(4);
  this.windowObj.clipX -= 4;
  this.windowObj.clipWidth += 4;
  //this.windowObj.setClip();
  this.amountToMove -= 4;
  eval('temp' + this.id + 's = this;');
  if (this.amountToMove > 0)
    setTimeout("eval('temp" + this.id + "s.clip_n_slideRight();')", this.delay);
  else
    this.finished = 1;
}

// Hide window left within a clipping layer
function clip_n_slideLeft()
{ 
  this.windowObj.moveLeft(4);
  this.windowObj.clipX += 4;
  this.windowObj.clipWidth -= 8;
  //this.windowObj.setClip();
  this.amountToMove -= 4;
  eval('temp' + this.id + 's = this;');
  if (this.amountToMove > 0)
    setTimeout("eval('temp" + this.id + "s.clip_n_slideLeft();')", this.delay);
  else {
    this.windowObj.clipX = this.clipX;
    this.windowObj.clipWidth = this.clipWidth;
    this.windowObj.x = this.x;
    this.finished = 1;
  }  
}

// Constructor function for animated items
function animobject(id, windowObj, delay, callBack, amountToMove)
{
  // Properties
  this.id = id;
  this.windowObj = windowObj;
  this.callBack = (callBack) ? callBack : "";
  this.x = windowObj.x;
  this.y = windowObj.y;
  this.width = windowObj.width;
  this.height = windowObj.height;
  this.clipX = windowObj.clipX;
  this.clipY = windowObj.clipY;
  this.clipWidth = windowObj.clipWidth;
  this.clipHeight = windowObj.clipHeight;
  this.delay = delay;
  this.finished = 0; 
  this.amountToMove = (amountToMove) ? amountToMove : 0;
  // Methods
  this.revealHorz = revealHorz;
  this.hideVert = hideVert;
  this.slideDown = slideDown;
  this.slideUp = slideUp;
  this.clip_n_slideRight = clip_n_slideRight;
  this.clip_n_slideLeft = clip_n_slideLeft;
}

// *********************************
// General functions

function inRect(tx, ty, w, h, x, y)
{
  if (x >= tx && x <= (tx + w)  && y >= ty && y <= (ty + h))
    return true;
  else
    return false;
}

function loadSourceFinish(id) 
{
  document.all[id].innerHTML = bufferFrame.document.body.innerHTML;
  if (id == "WindowL")
    mediaMenuSB.setScrollWindow(menuPane, 1);
  if (id == "clientWindowL")
    clientListSB.setScrollWindow(clientListWindow, 1);
  showGlobalOpeningWin();
}

function showGlobalOpeningWin() 
{
  if (globalWindowToOpen) {
    globalWindowToOpen.alreadyLoaded = 1;
    globalWindowToOpen.openWin(1);
  }
  // Hide Loading animation
  //loader.getLayerObj().visibility = "hidden";
}