//alert('protoA');

/*  HTML colors for views  */
  var aBackgroundColor = "#e0ffe0";
  var aSelectColor = "#bbffbb";
  var dBackgroundColor = "#e0e0ff";
  var dSelectColor = "#bbbbff";
  var dSelectColorSpouse = "#bbbbff";

/*  object that governs navigation in ancestor view  */
  var ancestorNav = new Object();
   ancestorNav.curN = 0;
   ancestorNav.curA = null;

/*  object that governs navigation in descendant view  */
  var descendantNav = new Object();
   descendantNav.curId = 'D';
   descendantNav.curD = null;

/*  resizes view output-area to fill bottom of screen  */
  function resizeOutputBox() {
    var outputBoxElem = document.getElementById('outBox');
    var outputBoxTop = outputBoxElem.offsetTop + outputBoxElem.offsetParent.offsetParent.offsetTop;
    var totalHeight = document.body.clientHeight;
    outputBoxHeight = String(Math.floor(0.95*(totalHeight - outputBoxTop)));
    outputBoxElem.style.height = outputBoxHeight + 'px';
    }

/*  fills Surname Select element  */
  function populateSurnames() {
    for(var i=0; i < surnameTbl.length; i++) {
       var newOption = document.createElement("OPTION");
       newOption.setAttribute("value", i);
       newOption.text = surnameTbl[i].surname;
       mySelectS.add(newOption, (navigator.appName.indexOf("Microsoft") != -1)?-1:null);
       }
    mySelectS.selectedIndex = 0;

  /*  advances selection to first non-? entry  */
    var thisText = mySelectS.options[0].text;
    while ((thisText.indexOf('?')>=0) && (mySelectS.selectedIndex < mySelectS.length - 1)) {
       mySelectS.selectedIndex++; 
       thisText = mySelectS.options[mySelectS.selectedIndex].text;
       }
    mySelectS.style.color = "#990000";

  /*  unlocks 'reFocus' button  */
    document.getElementById('selectRefocus').disabled = false;
    }  


   /*  fills given-names Select element  */
     function populateNames(thisJ)  {
         var theseGivens = surnameTbl[thisJ].givenTbl;
         mySelectG.options.length = 0;
         for(var j = 0; j < theseGivens.length; j++)  {
            var newOption = document.createElement("OPTION");
            newOption.setAttribute("value", theseGivens[j].indivId);
            newOption.text = theseGivens[j].displayName;
            mySelectG.add(newOption, (navigator.appName.indexOf("Microsoft") != -1)?-1:null);
            }
         mySelectG.selectedIndex = 0;

       /*   advances selection to first non-? entry  */
         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();

       /*  unlocks 'reFocus' button  */
         document.getElementById('selectRefocus').disabled = false;
       } 



/* *******************
 * 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 2.0 seconds are appended to the prior sequence, while those later start a new 
 * sequence.  
 */
     function comboSelect(evt)
     {
//       if (evt) { return true; }
       thisEvt = (evt)?evt:window.event;
//       thisEvt = window.event;
       thisSel = (thisEvt.srcElement)?thisEvt.srcElement:thisEvt.target;
       if (!(thisSel.delay))
       {
         thisSel.bestI = 0;
         thisSel.accumString = '';
         thisSel.delay = 2000;
         thisSel.timeout = null;
         thisSel.stuck =  false;
         thisSel.resetWait = 
            function() { thisSel.focus();
                         thisSel.selectedIndex = thisSel.bestI; 
                         thisSel.accumString = ''; 
                         thisSel.bestI = 0; 
                         thisSel.stuck = false;
                         if (thisSel.onchange) { 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.charCode)?thisEvt.charCode:thisEvt.keyCode;
       if ((thisKeyCode < 32) || (thisKeyCode > 127))
       {
         thisEvt.cancelBubble = true; 
         return true;  
       }
       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, 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;
       if (thisEvt.returnValue) {
             thisEvt.returnValue = false;
          } else if (thisEvt.preventDefault) {
             thisEvt.preventDefault();
             return false;
          } else { 
             return false;  
          }
     }

//  *********************************************************************************


     function alignFocus(s,g, iId)
     {
         if (permitRefocus)
         {
           document.getElementById('focusSurname').innerHTML = s;
           document.getElementById('focusGivens').innerHTML = g;
           mySelectV.selectedIndex = document.getElementById('familyOption').index;
           if (!blockHistory) { myHistory.addNew(iId); }
           refreshHistory();
           redisplay();
         }
      }

   /*  refocuses on specified individual  */
     function alignFocusById(iId)   {

      /*  force suppression of automatic triggers while manipulation Select elements  */
        var currentPermitRefocus = permitRefocus;
        permitRefocus = false;
        thisItem = iIndex[iId];
        thisSurIndex = thisItem.surIndex;
        if (mySelectS.selectedIndex != thisSurIndex)  {
           mySelectS.selectedIndex = thisSurIndex;
           populateNames(thisSurIndex);
           }
        permitRefocus = currentPermitRefocus;
        mySelectG.selectedIndex = thisItem.givenIndex;
        refocusSelect();
        }

   /*  handler for clicks in various views  */
     function clickAlign(myId, evt)
     {
       thisEvt = (evt)?evt:window.event;
       var thisCaller = (thisEvt.srcElement)?thisEvt.srcElement:thisEvt.target;
       if (thisEvt) {  // no evt for firefox if dNav refocus button is origin

         if (thisEvt.altKey)  {
           switch(mySelectV.value)
           {
            case 'descendants':
             resetIdDnav(thisCaller.parentNode.getAttribute('id'));
             break;
            case 'ancestors':
             var fullId = thisCaller.parentNode.getAttribute('id');
             resetAnav(fullId);
             break;
            default:
             alignFocusById(myId);
             break;
           }
         }  // if altKey

         if (thisEvt.ctrlKey)  {
           switch(mySelectV.value)
           {
            case 'descendants':
             showInsert(thisCaller, myId);
             break;
            case 'ancestors':
             showInsert(thisCaller, myId);
             break;
            default:
             alignFocusById(myId);
             break;
           }
         }  // if ctrlKey

         if (!(thisEvt.altKey || thisEvt.ctrlKey)) alignFocusById(myId);
         
       }
     else { 
        alignFocusById(myId); 
        }
    }


  /* helper routine to change fontColor in specified Element  */
    function changeColor(colorCode, iElem) {
       iElem.style.color = colorCode;
       } 


   /*  focus-history management routines  */
     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; }
     }


   /*  handler for 'refocus' button  */
     function refocusSelect()
     {
        var g = mySelectG.selectedIndex;
        var s = mySelectS.selectedIndex;
        alignFocus(surnameTbl[s].surname, surnameTbl[s].givenTbl[g].displayName, surnameTbl[s].givenTbl[g].indivId);
        document.getElementById('selectRefocus').disabled = true; 
     }
       
   /*  handler for 'viewSelect' button  */
     function redisplay()  {
       document.getElementById('bNavs').style.visibility = 'hidden';
       document.getElementById('aNavs').style.visibility = 'hidden';
       document.getElementById('dNavs').style.visibility = 'hidden';
       outputBlock.innerHTML = '';
       switch(mySelectV.value)  {
         case 'ancestors':  
           document.getElementById('aNavs').style.visibility = 'visible';
           outputBlock.innerHTML = buildAnces();
           resetAnav('A');
           break;
         case 'descendants':
           document.getElementById('dNavs').style.visibility = 'visible';
           outputBlock.innerHTML = buildDesc();
           resetIdDnav('D00'); 
           break;
         case 'family':
           document.getElementById('bNavs').style.visibility = 'visible';
           outputBlock.innerHTML = buildFamily();
           var divs = outputBlock.getElementsByTagName('div');
           divs[0].scrollIntoView();
           break;
         }
       }



      function iChild(iElemPtr) {
         this.iElem = iElemPtr;
         }
      iChild.prototype.bDateCompareTo = function(b) {
         var aDate = this.iElem.getAttribute("bDate");
         var bDate = b.iElem.getAttribute("bDate");
         return (aDate == bDate)?0:((aDate > bDate)?1:-1);
         }
      iChild.bDateCompare = function(a, b) { return a.bDateCompareTo(b); }

      function iSpouse(iElemPtr) {
         this.iElem = iElemPtr;
         }
      iSpouse.prototype.sortDateCompareTo = function(b)  {
         var aSort = this.iElem.getAttribute("partnerSortDate");
         var bSort = b.iElem.getAttribute("partnerSortDate");
         if (aSort == bSort)  {
           return (this.iElem.partnerRef > b.iElem.partnerRef)?1:-1;
           }
         else  { 
           return (aSort == bSort)?0:((aSort > bSort)?1:-1);
           }
         }
      iSpouse.sortDateCompare = function(a, b) { return a.sortDateCompareTo(b); }

      function linkedName(iElem, isSpouse)  {
         if (iElem) {
            return '<SPAN onClick = "clickAlign(\'' 
                       + iElem.getAttribute("iID")
                       + '\', event); return false;" onMouseOver = "changeColor(\'#ff0000\', this); return false;"' 
                       + 'onMouseOut = "changeColor(\'#000000\', this); return false">' 
                       + ((isSpouse)?'spouse: ':'') + iElem.getAttribute("displayName") 
                       + '</SPAN>';
            }
         else {
            return '<SPAN STYLE="font-style: italic;">unknown</SPAN><BR>';
            }
         }

  function showInsert(callerElem, thisId)  {
    var insertHTML = buildInsert(thisId);
    var insertElem = document.getElementById("insertBlock");
    var baseOffsetTop = callerElem.offsetTop;
    var baseOffsetLeft = callerElem.offsetLeft + callerElem.offsetWidth;

    var offsetElem = document.getElementById('outBox');
    if (insertElem.offsetParent.tagName == 'BODY')  {  // signals non-MSIE
      while (offsetElem)  {
        baseOffsetTop += offsetElem.offsetTop;
        baseOffsetLeft += offsetElem.offsetLeft;
        offsetElem = offsetElem.offsetParent;
        }
      var outputElem = document.getElementById('outBox');
      baseOffsetTop -= outputElem.scrollTop;
    }

    insertElem.innerHTML = insertHTML;
    if ((baseOffsetLeft + insertElem.offsetWidth) 
           >= document.getElementById('outBox').offsetWidth) {
      insertElem.style.left = '10px';
      }
    else insertElem.style.left = (baseOffsetLeft - 10) + 'px';
    insertElem.style.top = (baseOffsetTop) + 'px';
    insertElem.style.fontSize = '75%';
    insertElem.style.overflow = 'auto';
    insertElem.style.visibility = 'visible';
    }

  function killInsert()  {
    var insertElem = document.getElementById("insertBlock");
    insertElem.style.left = '10px';
    insertElem.style.top = '10px';
    insertElem.innerHTML = '';
    insertElem.style.visibility = 'hidden';
    }

