//********************************************************************
// autotoc.js
// 
// Automatically populate a Table of Contents in #nav with headings
// from #main.
//
// Dependencies:
// 
//      http://www.avtokrator.org/cwynne/js/onload.js
//      http://www.avtokrator.org/cwynne/js/domfunc.js
//
//   Author:    Colin J. Wynne <cwynne(at)avtokrator(dot)org>
//   Created:   2006-08-16
//   Version:   (see RCS string below)
//
//********************************************************************
// $Id: autotoc.js,v 1.8 2008/04/13 22:37:29 cwynne Exp $
//********************************************************************

  // Package variables.
var navID    = "nav";           // @id of navbar being built.
var mainID   = "main";          // @id of section containing content.
var tocLink  = "toclink";       // @id for created anchors and links.
var tocClass = "toc";           // Base name for @class of created
                                //   navbar elements; appended with
                                //   '-Hn' for corresponding <Hn>
                                //   element.

  // Autocreate the ToC.  Pull headers from @id main to populate
  // @id nav.
function populateToC(nav, main) {

    if(!nav)  nav  =  navID;
    if(!main) main = mainID;

        // Get the important DIVs from the document.
    var navbar  = document.getElementById( nav);
    var content = document.getElementById(main);

        // Make sure they exist.
    if( !navbar) return;
    if(!content) return;

        // Get headings in content and create a UL for #nav.
    var headings = getElementsByTagMatch(content, /\bH[1-9]\b/i);
    var list     = document.createElement('ul');

        // Look at those headings.
    for(var i=0; i < headings.length; ++i) {

            // Each ToC entry will be a LI with an A inside.
        var item  = document.createElement('li');
        var link  = document.createElement( 'a');

            // The ToC entry content will be a cleaned cersion of the
            // corresponding H* node.
        var cntnt = deepCleanNode( headings[i] );


            // A gets the content, as well as a class that lets us style
            // by different levels and an HREF to the heading tag.
        link.innerHTML = cntnt.innerHTML;
        link.href      = "#" + tocLink  + "-" + i;
        link.className =       tocClass + "-" + headings[i].nodeName;

            // Pack the link and the list item into the UL.
        item.appendChild(link);
        list.appendChild(item);

            // Make sure the H* gets an anchor of the same name as the
            // link HREF above.
        var anchor = document.createElement('a');

        anchor.id  = tocLink + "-" + i;

            // Put that anchor right inside its heading.  We do this
            // to make sure not to break :first-child styles.
        headings[i].insertBefore(anchor, headings[i].childNodes[0]);
    }

        // Attach the UL to the #nav element.
    navbar.appendChild(list);
}

  // Returns a duplicate of the passed node with all unique attributes
  // (@name or @id) stripped out.
function deepCleanNode(node) {

      // Functions may expect a node returned, so make sure we give
      // one.
    var empty = document.createTextNode("");

      // Make sure we get a proper DOM object here.
    if(! node.nodeType ) return empty;

      // 1 = Node.ELEMENT_NODE
      // 3 = Node.TEXT_NODE
      //
      // IE seems to recognize the constants, the loust piece of crap.
    if(  node.nodeType !=  1 && node.nodeType != 3 )
        return empty;

      // We have an ELEMENT or a TEXT NODE.  Now create a copy to work
      // with.
    var copy = node.cloneNode(true);

      // Main loop will need to be redone every time a descendant
      // element changes, so we will make it (effectively) infinite
      // with explicit loop control.
  TestUnique:
    for(var k = 0; k < 1000; ++k) {

          // Get the copies descendants.
        var elem = copy.getElementsByTagName("*");

        for(var j = 0; j < elem.length; ++j) {

            var chld = elem[j];

              // Test for unique attributes.
            if(chld.id || chld.name) {

                  // The cleaned version will keep the markup but
                  // strip the element entirely.
                var clean = document.createTextNode( chld.innerHTML );

                  // Replace the node and restart the loop.
                chld.parentNode.replaceChild(clean,chld);
                continue TestUnique;
            }
        }

          // We made a clean pass through with no replacements, so we
          // are done.
        break;
    }

    return copy;
}

function replaceUnique(node) {



}

    // Use onload.js script to add onload event.
addOnLoad( populateToC );

//********************************************************************
// END
//********************************************************************

