/* Copyright © 2002 Jean-Claude Manoli [jc@manoli.net]
 *
 * This software is provided 'as-is', without any express or implied warranty.
 * In no event will the author(s) be held liable for any damages arising from
 * the use of this software.
 * 
 * Permission is granted to anyone to use this software for any purpose,
 * including commercial applications, and to alter it and redistribute it
 * freely, subject to the following restrictions:
 * 
 *   1. The origin of this software must not be misrepresented; you must not
 *      claim that you wrote the original software. If you use this software
 *      in a product, an acknowledgment in the product documentation would be
 *      appreciated but is not required.
 * 
 *   2. Altered source versions must be plainly marked as such, and must not
 *      be misrepresented as being the original software.
 * 
 *   3. This notice may not be removed or altered from any source distribution.
 */ 

var treeSelected = null; //last treeNode clicked
var indexSelected = null; //last indexNode clicked

//pre-load tree nodes images
var imgPlus = new Image();
imgPlus.src="/images/treenodes/closed.gif";
//imgPlus.src="/images/treenodes/treenodeplus.gif";
var imgMinus = new Image();
imgMinus.src="/images/treenodes/open.gif";
//imgMinus.src="/images/treenodes/treenodeminus.gif";
var imgDot = new Image();
imgDot.src="/images/treenodes/topic.gif";
//imgDot.src="/images/treenodes/treenodedot.gif";


function findNode(el)
{
// Takes element and determines if it is a treeNode.
// If not, seeks a treeNode in its parents.
	while (el != null)
	{
		if (el.className == "treeNode")
		{
			break;
		}
		else
		{
			el = el.parentNode;
		}
	}
	return el;
}


function clickAnchor(el)
{
// handles click on a TOC link
//
	expandNode(el.parentNode);
	selectNode(el.parentNode);
	el.blur();
}


function selectNode(el)
{
// Un-selects currently selected node, if any, and selects the specified node
//
    // tree node selected
    if ((el.getAttribute('type') == 'tree') || (el.getAttribute('type') == 'cat')){
	   if (treeSelected != null)
	   {
	     // it could be same id element in tree and index divs
	  
	      if (el.getAttribute('id') != treeSelected.getAttribute('id')) {
		    setSubNodeClass(treeSelected, 'A', 'treeUnselected');
		  }
	   }	
	   setSubNodeClass(el, 'A', 'treeSelected');
	   treeSelected = el;
	}

	
	// index node selected
	if ((el.getAttribute('type') == 'index') || (el.getAttribute('type') == 'lib')){
	  if (indexSelected != null)
	  {
	    if (el.getAttribute('id') != indexSelected.getAttribute('id')) {
		  setSubNodeClass(indexSelected, 'A', 'treeUnselected');
		}
	  }	
	  setSubNodeClass(el, 'A', 'treeSelected');
	  indexSelected = el;
	}
	
}


function selectNode2(el)
{
// Un-selects currently selected node, if any, and selects the specified node
//
    // tree node selected
    if ((el.getAttribute('type') == 'tree') || (el.getAttribute('type') == 'cat')){
      // unselect all index and lib divs
      
	   if (treeSelected != null)
	   {
	     // it could be same id element in tree and index divs
	  
	      if (el.getAttribute('id') != treeSelected.getAttribute('id')) {
		    setSubNodeClass(treeSelected, 'A', 'treeUnselected');
		  }
	   }	
	   setSubNodeClass(el, 'A', 'treeSelected');
	   treeSelected = el;
	}

	
	// index node selected
	if ((el.getAttribute('type') == 'index') || (el.getAttribute('type') == 'lib')){
	  if (indexSelected != null)
	  {
	    if (el.getAttribute('id') != indexSelected.getAttribute('id')) {
		  setSubNodeClass(indexSelected, 'A', 'treeUnselected');
		}
	  }	
	  setSubNodeClass(el, 'A', 'treeSelected');
	  indexSelected = el;
	}
	
}

function setSubNodeClass(el, nodeName, className)
{
// Sets the specified class name on el's first child that is a nodeName element
//
	var child;
	for (var i=0; i < el.childNodes.length; i++)
	{
		child = el.childNodes[i];
		if (child.nodeName == nodeName)
		{
			child.className = className;
			break;
		}
	}
}


function setSubNodeSrc(el, xSrc)
{
// Sets the specified class name on el's first child that is a nodeName element
//
	var child;
	for (var i=0; i < el.childNodes.length; i++)
	{
		child = el.childNodes[i];
		if (child.nodeName == 'IMG')
		{
			child.src = xSrc;
			break;
		}
	}
}

function getSubNodeSrc(el)
{
// Sets the specified class name on el's first child that is a nodeName element
//
	var child;
	for (var i=0; i < el.childNodes.length; i++)
	{
		child = el.childNodes[i];
		if (child.nodeName == 'IMG')
		{
			return child.src;
		}
	}
}

function expandCollapse(el)
{
//	If source treeNode has child nodes, expand or collapse view of treeNode
//
   
   	if (el == null)	return;	//Do nothing if it isn't a treeNode
		
		
	var child;
	var imgEl;
	for(var i=0; i < el.childNodes.length; i++)
	{
		child = el.childNodes[i];
		if (child.src)
		{
			imgEl = child;
		}
		else if (child.className == "treeSubnodesHidden")
		{
			child.className = "treeSubnodes";
			imgEl.src = imgMinus.src; 
			break;
		}
		else if (child.className == "treeSubnodes")
		{
			child.className = "treeSubnodesHidden";
			imgEl.src = imgPlus.src; 
			break;
		}
	}
}


function expandNode(el)
{
//	If source treeNode has child nodes, expand it
//
	var child;
	var imgEl;
	for(var i=0; i < el.childNodes.length; i++)
	{
		child = el.childNodes[i];
		if (child.src)
		{
			imgEl = child;
		}
		if (child.className == "treeSubnodesHidden")
		{
			child.className = "treeSubnodes";
			imgEl.src = imgMinus.src; 
			break;
		}
	}
}


function expandParentNode(el)
{
//	If source treeNode's parent is closed, expand it all the way to the root

	var parent = el.parentNode.parentNode;
	if (parent == null) return;
	
	var parentSrc = getSubNodeSrc(parent);
	
	if (parentSrc == imgPlus.src){
	  setSubNodeSrc(parent,imgMinus.src);
	  el.parentNode.className = "treeSubnodes";
	  expandParentNode(parent);
	}
}

function syncTree2(topicid)
{
// Selects and scrolls into view the node that references the specified topicid
//
   // alert("topicid=" + topicid);
   if (topicid == "") return ;
   
   var tocEl = findElementByTopicID(document.getElementById('contents_inner'), topicid);
   //var tocEl = findElementByTopicID(document.getElementById('treeRoot'), topicid);
   if (tocEl != null) selectAndShowNode(tocEl);
	
   var tocEl = findElementByTopicID(document.getElementById('index_inner'), topicid);
   //var tocEl = findElementByTopicID(document.getElementById('indexRoot'), topicid);
   if (tocEl != null) selectAndShowNode(tocEl);
	
}

function findElementByTopicID(node, topicid)
{
// find the <div> element with the specified href value
//
    if (node == null) return null;
    
	var el;
	var divs = node.getElementsByTagName('DIV');
	for (var i = 0; i < divs.length; i++)
	{
		el = divs[i];
		var xid = new String();
		xid = el.getAttribute('id');
		
		if (xid == topicid)	return el;
	}
	return null;
}


function syncTree(href)
{
// Selects and scrolls into view the node that references the specified URL
//
	var loc = new String();
	loc = href;
	if (loc.substring(0, 7) == 'file://')
	{
		loc = 'file:///' + loc.substring(7, loc.length);
		loc = loc.replace(/\\/g, '/');
	}
	
	var base = loc.substr(0, loc.lastIndexOf('/') + 1);
	
	var tocEl = findHref(document.getElementById('treeRoot'), loc, base);
	if (tocEl != null)
	{
		selectAndShowNode(tocEl);
	}
}


function findHref(node, href, base)
{
// find the <a> element with the specified href value
//
	var el;
	var anchors = node.getElementsByTagName('A');
	for (var i = 0; i < anchors.length; i++)
	{
		el = anchors[i];
		var aref = new String();
		aref = el.getAttribute('href');
		
		if ((aref.substring(0, 7) != 'http://') 
			&& (aref.substring(0, 8) != 'https://')
			&& (aref.substring(0, 7) != 'file://'))
		{
			aref = base + aref;
		}
		
		if (aref == href)
		{
			return el;
		}
	}
	return null;
}

function selectAndShowNode(node)
{
// Selects and scrolls into view the specified node
//
	var el = findNode(node);
	if (el != null) 
	{
		selectNode(el);
		do 
		{
			expandNode(el);
			el = findNode(el.parentNode);
		} while ((el != null))  
		
		//vertical scroll element into view
		var windowTop;
		var windowBottom;
		var treeDiv = document.getElementById('tree');
		
		var ua = window.navigator.userAgent.toLowerCase();
		if ((i = ua.indexOf('msie')) != -1)
		{
			windowTop = node.offsetTop - treeDiv.scrollTop;
			windowBottom = treeDiv.clientHeight - windowTop - node.offsetHeight;
		}
		else if (ua.indexOf('gecko') != -1)
		{
			windowTop = node.offsetTop - treeDiv.offsetTop - treeDiv.scrollTop;
			windowBottom = treeDiv.clientHeight - windowTop - node.offsetHeight;
		}
		else 
		{
			return;
		}
		
		if (windowTop < 0)
		{
			treeDiv.scrollTop += windowTop - 18;
			return;
		}
		if (windowBottom < 0)
		{
			treeDiv.scrollTop -= windowBottom - 18;
			return;
		}
	}
}


function resizeTree()
{
	var treeDiv = document.getElementById('tree');
	//treeDiv.setAttribute('style', 'width: ' + document.body.offsetWidth + 'px; height: ' + (document.body.offsetHeight - 27) + 'px;');
	treeDiv.style.width = document.documentElement.offsetWidth;
	treeDiv.style.height = document.documentElement.offsetHeight - 27;
}


function UnselectDivsOfType(rootid,nodetype) {
          
          var maindiv = document.getElementById(rootid);
          var allells = maindiv.getElementsByTagName('DIV');
          var xell;
          var divtype;
          
          for(var i=0; i < allells.length; i++)
	      {
	        xell = allells[i]; 
		    divtype = xell.getAttribute('type');
		    
		    if (nodetype == divtype)
		    {
		      //alert('unselect divtype=' + divtype);
		      setSubNodeClass(xell, 'A', 'treeUnselected');
		      // if it is folder expand it
		    }
	      }
}
        
function SelectDivsWithId(rootid,nodeid) {
          
          var maindiv = document.getElementById(rootid);
          var allells = maindiv.getElementsByTagName('DIV');
          var xell;
          var divtype;
          var offsetTop = 0;
          
          for(var i=0; i < allells.length; i++)
	      {
	        xell = allells[i]; 
		    divid = xell.getAttribute('id');
		
		    if (nodeid == divid)
		    {
		      setSubNodeClass(xell, 'A', 'treeSelected');
		      // make sure that tree is expanded to show this node
		      expandParentNode(xell);
		      expandNode(xell);
		      
		      if (offsetTop < 1){
		        offsetTop = xell.offsetTop;
		       // alert("SelectDivsWithId.offsetTop="+offsetTop);
		      }
		      
		    }
		    else
		    {
		      setSubNodeClass(xell, 'A', 'treeUnselected');
		    }
	      }
	      return offsetTop;
}

function GetNextDivWithId(rootid,parentnodeid) {
          
          var maindiv = document.getElementById(rootid);
          var allells = maindiv.getElementsByTagName('DIV');
          var xell;
          var divtype;
          var fParentFound = false;
          var xdivid;
          var childDivEl;
          
          for(var i=0; i < allells.length; i++)
	      {
	        xell = allells[i]; 
		    divid = xell.getAttribute('id');
		
		    if (parentnodeid == divid)
		    {
		    
		       xdivid = GetFirstChildDivId(xell);
		       
		       if (xdivid > 0) {
		      //   alert ("first child divid=" + xdivid);
		         return xdivid;
		       }  
		    
		       		     
		       if (i == (allells.length - 1)){
		         // it is last node in this brench
		         // get node next to parent
		         var nextsibling = xell.parentNode.nextSibling;
		         
		         if (nextsibling != null) { 
                 // alert ("next parent.sibling divid=" + nextsibling.getAttribute('id'));
		           return nextsibling.getAttribute('id');
		         }  
		       }
		     
		       fParentFound = true;
		    }
		    else
		     if (fParentFound == true) {
		       
		       if (divid > 0){
               //  alert ("next divid=" + divid);
		        return divid;
		       } 
		       
		       xdivid = GetFirstChildDivId(xell);
		       
		       if (xdivid > 0) {
		       //  alert ("first child divid=" + xdivid);
		         return xdivid;
		       }  
		       
		       
		       return 0;
		     }  
		    
	      }
	      return 0;
}

function GetFirstChildDivId(ell){

  // alert("GetFirstChildDivEl " + ell.childNodes.length);
   if (ell.childNodes.length == 0) return null;
   
   var xnode; 
   var divid;
   
   
   for (i=0; i<ell.childNodes.length; i++){
     xnode = ell.childNodes[i];
     
     if (xnode.nodeName == "DIV") {
       
       divid = xnode.getAttribute('id')
       if (divid > 0) return divid; 
       
       return GetFirstChildDivId(xnode);
      
     }  
   }
   return null;
}

function GetPrevDivWithId(rootid,nodeid) {
   
        //alert("GetPrevDivWithID");       
          var maindiv = document.getElementById(rootid);
          var allells = maindiv.getElementsByTagName('DIV');
          var xell;
          var divtype;
          var previd = 0;
          
          for(var i=0; i < allells.length; i++)
	      {
	        xell = allells[i]; 
		    divid = xell.getAttribute('id');
		
		    if (nodeid == divid)
		    {
		      return previd;
		    }
		    
		    if (divid > 0) previd = divid;
		    
	      }
	      return 0;
}

