/* EvocBrowse Javascript */

var aDynamics = new Array();
var bDocumentLoaded = 0;
var sOriginalOnLoad = document.onLoad;
var sPubDirUrl = "";

// Overriding Onload Method

function OnloadOverride() {
    if (sOriginalOnLoad) eval(sOriginalOnLoad);
    bDocumentLoaded = 1;
}
document.onLoad = OnloadOverride();

// Set PubDirUrl Global

function setPubDirUrl(sUrl) {
   sPubDirUrl = sUrl;
}

// Add a new dynamic element.
//   sId - a unique ID for the element.
//   oDiv - an Active.HTML.DIV object. 

function addDynamicDiv(sId) {
   aDynamics.push(new dynamicDiv(sId)); 
}

// Constructor for a dynamic element object.

function dynamicDiv(sId) {
   this.oReq = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP")
                                    : new XMLHttpRequest();
   this.sId = sId;
   this.iWaiting = 0;  
   this.iLoadCnt = 0; 
   this.sHeadText = "";
   this.sWaitText = "";
   this.sNoDataText = "";
   this.sUrl = "";
}

// Searches aDynamics array for a given sId and returns the associated object. 

function findById(sId) {
   var i; 
   for (i=0; i < aDynamics.length; i++) {
      if (aDynamics[i].sId == sId) break;
   }
   if (i == aDynamics.length) 
      alert("Dynamic object " + sId + " not found.");
   return aDynamics[i];
}

// Write a dynamic element stub

function writeDynamicDivStub(sId) {
   sHtml = "<div id='" + sId + "' class='dynamicdiv'></div>\n";
   document.write(sHtml);
}

// Retrieve a document element

function findElemById(sId) {
   e = document.getElementById(sId);
   if (!e)
       alert("Could not find document element " + sId + ".");
   return e;
}

// Check an element exists

function elemExists(sId) {
   e = document.getElementById(sId)
   if (e) return true;
   else return false;
}

// Hide a document element

function hideDiv(sId) {
   e = findElemById(sId);
   e.style.display = 'none';
   e.style.border = 'none';
}

// Show a document element
/* Hack around Gecko resize bug */
if (navigator.product)
    var bGeckoBrowser = (navigator.product.toLowerCase() == "gecko");
else
    var bGeckoBrowser = false;  

function showDiv(sId) {
   e = findElemById(sId);
   e.style.display = 'block';
   
   if (bGeckoBrowser) {   
     document.body.style.display = "none";
     document.body.style.display = "block";
   }
}

// Set the URL for a dynamics object and start loading it.
//   sHeadText - text to display above the fetched data.
//   sWaitText - text to display while loading.
//   sNoDataText - text to display if no data is returned.

function setUrl(sId,sUrl,sHeadText,sWaitText,sNoDataText) {
   oDyn = findById(sId);

   oDyn.sHeadText = sHeadText; 
   oDyn.sWaitText = sWaitText; 
   oDyn.sNoDataText = sNoDataText; 

   // Don't attempt to refetch the current URL.
   if (oDyn.sUrl == sUrl) return;

   // Clean up old URL
   if (oDyn.iWaiting != 0)
       cancelUrl(sId,sWaitText); 

   oDyn.sUrl = sUrl;

   if (sUrl == "") {
       oDiv = findElemById(oDyn.sId);
       oDiv.innerHTML = sNoDataText;
   }
   else {  
       oDyn.oReq.open("GET",oDyn.sUrl,true); // async = true
       oDyn.oReq.send(null);
       oDyn.iWaiting = 1; 
       checkDynamics();
   } 
}

// Cancel data download.

function cancelUrl(sId,sNewText) {
   oDyn = findById(sId);
   
   oDyn.iWaiting = 0;
   oDyn.iLoadCnt = 0;
   oDyn.sUrl = "";
   oDyn.oReq.abort();

   oDiv = findElemById(oDyn.sId);
   oDiv.innerHTML = sNewText;
}

// Checks to see if there are any dynamic elements whose
// content has arrived.

function checkDynamics() {
   var iDynamicsLeft = 0;

   for (i=0; i < aDynamics.length; i++) {
      oDyn = aDynamics[i];

      if (oDyn.iWaiting == 0) continue;

      oDiv = findElemById(oDyn.sId);

      if (oDyn.oReq.readyState != 4) { // 4 is the "download complete" state
         iDynamicsLeft++;
         oDyn.iLoadCnt++;

         sHtml = oDyn.sWaitText
               + Math.floor(oDyn.iLoadCnt/5) + " seconds elapsed.";
      }
      else {
         oDyn.iWaiting = 0;
         oDyn.iLoadCnt = 0;
         sRes = oDyn.oReq.responseText;
    
         iStatus = oDyn.oReq.status;
         iStatusMajor = iStatus - (iStatus % 100);  
 
         if (sRes == '' || iStatusMajor != 200)
             sHtml = oDyn.sHeadText + oDyn.sNoDataText;
         else
             sHtml = oDyn.sHeadText + sRes;
      }
      
      oDiv.innerHTML = sHtml;
   } 

   if (iDynamicsLeft > 0) {
       window.setTimeout(checkDynamics,200);
   } 
}

// Variables for keeping track of the current ontology and term.
var currentOnt = '';
var currentUr = '';
var currentTermId = '';
var currentHighlightId = ''; 
var currentTermName = '';
var dataUrl = '';
var ontologySet = '';
var ontSelectorId = '';
var sTermToLoad = '';

// Track which ontology is being presented. 

function setOntSelector (sId) { ontSelectorId = sId; }
function setOnt (sNewOnt) { currentOnt = sNewOnt; }
function changeOnt (sNewOnt) {
    if (currentOnt != sNewOnt) {
       hideDiv(currentOnt);
       showDiv(sNewOnt);
       currentOnt = sNewOnt;
       currentTermId = '';
       currentTermName = '';
       updateEvocData();
    }
}

// Track which resource is being presented.

function setUr (sNewUr) { currentUr = sNewUr; }
function changeUr (sNewUr) {
   if (sNewUr != currentUr) {
     currentUr = sNewUr;
     updateEvocData();
   }
}

// Track current term.

function updateTerm (sId) {
    currentTermId = sId;
    currentTermName = getTermName(sId);
    highlightTerm(sId);
    updateEvocData();
}

function getTermName (sId) {
    oE = findElemById(sId);
    oSib = oE.firstChild;

    sName = '';

    while (oSib != null) {
        if (oSib.nodeValue) sName = sName + oSib.nodeValue;
        oSib = oSib.nextSibling;      
    }

    return sName;
}

// Set the URL to retrieve term data from. 

function setDataUrl(sUrl) { dataUrl = sUrl; }

// Set the ontology set to use.

function setOntologySet(sOS) { ontologySet = sOS; }

// Cancel data being loaded into the term data widget. 

function cancelEvocDataDownload() {
    currentTermId = '';
    currentTermName = '';
    unHighlightTerm();
    cancelUrl('evocdata','No term selected.');
}

// Update the term data widget.

function updateEvocData() {
    if (currentTermId == '' || currentTermName == '') {
        cancelUrl('evocdata','No term selected.');
    }
    else if (currentUr == '') {
        cancelUrl('evocdata','<b>Term: ' + currentTermName + '</b><br/>' + 'No data type selected.'); 
    }
    else {
        sHeader = '<b>Term: ' + currentTermName + '</b><br/>';
        sWait = 'Loading data for ' + currentTermName + "...<br/>";
        sFail = 'Error loading data.';
        sUrl = dataUrl + '?term=' + currentTermId 
             + '&ur=' + currentUr
             + '&os=' + ontologySet;

        setUrl('evocdata',sUrl,sHeader,sWait,sFail);
    }
}

// Opening at a given term

function selectTermOnceLoaded(sTermId) {
    sTermToLoad = sTermId;
    window.setTimeout(checkTermOnceLoaded,500);
}

function checkTermOnceLoaded() {
    if (elemExists(sTermToLoad)) {
        oTerm = findElemById(sTermToLoad);
        oSel = findElemById(ontSelectorId);
        oPar = oTerm.parentNode;

        while (oPar != null) {
            if (oPar.className == 'evoctreerl') break;
            if (oPar.tagName == 'OL' || oPar.tagName == 'ol') setTermVisibility(oPar,1); 
            oPar = oPar.parentNode;      
        }

        while (oPar != null) {
            if (oPar.className == 'dynamicdiv') {
                oSel.value = oPar.id;
                changeOnt(oPar.id);
                break;
            }
            oPar = oPar.parentNode;
        }

        updateTerm(sTermToLoad);
    }
    else {
        window.setTimeout(checkTermOnceLoaded,500);
    }
}

// Open with all terms visible

var aExpOntIds = null;
var aExpOntStates = null;

function openAllTermsOnceLoaded() {
    window.setTimeout(checkOpenAllTermsOnceLoaded,500);
} 

function checkOpenAllTermsOnceLoaded() {
    iDone = 0;

    if (bDocumentLoaded && aExpOntIds == null) {
        aExpOntIds = new Array();
        aExpOntStates = new Array();
        oSel = findElemById(ontSelectorId);
 
        oC = oSel.firstChild;
        while (oC != null) {
           if (oC.tagName == "option" || oC.tagName == "OPTION") {
              aExpOntIds.push(oC.value);
              aExpOntStates.push(0);
           }
           oC = oC.nextSibling;
        }
    }

    if (bDocumentLoaded) {
        iWaitingOnts = 0; 
        for (i=0;i<aExpOntIds.length;i++) {
           if (aExpOntStates[i] == 1) continue;
           iWaitingOnts++;

           sId = aExpOntIds[i];
           oP = findElemById(sId);
           if(oP.firstChild) {
              oE = oP.firstChild.firstChild;
              setAllTermVisibilities(oE,1);
              aExpOntStates[i] = 1;
           } 
        }
        if (iWaitingOnts == 0) iDone = 1;
    }

    if (iDone != 1) { 
        window.setTimeout(checkOpenAllTermsOnceLoaded,500);
    }
}

// Term Highlighting

function highlightTerm(sId) {
   unHighlightTerm();

   e = findElemById(sId);
   e.style.fontWeight = "bold";

   currentHighlightId = sId;
}

function unHighlightTerm() {
   sId = currentHighlightId;

   if (sId == '') return;

   e = findElemById(sId);
   e.style.fontWeight = "normal"; 
   
   currentHighlightId = '';
}

// Toggle Visibility of Tree Elements

function toggle(oE) {
    setTermVisibility(oE,0);
}

function toggleAll(oTop) {
    setAllTermVisibilities(oTop,0);
}

// Set Visiblity of Tree Elements
// iToggle: 0 - toggle, 1 - visible, -1 - hidden

function setTermVisibility(oE,iToggle) {
    var oSib = oE.parentNode.firstChild;
    var oEbtTag = null;
    var oOlTag = null;
    var sOpenBullet = "url(" + sPubDirUrl + "/images/term-open-bullet.gif)";
    var sClosedBullet = "url(" + sPubDirUrl + "/images/term-closed-bullet.gif)"; 

    while (oSib != null) {
       if ((oSib.tagName == "A" || oSib.tagName == "a") 
           && (oEbtTag == null)) {
           if (oSib.className == "ebt") {
               oEbtTag = oSib;
               if (oOlTag != null) break;
           } 
       }
       if ((oSib.tagName == "OL" || oSib.tagName == "ol") 
           && (oOlTag == null)) {
           if ((oSib.style.display != "block" && iToggle == 0) 
               || (iToggle == 1)) {
               newDisplay = "block";
               newBg = sOpenBullet;
           }
           else {
               newDisplay = "none";
               newBg = sClosedBullet;
           }
           oOlTag = oSib;
           if (oEbtTag != null) break;
       }
       oSib = oSib.nextSibling;
    }

    if (oOlTag != null && oEbtTag != null)  {
        oOlTag.style.display = newDisplay;
        oEbtTag.style.backgroundImage = newBg;
    }
}

function setAllTermVisibilities(oTop,iToggle) {
    var oSib = oTop.parentNode;
    var aStack = Array(oSib);
    var sOpenBullet = "url(" + sPubDirUrl + "/images/term-open-bullet.gif)";
    var sClosedBullet = "url(" + sPubDirUrl + "/images/term-closed-bullet.gif)"; 

    while (aStack.length > 0) {
       oE = aStack.pop();
       if (oE == null) continue;

       var oEbtTag = null;
       var oOlTag = null;

       oC = oE.firstChild;
       while (oC != null) { 
          // Add child OL and LI elements to the stack
          if (oC.tagName == "OL" || oC.tagName == "ol" ||
              oC.tagName == "LI" || oC.tagName == "li") { 
             aStack.push(oC);
	     
          }

          // Find first OL tag 
          if ((oC.tagName == "OL" || oC.tagName == "ol") 
              && (oOlTag == null)) {
             if ((oC.style.display != "block" && iToggle == 0) 
                 || (iToggle == 1)) {
                newDisplay = "block";
                newBg = sOpenBullet;
             }
             else {
                newDisplay = "none";
                newBg = sClosedBullet;
             }
             oOlTag = oC;
          }

          // Find first AL tag 
          if ((oC.tagName == "A" || oC.tagName == "a") 
              && (oEbtTag == null) && (oC.className == "ebt")) {
             oEbtTag = oC;
          }
 
          oC = oC.nextSibling; 
       }    

       // Set Visibility if tags found 
       if (oOlTag != null && oEbtTag != null)  {
          oOlTag.style.display = newDisplay;
          oEbtTag.style.backgroundImage = newBg;
       }
    } 
} 
