// This utility function traverses Node n, returning the content of
// all Text nodes found and discarding any HTML tags. This is also
// defined as a nested function, so it is private to this module.
function getTextContent(n) 
{
    var s = '';
    var children = n.childNodes;
    for(var i = 0; i < children.length; i++) 
    {
        var child = children[i];
        if (child.nodeType == 3 /*Node.TEXT_NODE*/)
            s += child.data;
        else s += getTextContent(child);
    }
    
    return s;
}

// This method recursively traverses the tree rooted at Node n, looking
// looking for <h1> through <h6> tags, and uses the content of these tags
// to build the table of contents by adding rows to the HTML table specified
// by the toc argument. It uses the sectionNumbers array to keep track of
// the current section number.
// This function is defined inside of maketoc(  ) so that it is not
// visible from the outside. maketoc(  ) is the only function exported
// by this JavaScript module.
function addSections(n, toc, sectionNumbers,minSectionDepth,maxSectionDepth) 
{
    // Loop through all the children of n
    for(var m = n.firstChild; m != null; m = m.nextSibling) 
    {
        // Check whether m is a heading element. It would be nice if we
        // could just use (m instanceof HTMLHeadingElement), but this is
        // not required by the specification and it does not work in IE.
        // Therefore, we must check the tagname to see if it is H1-H6.
        if ((m.nodeType == 1) &&  /* Node.ELEMENT_NODE */ 
            (m.tagName.length == 2) && (m.tagName.charAt(0) == "H")) 
        {
            // Figure out what level heading it is
            var level = parseInt(m.tagName.charAt(1));
            if (!isNaN(level) && (level >= minSectionDepth) && 
                (level <= maxSectionDepth)) 
            {
                // Increment the section number for this heading level
                sectionNumbers[level-1]++;
                // And reset all lower heading-level numbers to zero
                for(var i = level; i < maxSectionDepth; i++) 
                    sectionNumbers[i] = 0;
                // Now combine section numbers for all heading levels
                // to produce a section number like "2.3.1"
                var sectionNumber = "";
                for(var i = minSectionDepth-1; i < level; i++) 
                {
                    sectionNumber += sectionNumbers[i];
                    if (i < level-1) sectionNumber += ".";
                }
                
                // Create an anchor to mark the beginning of this section
                // This will be the target of a link we add to the TOC
                var sectionAnchor = document.createElement("a");
                sectionAnchor.setAttribute("name", "SECT"+sectionNumber);
                
                // Create a link back to the TOC and make it a
                // child of the anchor
                if( level == minSectionDepth )
                {
                    var parag = document.createElement("p");
                    parag.setAttribute("class", "back2toc");
                    var backlink = document.createElement("a");
                    backlink.setAttribute("href", "#TOC");
                    backlink.appendChild(document.createTextNode("top"));
                    parag.appendChild(backlink);
                    var bar = document.createElement("hr");
                    parag.appendChild(bar);
                    sectionAnchor.appendChild(parag);
                } 	
                
                // Insert the anchor into the document right before the
                // section header
                n.insertBefore(sectionAnchor, m);
		
                // Now create a link to this section. It will be added
                // to the TOC below.
                var tmplink = document.createElement("a");
                tmplink.setAttribute("href", "#SECT" + sectionNumber);
                // Get the heading text using a function defined below
                var sectionTitle = getTextContent(m);
                // Use the heading text as the content of the link
                tmplink.appendChild(document.createTextNode(sectionTitle));
                
                // Create a new row for the TOC
                var row = document.createElement("tr");
                // Create two columns for the row
                var col1 = document.createElement("td");
                var col2 = document.createElement("td");
                // Make the first column right-aligned and put the section
                // number in it
                //col1.setAttribute("align", "right");
                col1.appendChild(document.createTextNode(sectionNumber));
                // Put a link to the section in the second column
                col2.appendChild(tmplink);
                // Add the columns to the row, and the row to the table
                row.appendChild(col1);
                row.appendChild(col2);
                toc.appendChild(row);
                
                // Modify the section header element itself to add
                // the section number as part of the section title
                m.insertBefore(document.createTextNode(sectionNumber+"- "),
                               m.firstChild);
            }
        }
        else 
        {  // Otherwise, this is not a heading element, so recurse
            addSections(m, toc, sectionNumbers);
        }
    }
}

/**
 * Create a table of contents for this document, and insert the TOC into
 * the document by replacing the node specified by the replace argument.
 * I just added two numbers to create only the table of contents between 
 * a minimum and maximum of sections, like between h2 and h4
 **/
function maketoc(node2replace,minSectionDepth,maxSectionDepth) 
{
    // Create a <div> element that is the root of the TOC tree
    var toc = document.createElement("div");
    toc.setAttribute("class","toc");
    
    // Set a background color and font for the TOC. We'll learn about
    // the style property in the next chapter.
    // I've commented everything related to the style since it should be handled 
    // by the style-sheet.
    
    //toc.style.backgroundColor = "white";
    //toc.style.fontFamily = "sans-serif";
    
    // Start the TOC with an anchor so we can link back to it
    var tocAnchor = document.createElement("a");  // Create an <a> node
    tocAnchor.setAttribute("name", "TOC");        // Give it a name
    toc.appendChild(tocAnchor);                   // Insert it
 
    // Make the body of the anchor the title of the TOC
    tocAnchor.appendChild(document.createTextNode("Contents"));
 
    // Create a <table> element that will hold the TOC and add it 
    var tocTable = document.createElement("table");
    toc.appendChild(tocTable);
 
    // Create a <tbody> element that holds the rows of the TOC
    var toctbody = document.createElement("tbody");
    tocTable.appendChild(toctbody);
 
    // Just to be sure
    if( minSectionDepth > maxSectionDepth )
    {
	maxSectionDepth = minSectionDepth;
    }
    
    // Initialize an array that keeps track of section numbers
    var sectionNumbers = [0,0,0,0,0,0];

    // Recursively traverse the body of the document, looking for sections
    // sections marked with <h1>, <h2>, ... tags, and use them to create 
    // the TOC by adding rows to the table
    addSections(document.body, toctbody, sectionNumbers, minSectionDepth,maxSectionDepth);
 
    // Finally, insert the TOC into the document by replacing the node
    // specified by the replace argument with the TOC subtree
    node2replace.parentNode.replaceChild(toc, node2replace); 
}

