var DIR_IMAGES = "images/";
var IMG_PLUS = DIR_IMAGES + "btnplus.gif";
var IMG_MINUS = DIR_IMAGES + "btnminus.gif";
 
var imgPlus = new Image();
imgPlus.src = IMG_PLUS;
var imgMinus = new Image();
imgMinus.src = IMG_MINUS;
 
var objLocalTree = null;
 
var INDENT_WIDTH = 18;
function jsTree() {
 
    //Public Properties (NCZ, 1/27/02)
    this.root = null;           //the root node of the tree
 
     //Public Collections (NCZ, 1/27/02)
    this.nodes = new Array;     //array for all nodes in the tree
   
    //Constructor
    //assign to local copy of the tree (NCZ, 1/27/02)
    objLocalTree = this;
}
jsTree.prototype.createRoot = function(strText, strURL, strTarget) {
 
    //create a new node (NCZ, 1/27/02)
    this.root = new jsTreeNode(strText, strURL, strTarget);
    
    //assign an ID for internal tracking (NCZ, 1/27/02)
    this.root.id = "root";
    
    //add it into the array of all nodes (NCZ, 1/27/02)
    this.nodes["root"] = this.root;
    
    //make sure that the root is expanded (NCZ, 1/27/02)
    this.root.expanded = true;
    
    //return the created node (NCZ, 1/27/02)
    return this.root;
}
jsTree.prototype.buildDOM = function() {
 
    //call method to add root to document, which will recursively
    //add all other nodes (NCZ, 1/27/02)
    this.root.addToDOM(document.body);
}
jsTree.prototype.toggleExpand = function(strNodeID) {
 
    //get the node (NCZ, 1/27/02)
    var objNode = this.nodes[strNodeID];
    
    //determine whether to expand or collapse
    if (objNode.expanded)
        objNode.collapse();
    else
        objNode.expand();
}
function jsTreeNode(strText, strURL, strTarget) {
 
    //Public Properties (NCZ, 1/27/02)
    this.text = strText;            //the text to display
    this.url = strURL;              //the URL to link to
    this.target = strTarget;        //the target for the URL
    
    //Private Properties (NCZ, 1/27/02)
    this.indent = 0;                //the indent for the node
    
    //Public States (NCZ, 1/27/02)
    this.expanded = false;          //is this node expanded?
 
    //Public Collections (NCZ, 1/27/02)   
    this.childNodes = new Array;    //the collection of child nodes
}
jsTreeNode.prototype.addChild = function (strText, strURL, strTarget) {
 
    //create a new node (NCZ, 1/27/02)
    var objNode = new jsTreeNode(strText, strURL, strTarget);
    
    //assign an ID for internal tracking (NCZ, 1/27/02)
    objNode.id = this.id + "_" + this.childNodes.length;
    
    //assign the indent for this node
    objNode.indent = this.indent + 1;
    
    //add into the array of child nodes (NCZ, 1/27/02)
    this.childNodes[this.childNodes.length] = objNode;
    
    //add it into the array of all nodes (NCZ, 1/27/02)
    objLocalTree.nodes[objNode.id] = objNode;
    
    //return the created node (NCZ, 1/27/02)
    return objNode;
}
jsTreeNode.prototype.addToDOM = function (objDOMParent) {
 
    //create the URL 
    var strHTMLLink = "<a href=\"" + this.url + "\"";
    if (this.target)strHTMLLink += " target=\"" + this.target + "\">";
    
    //create the layer for the node 
    var objNodeDiv = document.createElement("div");
    
    //add it to the DOM parent element 
    objDOMParent.appendChild(objNodeDiv);
    
    //create string buffer 
    var d = new jsDocument;
    
    //begin the table 
    d.writeln("<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><tr>");
    
    //no indent needed for root or level under root 
    if (this.indent > 1) {
        d.write("<td width=\"");
        d.write(this.indent * INDENT_WIDTH);
        d.write("\"> </td>");
    }
    
    //there is no plus/minus image for the root 
    if (this.indent > 0) {
    
        d.write("<td width=\"18\" align=\"center\">");
        
        //if there are children, then add a plus/minus image 
        if (this.childNodes.length > 0) {
            d.write("<a href=\"javascript:objLocalTree.toggleExpand('");
            d.write(this.id);
            d.write("')\"><img src=\"");
            d.write(this.expanded ? imgMinus.src : imgPlus.src);
            d.write("\" border=\"0\" hspace=\"1\" id=\"");
            d.write("imgPM_" + this.id);
            d.write("\" /></a>");
        }
        
        d.write("</td>");
    }
    
    //finish by drawing the icon and text 
    d.write("<td nowrap=\"nowrap\">" + strHTMLLink + this.text + "</a></td>");
    d.writeln("</tr></table>");
        
    //assign the HTML to the layer 
    objNodeDiv.innerHTML = d;
    
    //create the layer for the children 
    var objChildNodesLayer = document.createElement("div");
    objChildNodesLayer.setAttribute("id", "divChildren_" + this.id);
    objChildNodesLayer.style.position = "relative";
    objChildNodesLayer.style.display = (this.expanded ? "block" : "none");
    objNodeDiv.appendChild(objChildNodesLayer);
    
    //call for all children 
    for (var i=0; i < this.childNodes.length; i++)
        this.childNodes[i].addToDOM(objChildNodesLayer);
}
jsTreeNode.prototype.collapse = function () {
 
    //check to see if the node is already collapsed 
    if (!this.expanded) {
    
        //throw an error 
        throw "Node is already collapsed"
 
    } else {
    
        //change the state of the node 
        this.expanded = false;
        
        //change the plus/minus image to be plus 
        document.images["imgPM_" + this.id].src = imgPlus.src;
        
        //hide the child nodes 
        document.getElementById("divChildren_" + this.id).style.display = "none";
    }
}
jsTreeNode.prototype.expand = function () {
 
    //check to see if the node is already expanded 
    if (this.expanded) {
    
        //throw an error 
        throw "Node is already expanded"
    
    } else {
    
        //change the state of the node 
        this.expanded = true;
        
        //change the plus/minus image to be minus 
        document.images["imgPM_" + this.id].src = imgMinus.src;
        
        //show the child nodes 
        document.getElementById("divChildren_" + this.id).style.display = "block";
    }
}
throw new Error("Node is already expanded");