
  var aBackgroundColor = "#f4f4ff";
  var aSelectColor = "#ccffcc";
  var dBackgroundColor = "#fff4f4";
  var dSelectColor = "#ccccff";
  var dSelectColorSpouse = "#e8e8ff";
  var ancestorNav = new Object();
   ancestorNav.curN = 0;
   ancestorNav.curA = null;
  var descendantNav = new Object();
   descendantNav.curId = 'D';
   descendantNav.curD = null;

      function resizeOutputBox()
      {
        var outputBoxElem = document.getElementById('outBox');
        var outputBoxTop = outputBoxElem.offsetTop;
        var totalHeight = document.body.clientHeight;
        outputBoxHeight = String(Math.floor(0.95*(totalHeight - outputBoxTop)));
        outputBoxElem.style.height = outputBoxHeight + 'px';
      }

     function populateSurnames()
      {
         objXSLTProc.addParameter('param1', 'surnames');
         objXSLTProc.addParameter('param2', '');
         objXSLTProc.transform();
         var thisSlot = document.getElementById('selectS');
         thisSlot.innerHTML = objXSLTProc.output;
         mySelectS = thisSlot.firstChild;
         mySelectS.id = "surnameSelect";
         mySelectS.onkeypress =  comboSelect;
         mySelectS.selectedIndex = 0;
         while ((mySelectS.value.indexOf('?')>=0) && (mySelectS.selectedIndex < (mySelectS.length - 1)))
          { mySelectS.selectedIndex++; }
         mySelectS.style.color = "#990000";
      }  
 
     function populateNames(thisSurname)
       {
         objXSLTProc.addParameter("param1", 'givennames');
         objXSLTProc.addParameter("param2", thisSurname);
         objXSLTProc.transform();
         var thisSlot = document.getElementById('selectG');
         thisSlot.innerHTML = objXSLTProc.output;
         mySelectG = thisSlot.firstChild;
         mySelectG.id = "givensSelect";  // needed to insure id is set properly
         mySelectG.onkeypress = comboSelect;
         mySelectG.selectedIndex = 0;
         var thisText = mySelectG.options[0].text;
         while (((thisText.indexOf('?')>=0) || (thisText.indexOf('[')>=0))
                  && (mySelectG.selectedIndex < (mySelectG.length - 1)))
         { 
            mySelectG.selectedIndex++;
            thisText = mySelectG.options[mySelectG.selectedIndex].text;
         }
         mySelectG.focus();
       } 
 
     function alignFocusById(thisId)
     {
        objXSLTProc.addParameter('param1', 'surnameById');
        objXSLTProc.addParameter('param2', thisId);
        objXSLTProc.transform();

        var thisSurname = objXSLTProc.output;
        var currentPermitRefocus = permitRefocus;
        permitRefocus = false;
        var i = 0;
        while ((i < mySelectS.options.length) && (mySelectS.options[i].value != thisSurname))
          { ++i; }
        if (i == mySelectS.options.length) { alert('system error 1'); i = 0; }
        mySelectS.selectedIndex = i;
        populateNames(thisSurname);
        permitRefocus = currentPermitRefocus;
        var j = 0;
        while ((j < mySelectG.options.length) && (mySelectG.options[j].value != thisId))
          { j++; }
        if (j == mySelectG.options.length) { alert('system error 2'); j = 0; }
        mySelectG.selectedIndex = j;
        refocusSelect(); 
     }

 
     function alignFocus(s,g, i)
     {
         if (permitRefocus)
         {
           document.getElementById('focusSurname').innerHTML = s;
           document.getElementById('focusGivens').innerHTML = g;
           mySelectV.selectedIndex = document.getElementById('familyOption').index;
           if (!blockHistory) { myHistory.addNew(i) };
           refreshHistory();
           redisplay();
         }
      } 

     function focusBack()
     {
       myHistory.point--;
       blockHistory = true;
       alignFocusById(myHistory.current());
       blockHistory = false;
     }

     function focusForward()
     {
       myHistory.point++;
       blockHistory = true;
       alignFocusById(myHistory.current());
       blockHistory = false;
     }

     function refreshHistory()
     {
       if (myHistory.point <= 0) { document.getElementById('backButton').disabled = true; }
       else { document.getElementById('backButton').disabled = false; }
       if (myHistory.point >= (myHistory.length - 1)) { document.getElementById('forwardButton').disabled = true; }
       else { document.getElementById('forwardButton').disabled = false; }
     }

     function refocusSelect()
     {
        var j = mySelectG.selectedIndex;
        var i = mySelectS.selectedIndex;
        alignFocus(mySelectS.options[i].value, mySelectG.options[j].text, mySelectG.value); 
     }
       
     function clickAlign(myId, Ev)
     {
// line 132
       evt = (Ev)?Ev:window.event;
       if (evt.altKey)
       {
         var thisCaller = (evt.srcElement)?evt.srcElement:evt.target;
         switch(mySelectV.value)
         {
          case 'descendants':
           resetIdDnav(thisCaller.parentNode.getAttribute('id'));
           break;
          case 'ancestors':
           var fullId = thisCaller.parentNode.getAttribute('id');
           var newAnavNum = Number(fullId.substring(1));
           resetAnav(newAnavNum);
           break;
          default:
           alignFocusById(myId);
           break;
         }
       }
       else { alignFocusById(myId); }
     }

     function redisplay()
     {
        objXSLTProc.addParameter("param1", mySelectV.value);
        objXSLTProc.addParameter("param2", mySelectG.value);
        objXSLTProc.transform();
      

/*
if (mySelectV.value == 'descendants')
{
  asis.innerText = objXSLTProc.output;
  throw "tpg";
}
*/
// line 141
        output.innerHTML = objXSLTProc.output;
        document.getElementById('bNavs').style.visibility = 'hidden';
        document.getElementById('aNavs').style.visibility = 'hidden';
        document.getElementById('dNavs').style.visibility = 'hidden';
        switch(mySelectV.value)
        {
          case 'ancestors':
           var aRoot = document.getElementById("A000001");
           aRoot.firstChild.onclick = null;
           document.getElementById('aNavs').style.visibility = 'visible';
           ancestorNav.curA = null;
           resetAnav(1);
           break;
          case 'descendants':
           var dRoot = document.getElementById("D00");
           dRoot.firstChild.onclick = null;
           document.getElementById('dNavs').style.visibility = 'visible';
           descendantNav.curD = null;
           resetIdDnav('D00');
           break;
          case 'family':
           document.getElementById('bNavs').style.visibility = 'visible';
           break;

         }
      }



/* *******************
 * The function comboSelect can be attached to any Select element as its onKeyPress attribute by 
 * onKeyPress="return comboSelect();"  The function compares a sequence of keyed values with the
 * text displayed in the Select's Options and selects the last option that is <= the keyed sequence.
 * If the Select element has an associated onChange event, it is fired.
 *
 * The comparisons are case insensitive.  Note that any text up to an including the first occurance
 * of an ',' in the Option, if any, is disregarded as not being relevant to the comparison.  Further,
 * it is assumed that the Options are ordered by the relevant sections of their text.
 * Key presses within 1.0 seconds are appended to the prior sequence, while those later start a new 
 * sequence.  
 */
     function comboSelect(evt)
     {
       if (evt) { return true; }
       thisEvt = window.event;
       thisSel = thisEvt.srcElement;
       if (!(thisSel.delay))
       {
         thisSel.bestI = 0;
         thisSel.accumString = '';
         thisSel.delay = 1000;
         thisSel.timeout = null;
         thisSel.stuck =  false;
         thisSel.oldIndex = 0;  
         thisSel.resetWait = 
            function() { thisSel.focus();
                         thisSel.selectedIndex = thisSel.bestI; 
                         thisSel.accumString = ''; 
                         thisSel.bestI = 0; 
                         thisSel.stuck = false;
                         if (thisSel.onchange && (thisSel.selectedIndex != thisSel.oldIndex)) { thisSel.onchange(); }
                       };
       } 
	 else { window.clearTimeout(thisSel.timeout); }

       if (thisSel.stuck)
       { 
         thisSel.timeout = setTimeout("thisSel.resetWait()", thisSel.delay); 
         thisEvt.cancelBubble = true;
         thisEvt.returnValue = false; 
         return false;  
       }

       var thisKeyCode = thisEvt.keyCode;
       if ((thisKeyCode < 32) || (thisKeyCode > 127))
       {
         thisEvt.cancelBubble = true; 
         return true;  
       }
       if (thisSel.accumString == '') { thisSel.oldIndex = thisSel.selectedIndex; }
       var newChar = String.fromCharCode(thisKeyCode).toUpperCase();
       thisSel.accumString += newChar;

       var okToHere = true;
       var txtSoFar; 
       for (var i = thisSel.bestI; (i < thisSel.length) && okToHere; i++)
       {   
         var work = thisSel.options[i].text;
         var firstN = work.indexOf(',');
         firstN = (firstN >= 0)?(firstN + 2):0;
         txtSoFar = work.substr(firstN, thisSel.accumString.length).toUpperCase();
         okToHere = ((thisSel.accumString > txtSoFar) ||
                     (txtSoFar.indexOf('[') >= 0)); //  for sort order incompatibility
       }
       thisSel.bestI = Math.max(i-1, 0);
       if ((thisSel.bestI == (thisSel.length - 1)) || (txtSoFar != thisSel.accumString))
       { 
         thisSel.stuck = true;
         thisSel.bestI = Math.max(thisSel.bestI - 1, 0);
         thisSel.timeout = setTimeout("thisSel.resetWait()", thisSel.delay); 
       }
       else
       { 
         thisSel.focus();
         thisSel.selectedIndex = thisSel.bestI; 
         thisSel.timeout = setTimeout("thisSel.resetWait()", thisSel.delay); 
       }
       thisEvt.cancelBubble = true;
       thisEvt.returnValue = false; 
       return false;  
     }

/*
 *  ************ aNav support functions ********
 */
     function anavToNum(a)
     {
       return Number(a.substr(1, a.length - 1));
     }

     function numToAnav(n)
     {
       var work = String(n);
       while (work.length < 6) { work = '0' + work; }
       return ('A' + work);
     }  
// line 296
     function resetAnav(n)
     {
       if (ancestorNav.curA) { ancestorNav.curA.style.backgroundColor = aBackgroundColor; }
       ancestorNav.curN = n;
       ancestorNav.curA = document.getElementById(numToAnav(n));
       ancestorNav.curA.style.backgroundColor = aSelectColor;
       var relSpan = document.getElementById('aNavRel');
       if (n == 1)
       { 
         document.getElementById('aChildButton').disabled = true;
         document.getElementById('aRefocusButton').disabled = true; 
         document.getElementById('aSpouseButton').disabled = true;
         document.getElementById('aRootButton').disabled = true;
         relSpan.innerHTML = 'self';
       }
       else 
       { 
         document.getElementById('aChildButton').disabled = false;
         document.getElementById('aRefocusButton').disabled = false;
         document.getElementById('aRootButton').disabled = false;
         var thisSpouseId = numToAnav(n + (((n % 2) == 0)? 1: -1) ); 
         document.getElementById('aSpouseButton').disabled
                       = !(document.getElementById(thisSpouseId));
         var relCount = Math.floor(Math.log(n)/Math.LN2);
         switch (relCount)
         {
          case 1:
           relSpan.innerHTML = 'parent';
           break;
          case 2:
           relSpan.innerHTML = 'grandpar.';
           break;
          case 3:
           relSpan.innerHTML = 'Ggrandpar.';
           break;
          default:
           relSpan.innerHTML = '(' + String(relCount-2) + ')Ggrandpar.';
           break;
          }
       }
       document.getElementById('aFatherButton').disabled 
                         = !(document.getElementById(numToAnav(2*n)));
       document.getElementById('aMotherButton').disabled 
                         = !(document.getElementById(numToAnav(2*n + 1)));
       ancestorNav.curA.scrollIntoView();
     }

     function rootAnav()
     { resetAnav(1); }

     function fatherAnav()
     { resetAnav(2*ancestorNav.curN); }

     function motherAnav()
     { resetAnav(2*ancestorNav.curN + 1); }

     function childAnav()
     { resetAnav(Math.floor(ancestorNav.curN/2)); }

     function spouseAnav()
     {
       var del = ((ancestorNav.curN % 2) == 0)? 1: -1;
       resetAnav(ancestorNav.curN + del);
     }

     function refocusAnav()
     { ancestorNav.curA.firstChild.click(); }

/*
 *  ************* dNav support functions **************
 */
// line 314
   function elemToIdDnav(x)
   { 
     if (x) { return x.getAttribute('id'); }
     else { return descendantNav.curD.getAttribute('id'); }
   }

   function stubDnav()
   {
     var work = descendantNav.curId;
     var len = work.length;
     return (work.substr(0, len - 2));
   }

   function extDnav()
   {
     var work = descendantNav.curId;
     var len = work.length;
     return (work.substring(len - 2));
   }

   function atSpouseDnav()
   {
     if (atRootDnav()) { return false; }
     var work = descendantNav.curId;
     var len = work.length;
     return (work.charAt(len-2) == 's');
   }

   function atRootDnav()
   {  return (descendantNav.curId == 'D00'); }  
// line 345
   function parentElemDnav()
   {  
     if (atRootDnav() || atSpouseDnav()) { return null; }
     var work = descendantNav.curId;
     var len = work.length;
     return (document.getElementById(work.substr(0, len-2)));
   }

   function spouseElemDnav()
   {
     var work = descendantNav.curId;
     var len = work.length;
     if (atSpouseDnav()) { return (document.getElementById(work.substr(0, len-2))); }
     return (document.getElementById(work + 's1')); 
   }
// line 370
   function nextCoSpouseElemDnav()
   {
     if (!atSpouseDnav()) { return null }
     var work = descendantNav.curId;
     var len = work.length;
     var thisId = stubDnav() + 's' + String(Number(work.charAt(len-1)) + 1);
     return (document.getElementById(thisId));
   }

   function prevCoSpouseElemDnav()
   {
     if (!atSpouseDnav() || (extDnav() == 'a')) { return null }
     var work = descendantNav.curId;
     var len = work.length;
     var thisId = stubDnav() + 's' + String(Number(work.charAt(len-1)) - 1);
     return (document.getElementById(thisId));
   }

   function nextSibElemDnav()
   {
     if (atRootDnav() || atSpouseDnav()) { return null };
     var len = descendantNav.curId.length;
     var sibNum = String(Number(descendantNav.curId.substring(len-2)) + 1);
     while (sibNum.length < 2) { sibNum = '0' + sibNum; }
     var thisId = (stubDnav() + sibNum);
     return (document.getElementById(thisId));
   }
// line 397
   function prevSibElemDnav()
   {
     if (atRootDnav() || atSpouseDnav() || (extDnav() == 'A')) { return null; }
     var len = descendantNav.curId.length;
     var sibNum = String(Number(descendantNav.curId.substring(len-2)) - 1);
     while (sibNum.length < 2) { sibNum = '0' + sibNum; }
     var thisId = (stubDnav() + sibNum);
     return (document.getElementById(thisId));
   }
// line 406          
   function childElemDnav()
   {
     var work = descendantNav.curId;
     var len = work.length;
     var thatId;
     if (atSpouseDnav())
     { thatId = descendantNav.curD.nextSibling.innerHTML; }
     else
     { thatId = work + '01'; }
     return (document.getElementById(thatId));
   }
// line 421
   function oParentElemDnav()
   {
     if (atSpouseDnav() || atRootDnav()) { return null; }
     var thatId = descendantNav.curD.nextSibling.innerHTML;
     if (thatId != '*') { return (document.getElementById(thatId)); }
     else { return null; }
   }

   function resetDnav()
   {
     descendantNav.curD.style.backgroundColor = atSpouseDnav()?dSelectColorSpouse:dSelectColor;
//     descendantNav.curD.style.backgroundColor = dSelectColor;
     document.getElementById('dRefocusButton').disabled = atRootDnav();
     document.getElementById('dRootButton').disabled = atRootDnav();
     document.getElementById('dChildButton').disabled = !(childElemDnav());
     document.getElementById('dParentButton').disabled = !(parentElemDnav());
     document.getElementById('dOtherParentButton').disabled = !(oParentElemDnav());
     document.getElementById('dSpouseButton').disabled = !(spouseElemDnav());
     document.getElementById('dSibNextButton').disabled = !(nextSibElemDnav());
     document.getElementById('dSibPrevButton').disabled = !(prevSibElemDnav());
     document.getElementById('dCoSpouseNextButton').disabled = !(nextCoSpouseElemDnav());
     document.getElementById('dCoSpousePrevButton').disabled = !(prevCoSpouseElemDnav());
     descendantNav.curD.scrollIntoView();
     var dCount = (descendantNav.curId.length - 1)/2;
     if (atSpouseDnav()) { dCount = dCount - 1; }
     var gc;
     switch (dCount)
     {
       case 1:
        gc = 'self';
        break;
       case 2:
        gc = 'child';
        break;
       case 3:
        gc = 'gchild';
        break
       case 4:
        gc = 'Ggchild';
        break;
       default:
        gc = '(' + String(dCount-3) + ')Ggchild';
        break;
     }
     if (atSpouseDnav()) { gc = 'sp-' + gc; }
     document.getElementById('dNavRel').innerHTML = gc;
   }

   function resetIdDnav(newId)
   {
     if (descendantNav.curD) { descendantNav.curD.style.backgroundColor = dBackgroundColor; }
     descendantNav.curId = newId;
     descendantNav.curD = document.getElementById(newId);
     resetDnav();
   }

   function resetElemDnav(newElem)
   {
     if (descendantNav.curD) { descendantNav.curD.style.backgroundColor = dBackgroundColor; }
     descendantNav.curD = newElem;
     descendantNav.curId = elemToIdDnav();
     resetDnav();
   }    

   function refocusDnav()
   { descendantNav.curD.firstChild.click(); }

   function rootDnav()
   { resetIdDnav('D00'); }

   function childDnav()
   {  resetElemDnav(childElemDnav()); }

   function parentDnav()
   {  resetElemDnav(parentElemDnav()); }
   
   function spouseDnav()
   {  resetElemDnav(spouseElemDnav()); }

   function sibNextDnav()
   {  resetElemDnav(nextSibElemDnav()); }

   function sibPrevDnav()
   {  resetElemDnav(prevSibElemDnav()); }

   function coSpouseNextDnav()
   {  resetElemDnav(nextCoSpouseElemDnav()); }

   function coSpousePrevDnav()
   {  resetElemDnav(prevCoSpouseElemDnav()); }

   function oParentDnav()
   {  resetElemDnav(oParentElemDnav()); }
     