/*

Tree Menu
---------
Copyright 2000 idea2net, Inc.
http://www.idea2net.com

Version 1.0

Supports only one level of nesting, ie a menu and submenu.

  Date    Who    Change description
--------  ---  -----------------------------------------------------
06/02/27  LDM  Changed to support multiple levels of submenus (at least 2).

*/

var a = new Array();

/*

function getMenuID(menuName)

input:
menuName:     The name of the menu item, (the link name)

returns:
the ID of the menu with menuName


*/
function getMenuID(menuName)
{
   for (var i = 0; i < a.length; i++)
   {
      if (indexOf(a[i][4], menuName) != -1) return a[i][1];
   }
   return -1;
}


/*

function withMenu(menuName, url)

input:
menuName:     The ID of the menu item to select for the link
url:          The url to modify

returns:
the modified url

*/
function withMenu(menuID, url)
{
   if (menuID != -1)
      return addQueryParameter(url, "smenu", menuID);
   else
      return url;
}


/*

function modifyLinks

modifies all the links on the page, adds smenu=____ to it.

*/
function modifyLinks()
{
  var linkCount = document.links.length;
  var smenuvalue = getQueryParameter("smenu");

  for (var i = 0; i < linkCount; i++)
  {
    if ((smenuvalue != false) && (document.links[i].href.indexOf("javascript") == -1) && (document.links[i].href.indexOf("?") == -1))
      document.links[i].href = addQueryParameter(document.links[i].href, "smenu", smenuvalue);
  }
}


/*
   function addMenuItem

   This function allows the user to add a menu item to the tree Menu

   id             Every menu item must have a unique integer ID
                  ** Integer must be 1 or greater
   parentID       The integer id of the parent menu.
                  Enter 0 if the menu item is a top level menu
   closedImg      Image to use when the menu is not expanded
                  Enter 0 to indicate that no image should be used
   expandedImg    Image to use when the menu is expanded
                  Enter 0 to indicate that no image should be used
   linkName       The text of the menu Item
   linkURL        The URL to link to when the item is clicked

*/
function addMenuItem (id, parentID, closedImg, expandedImg, linkName, linkURL)
{
   if (id < 1)
   {
      showError("MenuID must be an integer greater than 0");
      return;
   }

   var parentExists = false;

   //
   // Check input:
   // Make sure menu id doesn't already exist
   // Make sure parent id, if one has been designated, exists
   //
   var strParentID = parentID.toString() + "";
   var parents = new Array ();
   var j;
   if((parentID != 0))
      {if ((strParentID.length > 3) && ((strParentID.length % 3) != 0))
          {showError("MenuItem " + id + ": parent ID string (" + parentID + ") invalid (%3).");
           return;
           }  //make sure length of parent string is right

       for (var i = 0; i < strParentID.length; i = i + 3)
          {var l = i + 3;
           if (l > strParentID.length) l = strParentID.length;
           parents[parents.length] = strParentID.substring(i,l);
           }   //break parent ID string into an array of ids
       }   //have parent
   var parentCount = parents.length;

   for (var i = 0; i < a.length; i++)
   {
      if(a[i][0] == id)
      {
         showError("MenuItem " + id + " already exists. Menu will not be added.");
         return;
      }   //id in array already

      if((parentID != 0))
         {for (var j = 0; j < parents.length && parentCount > 0; j++)
             {if (a[i][0].toString() == parents[j])
                 {parentCount --;
                  parents[j] = "";
                  j = parents.length;
                  }   //matched
              }   //check for that parent exists
          }   //have parent
   }   //for all in array already

   if (parents.length > 0 && parentCount > 0)
      {var t = "";
       var s = "";
       for (var i = 0; i < parents.length & parentCount > 0; i ++)
          {if (parents[i] != "")
              {t = t + s + parents[i];
               if (parentCount > 2) s = ", ";
               if (parentCount == 2) s = " and ";
               parentCount --;
               }   //id not matched
           }   //for all parents
       if (s != "") s = "s";
       showError("MenuItem " + id + ", Parent ID" + s + " " + t + " not found.");
       return;
       }   //have parents and some not matched
   else
       parentExists = true;

   if ((parentID != 0) && (parentExists == false))
   {
      showError("Parent Menu for menu item " + id + " does not exist. Menu will not be added.");
      return;
   }

   a[a.length] = new Array(id, parentID, closedImg, expandedImg, linkName, linkURL);
}


function showError(msg)
{
   alert("ERROR TreeMenu.js:\n" + msg + "\n");
}


/*

function getQueryParameter

Input:
attrName    The name of the query parameter

Returns:
value of the attribute, or a boolean false if the attribute does not exist.

*/
function getQueryParameter(attrName)
{
   var query = this.location.search.substring(1);

   if (query.length > 0)
   {
      var params = query.split("&");

      var value;

      for (var i=0 ; i < params.length ; i++)
      {
         var pos = params[i].indexOf("=");
         var name = params[i].substring(0, pos);
         if (name == attrName)
         {
            var value = params[i].substring(pos + 1);
            if (value.length == 0)
               return true;
            else
               return value;
         }
      }
   }
   else
   {
      return false;
   }
}


/*
function addQueryParameter (url, paramName, paramValue);

Input:
url:        a complete url
paramName:  the name of the query parameter to add
paramValue: the value of the query parameter to add

Returns:
The modified URL.

*/
function addQueryParameter(url, paramName, paramValue)
{
   var poundLoc = url.lastIndexOf("#");

   var resourceAndQuery = (poundLoc == -1) ? url : url.substring(0,poundLoc);

   // Here are the 3 parts of the URL
   var localAnchor = (poundLoc == -1) ? "" : url.substring(poundLoc);
   var resource = (resourceAndQuery.split("?"))[0];
   var query = substringAfter(resourceAndQuery, "?");

   if (query.indexOf(paramName + "=") == -1)
      query = ((query == "") ? "" : query + "&") + paramName + "=" + paramValue;

   return (resource + "?" + query + localAnchor);
}


/*

function displayMouseTracks

Input:

styleClass     The CSS style class to used to format the mouse tracks links
delimiter      The text delimiter to use between the links


Functionality:

Writes the Mouse tracks to the html page

Returns true if something was printed,
false if not.

*/
function displayMouseTracks(styleClass, delimiter)
{
   var sMenuID = getQueryParameter("smenu");

   if (sMenuID == false) return false;

   // Print the mouse track for the menu to expand
   for (var i = 0; i < a.length; i++)
   {
      if (a[i][0] == sMenuID)
      {
         // Check to see if the menu has a parent, if so, we should print that first
         parentMenu = a[i][1];
         var strParentMenu = parentMenu.toString();
         var parents = new Array ();
         if((parentMenu != 0))
            {for (var j = 0; j < strParentMenu.length; j = j + 3)
                {var l = j + 3;
                 if (l > strParentMenu.length) l = strParentMenu.length;
                 parents[parents.length] = strParentMenu.substring(j,l);
                 }   //break parent ID string into an array of ids
              }   //have parent
         var parentCount = parents.length;

         for (var j = 0; j < a.length; j++)
         {
            for (var k = 0; k < parents.length; k ++)
            {
               if (a[j][0].toString() == parents[k])
                  {
                     document.write("<span class=\"mouseTrack\" style=\"COLOR: black;\">" + delimiter + "</span>");
                     document.write("<a class=" + styleClass + " href=" + addQueryParameter(a[j][5],"smenu",a[j][0]) + ">" + a[j][4] + "</a>");
                     k = parents.length;
                     //k = a.length;
                  }   //ancestor of item
            }   //for all ancestors
         }   //for all items

         document.write("<span class=\"mouseTrack\" style=\"COLOR: black;\">" + delimiter + "</span>");
         document.write("<a class=" + styleClass + " href=" + addQueryParameter(a[i][5], "smenu", a[i][0]) + ">" + a[i][4] + "</a>");

         return true;
      }
   }

   return false;
}


/*
function displayMenu

Input:

styleClass1    The CSS style class for parentMenus
styleClass2    The CSS style class for subMenus

?smenu=       displayMenu requires this query parameter. It is the id of the menu to expand.
               If there is no menu with the given id, no menu is expanded.

Functionality:
Writes the menu to the html page. Returns nothing.

*/
function displayMenu (styleClass1, styleClass2)
{
   // smenu is the selected menu
   var smenuID = getQueryParameter("smenu");
   if (smenuID == false)
      smenuID = -1;

   // smenuIndex is index of 'smenuID' in array a
   var smenuIndex = idToIndex(smenuID);
   var parents = new Array ();
   var parentList = new Array ();
   var strParentID = "";
   var strParentID2 = "";
   var nColMax = 3;

   if (smenuIndex == -1)
      smenuParentID = -1;
   else
      {smenuParentID = a[smenuIndex][1];
       if ((smenuParentID != 0))
          {strParentID = smenuParentID.toString() + "";
           strParentID2 = smenuParentID.toString() + smenuID.toString();
           for (var i = 0; i < strParentID.length; i = i + 3)
              {var l = i + 3;
               if (l > strParentID.length) l = strParentID.length;
               parents[parents.length] = strParentID.substring(i,l);
               var x = parentList.length;
               if (x == 0)
                  parentList[x] = strParentID.substring(i,l);
               else
                  parentList[x] = parentList[(x - 1)] + strParentID.substring(i,l);
               }   //break parent ID string into an array of ids
           var x = parentList.length;
           //add potential parent to list
           if (x == 0)
              parentList[x] = smenuID.toString();
           else
              parentList[x] = parentList[(x - 1)] + smenuID.toString();
           }   //have parent
       nColMax = parents.length + 3;
       }   //have index

   document.writeln("<table border='0' cellpadding='1'>");
   for (var i = 0; i < a.length; i++)
   {  var id = a[i][0];
      var parentID = a[i][1];
      var closedImg = a[i][2];

      var expandedImg = a[i][3];
      var linkName = a[i][4];
      var linkURL = a[i][5];

      if (parentID == 0)
      {
         document.writeln("<tr>");

         // There are two situations where we would expand the top level menu:
         // 1) The menu was selected as the one to expand
         // 2) A child menu of this menu was selected
         var expandMenu = (id == smenuID); // || (id == smenuParentID);
         if (expandMenu == false)
            {for (var j = 0; j < parents.length && expandMenu == false; j ++)
                {if (parents[j] == id.toString())
                    expandMenu = true;
                 }   //for all parents of selected item
             }   //not selected item

         // draw the image as the first column of the table
         document.writeln("<td colspan='1'>");
         if (expandMenu)
            document.writeln(expandedImg
                                ? "<img src=" + expandedImg + ">"
                                : "");
         else
            document.writeln(closedImg
                                ? "<img src=" + closedImg + ">"
                                 : "");
         document.writeln("</td>");

         // write the link through the second and third columns
         document.write("<td colspan='" + (nColMax - 1) + "'><a class=" + styleClass1 + " href=");
         document.write(expandMenu == true
                           ? addQueryParameter(linkURL, "smenu", 0)
                           : addQueryParameter(linkURL, "smenu", id));
         document.write(">" + linkName);
         document.write("</a></td>");

         document.writeln("</tr>");

         //
         // If we are expanding this menu, then write the links for its children menus
         //
         if(expandMenu)
         {var parentMenu = false;
            for (var j = 0; j < a.length; j++)
            {parentMenu = (a[j][1] == id);
             for (var k = 0; k < parentList.length && parentMenu == false; k ++)
                {if (parentList[k] == a[j][1].toString())
                    parentMenu = true;
                 }   //for all parents of selected item

             // If we have found a parent menu, print it..
             if (parentMenu)
               {
                  var child_id = a[j][0];
                  var child_smenu = child_id.toString();
                  var child_parentID = a[j][1];
                  var colspan = parseInt(child_parentID.toString().length / 3);
                  if (colspan == 0) colspan = 1;
                  var child_closedImg = a[j][2];
                  var child_expandedImg = a[j][3].toString();
                  var child_linkName = a[j][4];
                  var child_linkURL = a[j][5];
                  var img = (child_closedImg ? "<img src=" + child_closedImg + ">" : "");
                  var expandImg = false;
                  if (child_closedImg != child_expandedImg &&    //not the same
                      child_expandedImg != "0")                  //expanded exists
                     {if (child_id == smenuID)
                         {expandImg = true;
                          if (parents.length > 0)   // take last item in list
                             child_smenu = parents[(parents.length - 1)];
                          else
                             child_smenu = "0";
                          }   //clicked menu item
                      else
                         {for (var k = 0; k < parents.length; k ++)
                             {if (parents[k] == child_id.toString())
                                 {expandImg = true;
                                  if (k > 0)   // take previous item in list
                                     child_smenu = parents[(k - 1)];
                                  else
                                     child_smenu = "0";
                                  k = parents.length;
                                  }   //item is an ancestor
                              }   //for all ancestors
                          }   //clicked menu item
                      }   // have expanded image
                  if (expandImg)
                     img = (child_expandedImg ? "<img src=" + child_expandedImg + ">" : "");

                  document.writeln("<tr>");
                  document.writeln("<td colspan='" + colspan + "'>&nbsp;</td>");

                  // draw the image as the first column of the table
                  document.writeln("<td colspan='1'>");
                  document.writeln(img);
                  document.writeln("</td>");

                  document.writeln("<td colspan='" + (nColMax - colspan - 1) + "'>");
                  document.writeln("<a class=" + styleClass2 + " href=" + addQueryParameter(child_linkURL, "smenu", child_smenu) + " >" + child_linkName + "</a>");
                  document.writeln("</td>");

                  document.writeln("</tr>");
               }   // parent menu to get expanded
            }   // for all items
         }   // menu to be expanded
      }   // menu item with no parent
   }   //for all menu items
   document.writeln("</table>");
}


/*
substringBefore

Parameters:
conString      A String (containing string)
subString      A substring to search for within 'conString'

Returns:
the substring in 'conString' after 'subString'
OR, returns the original 'conString' if the 'subString' does not exist within it.

NOTE this function searches for the substring from the end frontwards (left to right)

*/
function substringBefore(conString, subString)
{
   return string.split(subString)[0];
}


/*
substringAfter

Parameters:
conString      A String (containing string)
subString      A substring to search for within 'conString'

Returns:
the substring in 'conString' after 'subString'
OR, returns an empty string if the 'subString' does not exist within 'conString'

NOTE this function searches for the substring from the end backwards (right to left)
*/
function substringAfter(conString, subString)
{
   var sLoc = conString.lastIndexOf(subString)+1;
   if (!sLoc) return "";

   return conString.substring(sLoc);
}


/*
function idtoIndex

Input:
menuID    id of a menu item

Returns:
index (location in the menu array) of the menu
or -1 if the menuID does not exist

*/
function idToIndex(menuID)
{
   for (var i = 0; i < a.length; i++)
   {
      if (a[i][0] == menuID)
         return i;
   }
   return -1;
}