var doDenerateTOC = true; // can be set to false...
function generateTOC(){
	if(doDenerateTOC){
		if(generate_TOC2('tocContents','content')){
			t = document.getElementById('toc');
			t.className = "showMe"; 
		}
	}
}

/*

This function is the main entry point into this script. 
It is intended to be called from the <body onload=""> handler with the 
ID of some <div> element (or anything else) that will be the parent of TOC.

It will construct the list of all headings, using getHeadlines(), 
then iterate through it and create elements inside the parent for each headline. 
The created elements will consist of a <div> having the class name "levelX", 
where X is the level of indentation (1 to 6) of that TOC entry. 
This will allow easy customization through CSS.


*/

function generate_TOC(parent_id) {
  var parent = document.getElementById(parent_id);
  var hs = getHeadlines(document.getElementsByTagName("body")[0]);
  for (var i = 0; i < hs.length; ++i) {
    var hi = hs[i];
    var d = document.createElement("div");
    if (hi.element.id == "")
      hi.element.id = "gen" + i;
    var a = document.createElement("a");
    a.href = "#" + hi.element.id;
    a.appendChild(document.createTextNode(hi.text));
    d.appendChild(a);
    d.className = "level" + hi.level;
    parent.appendChild(d);
  }
}

function generate_TOC2(parent_id,target_id) {
  var parent = document.getElementById(parent_id);
  var target = document.getElementById(target_id);  

  var hs = getHeadlines(target);
  parent.className = "hideMe";    
  
  // find any hs' to remove
  for (var i = 0; i < hs.length; ++i) {
    var hi = hs[i];
	var el = hi.element;
	var cl = el.className;
	//exclude specific classes
	if( cl != null && 
	   (cl.toUpperCase() == "PAGETITLE" ||
		cl.toUpperCase() == "TOCROUNDTOP" || 
		cl.toUpperCase() == "TOCROUNDBOTTOM")){		
		hs.splice(i--,1); //remove current element....		 
	}	
  }//next 

  
  //check to see if the given sequence of nesting requires
  //a generation of toc

  if(hs.length < 3)
  	return 0;  
  
  for (var i = 0; i < hs.length; ++i) {
    var hi = hs[i];
    var d = document.createElement("div");
    if (hi.element.id == "")
      hi.element.id = "gen" + i;
    var a = document.createElement("a");
    a.href = "#" + hi.element.id;
    a.appendChild(document.createTextNode(cropText(hi.text)));
    d.appendChild(a);
    d.className = "level" + hi.level;
    parent.appendChild(d);
  } 
  
  parent.className = "showMe";
  return i;

}

/*

For retrieving text from a simple heading like "<H2>Overview</H2>" 
we could use simple code like "text = element.firstChild.data;". 
However, we want to be able to retrieve code even from complicated 
headings, like "<H2><b>This</b> is a <em>complicated</em> 
<u>heading</u></H2>". They just might contain more than simple text, 
therefore we need to have a recursive function that walks through all 
children elements and accumulates every little piece of text it finds. 

*/

function H_getText(el) {
  var text = "";
  for (var i = el.firstChild; i != null; i = i.nextSibling) {
    if (i.nodeType == 3 /* Node.TEXT_NODE, IE doesn't speak constants */)
      text += i.data;
    else if (i.firstChild != null)
      text += H_getText(i);
  }
  return text;
}


function TOC_EL(el, text, level) {
  this.element = el;
  this.text = text;
  this.level = level;
}
/*

However, this method does not work for Internet Explorer 5.0 
because the browser doesn't properly understand the "*" parameter 
and returns no elements. Therefore we created the following function 
to deal with this problem. The function returns an Array object 
containing all the headlines found in the document, as objects defined 
in the previous section (thus also having the title and the TOC level). 
It should be called with a reference to the <BODY> element.

Some notes:

getHeadlines() contains a nested function. This function doesn't have 
a name, but we "assign" it to the variable rec so that we can call it. 
This kind of construct is very useful to avoid putting too many parameters 
or local variables inside the recursive function - it has access to variables 
defined in the containing function. 

We are using a RegExp to test if the current element is a headline, 
that is, if it's tagName matches any of Hx, where x is 1 .. 6. 

A somewhat confusing construct is used to push an element 
into the array: "l[l.length] = ...". That is because IE5 does not 
have the push method in the Array object. I recently found 
a good article that shows how to solve such problems at a more general level
*/

function getHeadlines(el) {
	

  var l = new Array;
  var rx = /[hH]([1-6])/;
  // internal recursive function that scans the DOM tree
  var rec = function (el) {
    for (var i = el.firstChild; i != null; i = i.nextSibling) {
      if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {		
		if (rx.exec(i.tagName))
          l[l.length] = new TOC_EL(i, H_getText(i), parseInt(RegExp.$1));
        rec(i);
      }
    }
  }
  rec(el);
  return l;
}


function cropText(s){
	var maxLen = 20;
	var ss = "";
	
	
	if(s.length > maxLen){

		ss = s.substr(0,maxLen);

		for(var i = ss.length; i > maxLen * 0.75 ; i--){
			if (ss[i] == " "){
				return (ss.substr(0,i) + " ...");
			}
		}
		return ss + " ...";
	}
	
	return s;	
}



