// <SCRIPT>
// REFERENCED BY:  MODULE "index.html" files.
//
// FUNCTIONS:      + To construct & facilitate module navigation.
//                 + The referencing of this file by _ALL_ modules
//                   enables global changes to be made to module
//                   navigation by modifying this file alone.



// ALL additions/changes/deletions whatsoever are to be brought to
// Luke's attention if it is desired that they be included.
// e-mail: bellal@rpi.edu.  Suggestions are welcome.
// ********************************************************
// ** THIS FILE IS TO BE UPDATED !ONLY! BY LUKE BELLANDI **
// ** One person editing ensures a coordinated           **
// ** navigation scheme                                  **
// ********************************************************
// last update: Tuesday, 26 February 2002 9:42AM [Lawrence Lansing] 
// last update: We'n'sday, 18 August 1999 2:35PM [MM] 
// last update: Thursday, 15 July 1999 2:35PM [LB] 


// Style sheet and "/devmodules/" finder as well as incompatible browser check
// were originally coded by Pamela Kott.  Revisions made to all 3 functions made
// by Luke Bellandi.  All other code written by Luke Bellandi



          ///////////////////////
          // FILE DEPENDENCIES //
          ///////////////////////
          //
          // Aside from the graphics referenced at the end of the file (changeable by the user),
          // this depends on the following files (all rooted in "devmodules/shared/"):
          // These files are globally used and MUST NOT BE INDIVIDUALLY TAILORED--
          // there should be no reason to do so.
          //
          // 1) html/blank.html   
          // 2) html/corner.html
          // 3) graphics/bkgleft2.jpg
          // 4) navigation/graphics/smallLinksLogo.gif
          // 5) style/*.*  (all style sheets)
          // 6) html/help.html
          //
          ///////////////////////


          ///////////////////////
          // FILE EXPECTATIONS //
          ///////////////////////
          //
          // This navigation scheme expects that you have the following files.
          // These are referenced from your module's root directory.
          //
          // 1) index.html           (the one & only file in each module that references this JavaScript "header" file)
          // 2) html/start.html      (beginning page to be loaded into the "mid_content" frame)
          // 3) html/crib.html       (brick)
          // 4) html/library.html    (brick)
          // 5) html/map.html        (brick)
          //
          ///////////////////////



/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// BUILDING THE NAVIGATION: HOW DOES THIS WORK?                                                            //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 1) index.html includes this source file.                                                                //                                                                
// 2) index.html passes all information for navigation construction (headers & links, etc.)                //                                                                               
//    to this file for storage.                                                                            //
// 3) index.html calls the 'buildNavigation()' function to begin building the navigation components.       //
// 4) 'buildNavigation()' produces the rest of the HTML for the index file, constructing its frames.       //
// 5) corner.html is one of the files called in the frame layout (blank.html is used for the               //
//    "side_nav" & "mid_content" in the meantime)                                                          //
// 6) corner.html calls for the "side_nav" frame to be built (functions included here in the "top" frame)  //
// 7) corner.html calls for the content frame ("mid_content") to be built (again using functions from      //
//    the "top" frame"                                                                                     //
// 8) corner.html calls the functions to build itself (need to call this last so that any writes to this   //
//    file do not overwrite calls to other functions)                                                      //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////



          //////////////////////////////////////////////////
          //      'Include' CONTENTS:                     //
          //  (1) Style Sheet & 'devmodules/' Finder      //
          //  (2) Incompatible Browser check              //
          //  (3) Frame setup                             //
          //  (4) Frame implementation                    //
          //  (5) Navigation component updaters           //
          //  (6) Navigation functions                    //
          //  (7) Helper functions                        //
          //  (8) Global variable declaration &           //
          //      Preliminary execution                   //
          //  (9) Module aesthetic variables (to modify)  //
          //////////////////////////////////////////////////


/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////


  
//----------------------------------------------------------------------------------
// (1) Style Sheet & 'devmodules/' Finder
//----------------------------------------------------------------------------------

  function module_root()
  {
    if (module_root_string != null) return module_root_string;
    else
    {
      h = new String(document.location);
      i = h.indexOf(module_root_search_string);
      if (i < 0) // no "modules"?  Maybe it's the home page.
      {
        if (h.indexOf("http:") == 0)
          return module_root_string = h.substring(0, h.indexOf("/", 8)) + "/devmodules/";
        else
          return module_root_string = h.substring(0, h.lastIndexOf("/")) + "/../";
      }
    else
      {
        j = i + module_root_search_string.length + 1;
        return module_root_string = h.substring(0, j);
      }
    return module_root_string;
      }
  }


function getStyle()
  {
    var fileString= "navstyle";
    var OSString="", browserString="";
    
    var UNIXChecklist = new Array("AIX", "IRIX", "HPUX", "LINUX", "BSD", "FREEBSD", "SCO", "UNIXWARE", "MPRAS", "RELIANT",
                                  "DEC", "SINIX", "SUN");

    // determine OS
    if (navigator.userAgent.indexOf("Win")>=0)
      OSString = "Win";
    else if (navigator.userAgent.indexOf("Mac")>=0)
      OSString = "Mac";
    else
    {
      tempString = navigator.appVersion;
      tempString = tempString.toUpperCase();
      for(i=0; i<UNIXChecklist.length; i++)
        if(tempString.indexOf(UNIXChecklist[i])>=0)
          { OSString = "Unix"; break; }
    } 


    // determine browser
    if (navigator.appName.indexOf("Netscape")>=0)
      browserString = "Net";
    else if (navigator.appName.indexOf("Microsoft")>=0)
      browserString = "Ie";

    // ensure browser version is valid
    tempString = navigator.appVersion;
    // here's the plan: find the first index of the decimal point in the string and take the string
    // in between that and the first space preceeding it (major version number)
    // then test this "string" as a number.
        
    tempString = tempString.substring(0, tempString.indexOf("."));
    tempString = tempString.substring(tempString.lastIndexOf(" "), tempString.length);
    if(tempString>=3)
    {
      // return complete file string
      fileString = "Nav_" + OSString + "_" + browserString + "_4";
      return (fileString);
    }

    // if incorrect browser version, return default string
    return(fileString);
  }
//-------------------------------------------------------------------------------------




//-------------------------------------------------------------------------------------
// (2) Check for older, incompatible browser versions
//-------------------------------------------------------------------------------------

  function checkBrowser()
  {
    var myBrowser = navigator.appVersion;

    if (myBrowser.indexOf("3.")>=0||myBrowser.indexOf("2.")>=0)
    {
      window.open("http://links.math.rpi.edu/devmodules/shared/html/required.html", "fixIt", 	
      "width=600,height=540,resizable=no,status=no,menubar=yes,scrollbars=yes" );
    }

    // perform IE 4.x for PC platform check
    if (navigator.appName.indexOf("Microsoft")>=0 &&
	myBrowser.indexOf("4.")>=0 &&
	!(myBrowser.indexOf("5.")>=0) && 
	!(myBrowser.indexOf("6.")>=0) && 
	navigator.userAgent.indexOf("Win")>=0)
    {
      if(confirm("We detect that you are using Microsoft Internet Explorer 4.x.\n" + 
                 "It is recommended that you upgrade to the latest version of Internet Explorer.\n" +
                 "Project Links has upgraded to a new navigation system in July 1999.\n" +
                 "This navigation is known to be incompatible with version 4.0 of Internet Explorer\n" +
                 "on the PC platform.  Click 'OK' to return to Project Links home (recommended),\n" +
                 "or click 'CANCEL' to try the module (may crash your browser)."))
        document.location = module_root() + "../"; 
    }
  } 
//-------------------------------------------------------------------------------------
  

  
  
//-------------------------------------------------------------------------------------
// (3) Set up navigation mechanisms
//-------------------------------------------------------------------------------------
  
  /* the following 2 functions dynamically construct the header list for the side navigation links */
  function addHeading(text, URL)
  {
    headerArray[headerIndex] = "H" + text;
    headerLinksArray[headerIndex] = URL;
    headerPopUpArray[headerIndex] = false;
    headerIndex++;
  }                                                

  function addSubHeading(text, URL)
  {
    headerArray[headerIndex] = "S" + text;
    headerLinksArray[headerIndex] = URL;
    headerPopUpArray[headerIndex] = false;
    headerIndex++;
  }
  
  /* these 2 functions are copies of the last 2, but instructing for the link to open in a pop-up window */
  function addHeadingAsPopUp(text, URL)
  {
    headerArray[headerIndex] = "H" + text;
    headerLinksArray[headerIndex] = URL;
    headerPopUpArray[headerIndex] = true;
    headerIndex++;
  }                                                

  function addSubHeadingAsPopUp(text, URL)
  {
    headerArray[headerIndex] = "S" + text;
    headerLinksArray[headerIndex] = URL;
    headerPopUpArray[headerIndex] = true;
    headerIndex++;
  }

  /* function sets fills one slice of a 2D array full of pix (one slice per track) for state buttons */
  /* index[0] of the slice holds the disabled image, index[1] holds the enabled, and index[2] the active image */
  function setTrackStateButtons(textID, picURLDis, picURLEn, picURLAct)
  {
    trackStateMOText[TSBIndex] = textID;
    trackStateButtons[TSBIndex] = new Array;
      trackStateButtons[TSBIndex][0] = new Image;
      trackStateButtons[TSBIndex][0].src = baseDir + picURLDis;
      trackStateButtons[TSBIndex][1] = new Image;
      trackStateButtons[TSBIndex][1].src = baseDir + picURLEn;
      trackStateButtons[TSBIndex][2] = new Image;
      trackStateButtons[TSBIndex][2].src = baseDir + picURLAct;
    TSBIndex++;
  }
//-------------------------------------------------------------------------------------
  
  
  
  
//-------------------------------------------------------------------------------------
// (4) Execute navigation scheme
//-------------------------------------------------------------------------------------

  function buildNavigation()
  {
    buildIndex();
  }                                                                                        

  /* ------------------------------------------------------------------ */  
  /* construct HTML code for the rest of the index file (create frames) */
  /* ------------------------------------------------------------------ */
  function buildIndex()
  {
    // calculate height of corner frame based on components it is to include
    var VSize = 100;
    if(tracksUsed) VSize+=40;
    if(prevNextUsed) VSize+=32;

    // add on to height of corner frame if title is (approximately) more than 2 lines.
    // add 15 pixels for each length of 15 characters (rounded UP)
    if(moduleTitle.length>30)
      VSize+=(Math.ceil((moduleTitle.length-30)/15)*17);
          
    // title the window
    document.writeln('    <TITLE>Project Links | ' + moduleTitle + '</TITLE>');
    document.writeln('  </HEAD>');
    document.writeln();
    document.writeln('  <FRAMESET COLS="165,*" BORDER=0 FRAMESPACING=0 NORESIZE SCROLLING=AUTO>');
    document.writeln('    <FRAMESET ROWS="' + VSize + ',*" BORDER=0 FRAMESPACING=0 NORESIZE SCROLLING=AUTO>');
    document.writeln('      <FRAME NAME="corner" SRC="' + baseDir + 'shared/navigation/html/corner.html" MARGINWIDTH=0 MARGINHEIGHT=0 SCROLLING=NO NORESIZE FRAMEBORDER=0>');
    document.writeln('      <FRAME NAME="side_nav" SRC="' + baseDir + 'shared/navigation/html/blank.html" MARGINWIDTH=0 MARGINHEIGHT=0 NORESIZE FRAMEBORDER=0>');
    document.writeln('    </FRAMESET>');
    document.writeln('      <FRAME NAME="mid_content" SRC="' + baseDir + 'shared/navigation/html/blank.html" MARGINWIDTH=0 MARGINHEIGHT=0 NORESIZE FRAMEBORDER=0>');
    document.writeln('  </FRAMESET>');
  }


  /* ------------------------------------ */
  /* construct HTML code for corner frame */
  /* ------------------------------------ */
  function buildCornerFrame()
  {
    corner.document.open();
    corner.document.clear();

    corner.document.writeln(CSSString);
    corner.document.writeln('  </HEAD>');
    corner.document.writeln();

    // calculate # of rows to space based on component inclusion
    numRows = 5;
    if(prevNextUsed) numRows+=1;
    if(tracksUsed) numRows+=3;

    corner.document.writeln('  <BODY BGCOLOR=E9E3D5 BACKGROUND="' + baseDir + 'shared/navigation/graphics/navBackground.jpg" BGPROPERTIES=FIXED>');
    corner.document.writeln('    <P>');
    corner.document.writeln('      <TABLE CELLSPACING=0 CELLPADDING=0 BORDER=0 WIDTH=' + componentWidth + '>');
    corner.document.writeln('      <TR><TD ROWSPAN=' + numRows + ' WIDTH=' + outerSpacing + '><IMG SRC="' + baseDir + 'shared/navigation/graphics/transparent.gif" WIDTH=' + outerSpacing + '></TD>');
    corner.document.writeln('        <TD COLSPAN=2 HEIGHT=' + outerSpacing + '></TD></TR>');
    corner.document.writeln('      <TR><TD ALIGN=LEFT COLSPAN=3><IMG SRC="' + baseDir + 'shared/navigation/graphics/smallLinksLogo.gif" ALIGN=LEFT VALIGN=TOP WIDTH=76 HEIGHT=35 HSPACE=0></TD></TR>');
    corner.document.writeln('        <TR><TD COLSPAN=3 HEIGHT=' + outerSpacing + '></TD></TR>');                      
    corner.document.writeln('        <TR><TD COLSPAN=3><P ALIGN="LEFT"><DIV CLASS="moduleTitle">' + moduleTitle + "</DIV></TD></TR>");

    // put space after title if either or both of the components are used.
    if(prevNextUsed||tracksUsed)
    corner.document.writeln('        <TR><TD COLSPAN=3 HEIGHT=' + outerSpacing*2 + '></TD></TR>');

    // next 2 'if' clauses control existance of prevNext & track buttons
    if(prevNextUsed)
    {
      // increment Track-button document base-index-# (to reference for changing
      // images) if 2 images for back/next control are included
      TButtonDocIndex+=3;
      corner.document.write('        <TR><TD ALIGN=LEFT><A' + linkMouseOverText('') + 'HREF="javascript:top.moveInSequence(-1);"><IMG SRC="' + prevNextGFX[0][0].src + '" ');
      corner.document.writeln('WIDTH=65 HEIGHT=21 BORDER=0 NAME="BACK"></A></TD>');
      corner.document.writeln('          <TD WIDTH=' + componentSpacing + '><IMG SRC="' + baseDir + 'shared/navigation/graphics/transparent.gif" WIDTH=' + componentSpacing + '></TD>');
      corner.document.write('            <TD ALIGN=RIGHT><A' + linkMouseOverText('') + 'HREF="javascript:top.moveInSequence(1);"><IMG SRC="' + prevNextGFX[1][0].src + '" ');
      corner.document.writeln('WIDTH=65 HEIGHT=21 BORDER=0 NAME="NEXT"></A></TD></TR>');
    }

    if(tracksUsed)
    {
      corner.document.writeln('        <TR><TD COLSPAN=3 HEIGHT=' + componentSpacing + '></TD></TR>');
      corner.document.writeln('        <TR><TD COLSPAN=3><DIV CLASS="title"><FONT COLOR=89827E>Tracks</FONT></TD></TR>');
      corner.document.writeln('        <TR>');
      // loops through & sets out each track button
      for(i=0; i<TSBIndex; i++)
      {
        corner.document.write('          <TD ALIGN=');
        // align graphics in cells as best as possible
        if(i==0) corner.document.write('LEFT');
        else if((i+1)==TSBIndex) corner.document.write('RIGHT');
        else corner.document.write('CENTER');
        corner.document.write('><A' + linkMouseOverText(tracksPre + trackStateMOText[i] + tracksPost) + 'HREF="javascript:top.changeTrack(' + (i+1) + ');">');
        corner.document.write('<IMG SRC="' + trackStateButtons[i][0].src + '" ');
        corner.document.writeln('BORDER=0></A></TD>');
        // insert spacing between buttons
        if(i+1!=TSBIndex)
          corner.document.writeln('          <TD WIDTH=' + componentSpacing + '><IMG SRC="' + baseDir + 'shared/navigation/graphics/transparent.gif" WIDTH=' + componentSpacing + '></TD>');
      }
      corner.document.writeln('        </TR>');
    }

    corner.document.writeln('      </TABLE>');
    corner.document.writeln('    </P>');
    corner.document.writeln('  </BODY>');
    corner.document.writeln('</HTML>');

    corner.document.close();
  }
  
  /* ------------------------------------------- */
  /* construct HTML code for side navigation bar */
  /* ------------------------------------------- */
  function buildSideFrame()
  {
    var whichClass, titleString;

    side_nav.document.open();
    side_nav.document.clear();

    side_nav.document.writeln('  <HEAD>');
    side_nav.document.writeln('    ' + CSSString);
    
    // must break up SCRIPT tag when writing into another document or the interpreter will think the tags
    // are applicable to this one
    side_nav.document.write('    <SCRI');
    side_nav.document.writeln('PT>');
    side_nav.document.writeln('    <!--');
    side_nav.document.writeln('    // variables for popUp window management');
    side_nav.document.writeln('      var win;');
    side_nav.document.writeln('      var winCount=0;');
    
    side_nav.document.writeln('      function popUp(URL)');
    side_nav.document.writeln('      { win = window.open(URL, ("WIN" + winCount++), "width=640,height=480");');
    side_nav.document.writeln('        win.focus(); }');
  
    side_nav.document.writeln('      function popUp(URL, width, height)');
    side_nav.document.writeln('      { win = window.open(URL, ("WIN" + winCount++), "width=" + width + ",height=" + height);');
    side_nav.document.writeln('        win.focus(); }');
    side_nav.document.writeln('    // -->');
    side_nav.document.write('    </SCRI');
    side_nav.document.writeln('PT>');

    side_nav.document.writeln('  </HEAD>');    

    side_nav.document.writeln('  <BODY BACKGROUND="' + baseDir + 'shared/navigation/graphics/navBackground.jpg" BGCOLOR=E9E3D5 BGPROPERTIES=FIXED>');

    side_nav.document.writeln('    <TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0><TR><TD WIDTH=' + outerSpacing + ' ROWSPAN=5><IMG SRC="' + baseDir + 'shared/navigation/graphics/transparent.gif" WIDTH=' + outerSpacing + '></TD><TD>');
    side_nav.document.writeln('      <TABLE WIDTH=' + componentWidth + ' CELLPADDING=3 CELLSPACING=0 BORDER=0 BGCOLOR="linen">');

    newDiv=true;

    /* loop to display side-nav bar titles */
    for(i=0; i<headerIndex; i++)
    {
      // ascertain which title mechanism is to be used
      // also determines whether or not closing mechanism is necessary
      if(headerArray[i].charAt(0)=="H") whichClass="title";          
        else whichClass="sub";

      // trim off "H" or "S" control character for output
      titleString=headerArray[i].substring(1, headerArray[i].length);

      side_nav.document.write('        <TR>');

      // include cell for bullet image (if 'bulletsUsed==true')
      if(bulletsUsed)
        side_nav.document.writeln('<TD WIDTH=9 VALIGN=CENTER ALIGN=RIGHT><IMG SRC="' + bulletOff.src + '" WIDTH=7 HEIGHT=11></TD>');

      side_nav.document.write('            <TD><DIV CLASS="' + whichClass + '">');

      // include <A> tag if the title is a link 
      if(headerLinksArray[i]!=null)
        {
          prelimLink = moduleBase + 'html/' + headerLinksArray[i]

          // if link is to a track page, make the HREF a call to the 'goTrackLink()' function
          j=prelimLink.indexOf(".html", 0);

          // rule out case for single digit # html files ("1.html" etc) so that system primer
          // doc's don't get put into 'goTrackLink()' functions.
          k = prelimLink.charAt(j-2);
          if(k!='/'&&k!='\\')
          {
            j=prelimLink.substring(j-1, j);         
            if(j>0&&j<10)
              prelimLink = "javascript:top.goTrackLink('" + prelimLink + "');";
          }

          // specify target (mid_content or new window)
          if(headerPopUpArray[i])
            targetString = 'TARGET="_"';                      
          else
            targetString = 'TARGET="mid_content"';
          
          side_nav.document.write('<A ' + targetString  + ' HREF="' + prelimLink + '">');
        }

      side_nav.document.write(titleString);

      // include </A> tag if the title is a link
      if(headerLinksArray[i]!=null)
        side_nav.document.write('</A>');
      
      side_nav.document.writeln('</DIV></TD></TR>');    
    }
    
    side_nav.document.writeln('      </TABLE></TD></TR>');
    side_nav.document.writeln('      <TR><TD HEIGHT=' + (outerSpacing*2) + '></TD></TR>');
    side_nav.document.writeln('      <TR><TD>');

    side_nav.document.writeln('      <TABLE WIDTH=' + componentWidth + ' BORDER=0 BORDERCOLOR=666699 CELLSPACING=0 CELLPADDING=1>');

    /* loop to construct the brick */    
    for(i=0; i<6; i++)
    {
      side_nav.document.write('        <TR><TD BGCOLOR=' + brickColor[i] + ' ALIGN=CENTER>');
      side_nav.document.writeln('<A TARGET="' + brickTarget[i] + '"' + linkMouseOverText(brickLinkText[i]) + 'HREF="' + brickHREF[i] + '">');

      if(i<4)
        side_nav.document.write('          <FONT FACE="Verdana, Arial, Helvetica, sans-serif" SIZE=-1 COLOR=FFFFFF>');
      else
        side_nav.document.write('          <FONT FACE="Verdana, Arial, Helvetica, sans-serif" SIZE=-1>');

      side_nav.document.writeln('<STRONG>' + brickTitle[i] + '</STRONG></A>');
      side_nav.document.writeln('          </FONT></TD></TR>');
    }

    side_nav.document.writeln('      </TABLE></TD></TR>');
    side_nav.document.writeln('      <TR><TD HEIGHT=' + outerSpacing + '></TD></TR>');
    side_nav.document.writeln('      <TR><TD>');
    
    /* copyright notice HTML */
    side_nav.document.writeln('    <P ALIGN=CENTER><FONT COLOR=000000 SIZE=-2>');
        side_nav.document.writeln('      Copyright © ' + copyrightYear + '<BR>');
        side_nav.document.writeln('      Rensselaer Polytechnic Institute.<BR>');
        side_nav.document.writeln('      All Rights Reserved. ');
	side_nav.document.writeln
	  ('<applet width="4" height="4" mayscript="true"' +
	   ' code="links.applet.dispatcher.SwingJmfDispatcher"' +
	   ' archive="' + module_root() +
	   'shared/code/links/dispatcher.jar,' +
	   module_root() + 'shared/code/links/appletstuff.jar"' +
	   ' name="swingjmfdispatcher">');
	side_nav.document.writeln('<param name="bgcolor" value="#E9E3D5">');
	side_nav.document.writeln('</applet>');

	side_nav.document.writeln('</FONT></TD></TR></TABLE>');
        side_nav.document.writeln('  </BODY>');
        side_nav.document.writeln('</HTML>');

    side_nav.document.close();
  }
//-------------------------------------------------------------------------------------
  
  
  
  
//---------------------------------------------------------------------------------------------
// (5) Update navigation on EVERY SINGLE CONTENT PAGE LOAD into the "mid_content" frame
//---------------------------------------------------------------------------------------------

  function updateNavigation(contentPageURL)
  {
    // skip this function if neither component is present
    if(!(tracksUsed||prevNextUsed||bulletsUsed)) return;
    
    // strip filename from argument
    contentPageURL = pageName(contentPageURL);
    
    /*------------------------------*/
    /* update previous/next buttons */
    /*------------------------------*/
    
    if(prevNextUsed)
    {
      var pageIndex=-1;      

      // determine which page (in the index) we're on.
      for (i=0; i<pageSequenceArray.length; i++)
        if (pageSequenceArray[i]==contentPageURL) { pageIndex=i; break; }
        
      // set button states accordingly; if pageIndex = -1 (page not found) both buttons are greyed out.
      if(pageIndex==0||pageIndex==-1) corner.document.BACK.src=prevNextGFX[0][0].src; 
        else corner.document.BACK.src=prevNextGFX[0][1].src;
      if(pageIndex>=(pageSequenceArray.length-1)||pageIndex==-1) corner.document.NEXT.src=prevNextGFX[1][0].src; 
        else corner.document.NEXT.src=prevNextGFX[1][1].src;
    }

    /*----------------*/
    /* update bullets */                                   
    /*----------------*/
    if(bulletsUsed)
    {

      // get the title from the current page & rip the header (part before the "_") from it
      dummyString = pageName(mid_content.document.location.href);
      dummyString = titleRip(dummyString);      

      // iterate through all bullets & set states accordingly
      for(i=0; i<headerLinksArray.length; i++)
      {
        // test for equivalent titles & set hi-lited bullet if true, washed button if false. 
        if(headerLinksArray[i]!=null)
        {
          if(dummyString==titleRip(headerLinksArray[i]))
            side_nav.document.images[bulletStartIndex + i].src = bulletOn.src;
          else side_nav.document.images[bulletStartIndex + i].src = bulletOff.src;
        }
        else side_nav.document.images[bulletStartIndex + i].src = bulletOff.src;
      }
    }

    
    /* --------------------------update tracks--------------------------- */
    /* WATCH OUT! the track updating 'if' block has 'return' calls in it! */
    /* Make sure it's the last check in the 'updateNavigation()' function */
    /* ------------------------------------------------------------------ */
    if(tracksUsed)
    {    

      // get indexes of position in track array
      k = trackIndex(contentPageURL);

      // case where page is not in tracks -- grey out all links
      if(k==-1)
      {
        for(j=0; j<trackArray.length; j++)
          corner.document.images[TButtonDocIndex+(j*2)].src = trackStateButtons[j][0].src;
        return;
      }

      // strip the 2 index numbers from the return argument for the trackIndex (find) call 
      pageIndex=k.substring(0, k.indexOf(","));
      trIndex=k.substring(k.indexOf(",") + 1, k.length);

      // determine if the current page is a track page, and if so: what is its index?
      trIndex = isTrackPage(trackArray[trIndex][pageIndex]);

      // case where page is in tracks, but is not a track -- grey out all links
      if(trIndex==-1) 
      {
        for(j=0; j<trackArray.length; j++)        
          corner.document.images[TButtonDocIndex+(j*2)].src = trackStateButtons[j][0].src;
        return;
      }      

      // We'll cycle 'j' through all possible tracks for 'pageIndex'
      // set all buttons: active, enabled, or disabled. (done left to right)       
      for(j=0; j<trackArray.length; j++)
      {
        if((j+1)==trIndex) 
          corner.document.images[TButtonDocIndex+(j*2)].src = trackStateButtons[j][2].src; // active
        else if(trackArray[j][pageIndex]!=null)
          corner.document.images[TButtonDocIndex+(j*2)].src = trackStateButtons[j][1].src; // enabled 
        else corner.document.images[TButtonDocIndex+(j*2)].src = trackStateButtons[j][0].src; // disabled 
      }

    }

  }
//-------------------------------------------------------------------------------------

  
  
  
//-------------------------------------------------------------------------------------
// (6) Navigation functions (changing tracks and prevNext button handlers)
//-------------------------------------------------------------------------------------  

  function moveInSequence(relToIndex)
  {
    // strip filename from current HREF
    contentPageURL = pageName(mid_content.document.location.href);
    pageIndex=-1;

    // determine which page (in the index) we're on.
    for (i=0; i<pageSequenceArray.length; i++)
      if (pageSequenceArray[i]==contentPageURL) { pageIndex=i; break; }

    // return if the page is not found in our listing
    if(pageIndex==-1) return;

    currentPage=pageIndex;

    // add the offset and perform bounds checking.
    pageIndex+=relToIndex;
    if(pageIndex<0) pageIndex=0;
    else if(pageIndex>=pageSequenceArray.length) pageIndex=pageSequenceArray.length-1;            

    // if the pageSequenceArray exists, and the current page != the new page (b/c of bounds checking): then change the page.
    changePage(moduleBase + "html/" + pageSequenceArray[pageIndex]);
  }

  function changeTrack(trackNumber)
  {
    currentPage = pageName(mid_content.document.location.href);

    // find location of page in array: return if not found in array.
    k = trackIndex(currentPage);  
    if(k==-1) return;

    // strip the 2 index numbers from the return argument for the trackIndex (find) call 
      pageIndex=k.substring(0, k.indexOf(","));
      trIndex=k.substring(k.indexOf(",") + 1, k.length);

    // determine whether or not this is a track page: return if it's not or if we're
    // already on the page we want to be on.
    k = isTrackPage(currentPage);
    if(k==-1) return;

    // make sure page exists, then switch it
    if(trackArray[trackNumber-1][pageIndex]!=null)
      changePage(moduleBase + "html/" + trackArray[trackNumber-1][pageIndex]);
  }

  function goTrackLink(defaultURL)
  {
    currentPage = pageName(mid_content.document.location.href);
    k = isTrackPage(currentPage);
    // if user is not currently on a track page, put default page in mid_content frame
    if(k==-1)
      {
        changePage(defaultURL);
        return;
      }
    
    j=currentPage.indexOf(".html", 0);
    j=currentPage.substring(j-1, j);         

    // construct new URL & change mid_content pane to it
    changePage(defaultURL.substring(0, defaultURL.indexOf(".html")-1) + j + defaultURL.substring(defaultURL.indexOf(".html"), defaultURL.length));
  }
//-------------------------------------------------------------------------------------
  

  

//----------------------------------------------------------------------
// (7) Helper functions
//----------------------------------------------------------------------

  // returns the index numbers (delimited by a comma) of the 2 indexes in the 2D array of the
  // page specified in the 'URLtoFind' argument.  Returns '-1' if the specified page is not found. 
  function trackIndex(URLtoFind)
  {
    for(i=0; i<trackArray.length; i++)
      for(j=0; j<trackArray[i].length; j++)
          if(trackArray[i][j]==URLtoFind)
            return (j + "," + i);       
    // case if not found in array
    return(-1);            
  }


  // strip filename from given HREF  
  function pageName(HREF)
  {
    return (HREF.substring((HREF.indexOf("/html/") + 6), HREF.length));    
  }


  // test filename for track number.  Return '-1' if not found
  function isTrackPage(fileName)
  {
    k = fileName.substring(fileName.indexOf(".html")-1, fileName.indexOf(".html"));

    // if k is an integer (1 through 9: we do NOT include 0) return the index number
    // Otherwise we assume the last character to be text, indicating a non-track page.
    if(k>0&&k<10)
      return(k);
    else return(-1);
  }

  // returns tags for inside the <A> tag (onMouseOver & onMouseOut) to display textToInsert in the status bar
  function linkMouseOverText(textToInsert)
  {
    dummyString = ' onMouseOver="javascript:status=\'' + textToInsert + '\'; return true;"';
    dummyString+= ' onMouseOut="javascript:status=\'\'; return true;" ';
    return(dummyString);
  }

  // change content page (perform check to see if it's a new page before doing so)
  function changePage(URL)
  {
    if(mid_content.document.location!=URL)
      mid_content.document.location = URL;
  }
  
  // return the string up to (not including) the "_" in the filename
  // if "_" not found return the whole string up to the "."
  function titleRip(pageName)
  {
   if(pageName.indexOf("_")>=0)
     return(pageName.substring(0, pageName.indexOf("_")));
   else return(pageName.substring(0, pageName.indexOf(".")));
  }

//-------------------------------------------------------------------------------------
  

  
  
//-------------------------------------------------------------------
// (8) Global variable declarations &
//     Preliminary (setup) execution (browser check, style sheet look-up)
//-------------------------------------------------------------------

  //////////////////////////////////
  //  START Set-up function calls  

  // utility variables
    var h, i, j, k;
    var dummyString;
    var numRows;

    var module_root_search_string = "modules";  
    var module_root_string = null;
    var baseDir, moduleBase;

  // style-sheet finder variables
    var whatStyle = "navstyle";
    var CSSString;

  // ensure browser version # is valid
    checkBrowser();


  // find "/devmodules/" directory
    baseDir = module_root();
    whatStyle = getStyle();

  // build style sheet reference string for use in corner & side_nav frames
    CSSString = '<LINK REL=StyleSheet HREF="' + baseDir + 'shared/navigation/style/' + whatStyle + '.css" TYPE="text/css">';

  
  // get module base (directory string (including "/") of module)
    moduleBase=top.document.location.href;
    moduleBase=moduleBase.substring(0, moduleBase.lastIndexOf("/") + 1);

  // END Set-up function calls
  ////////////////////////////////// 


  ///////////////////////////////////////////////////////////////////////////////////////
  // START variable declarations

  /* set default values for control variables & module title */
    var tracksUsed = false;
    var prevNextUsed = false;
    var bulletsUsed = false;
    var moduleTitle = "MODULE NAME";
    var copyrightYear = "XXXX";

  /* set default track-control variables */
    var currentTrack = 1;
    var TButtonDocIndex = 2;

  /* set up array for use in storing headers & their links.  also initialize counter variables for them */
    var headerArray = new Array();
    var headerLinksArray = new Array();
    var headerPopUpArray = new Array();
    var targetString;
    var headerIndex = 0;
    var newDiv = true;
    var prelimLink;
      
  /* prevNext button graphic storage */
    var prevNextGFX = new Array();

  /* trackArray variable declarations */
    var trackArray;
    var trackStateButtons = new Array();
    var trackStateMOText = new Array();
    var TSBIndex = 0;
    var pageIndex, trIndex;
    var currentTrack = 1;

    var contentPageURL;
    
  // set paths of graphics to use for prevNext buttons
    prevNextGFX[0] = new Array();
    prevNextGFX[1] = new Array();

    prevNextGFX[0][0] = new Image();
    prevNextGFX[0][0].src = baseDir + "shared/navigation/graphics/priorButtonInactive.gif";
    prevNextGFX[0][1] = new Image();
    prevNextGFX[0][1].src = baseDir + "shared/navigation/graphics/priorButton.gif";
    prevNextGFX[1][0] = new Image();
    prevNextGFX[1][0].src = baseDir + "shared/navigation/graphics/nextButtonInactive.gif";
    prevNextGFX[1][1] = new Image();
    prevNextGFX[1][1].src = baseDir + "shared/navigation/graphics/nextButton.gif";
        
    /* declare brick parameters */
    /* controls coloring, titles, status-bar text, HREF's, and page targets for the infamous "brick" */
    var brickColor = new Array("666699", "7777AA", "8888BB", "9999CC", "AAAADD", "BBBBEE");
    var brickTitle = new Array("CRIB SHEET", "LIBRARY", "HELP", "MAP", "MODULE HOME", "LINKS HOME");
    var brickLinkText = new Array("view the crib sheet", "visit the module library", "get help on using Links modules", "view the module map",
                                  "return to the beginning of the module", "go to the project Links home page");
    var brickHREF = new Array(moduleBase + "html/crib.html", moduleBase + "html/library.html", baseDir + "shared/html/help.html", 
                              moduleBase + "html/map.html", moduleBase + "index.html", baseDir + "../../index.html");
    var brickTarget = new Array("mid_content", "mid_content", "mid_content", "mid_content", "_top", "_top"); 

  /* Track status-bar string pieces */ 
    var tracksPre = "switch to the ";
    var tracksPost = " track";
   
 /* bullet graphics control */
    var bulletOff = new Image;
    bulletOff.src = baseDir + "shared/navigation/graphics/transparent.gif";
    var bulletOn = new Image;
    bulletOn.src = baseDir + "shared/navigation/graphics/sideNavArrow2.gif";

    var bulletStartIndex = 1;

  /* set width of brick, table of contents, and prevNext/tracks components (in pixels) */
    var componentWidth = 135;
  /* size (in pixels) of space between components and frame border and space between track & prevNext components */
    var outerSpacing = 10;
    var componentSpacing = 4;
  
  // END Variable declarations
  ///////////////////////////////////////////////////////////////////////////////////////

  
///////////////////
//  END OF FILE  //
///////////////////
