/********************************************************************** * License information (the MIT license)
 *
 * Copyright (c) 2006 Catherine Beauheim; Stanford University
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation files
 * (the "Software"), to deal in the Software without restriction,
 * including without limitation the rights to use, copy, modify, merge,
 * publish, distribute, sublicense, and/or sell copies of the Software,
 * and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *********************************************************************/
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
 * Now going to our own server, the OntologyService.  
 * parameter key words are func, ontologyId, and term
 * func can have the values : getOntologyList
 *                            getChildren --> ontologyId, term
 *                            getParents  --> ontologyId, term
 *                            getTermsByName  --> ontologyId, term
 *                            getTerm  --> ontologyId, term (id), uid
 *                            getTerm  --> ontologyId, term , uid
 *                            getRootTerms    --> ontologyId
 *                            getTermMetaData --> ontologyId, term
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 

  var ontologyList= new Array();
  var widget;
  var req;
  var widgetplace;
  //var nameSpace;
  var termList = new Array();
  var READY_STATE_UNINITIALIZED=0;
  var READY_STATE_LOADING=1;
  var READY_STATE_LOADED=2;
  var READY_STATE_INTERACTIVE=3;
  var READY_STATE_COMPLETE=4;
  var widgetList;
  //var currentQuery = 0;
  var queuedIntervals = new Array();
  var queuedQueries = new Array();
   var waitqueue = new Array();
  var queue = new Array();  //set a true false for the queued queries. false when
                           //query has not yet happened.  true when it has been cleared
  //var uiMax = 50;
  var wait=0;
  var formId;

function SMDService (id) {

    try {
        formId = id;
        var ele = getElement ('busy');
        ele.setAttribute ("flag", 0 ); 
        //first get all the ontologies from the db 
        var ret = this.sendRequest ("?func=getOntologyList", "GET", SMDService.prototype.parseOntologyList);
    } catch (e ) {
        alert ("SMDService creation failed.  Exception : " + e );
        }
        return true;
    }


 
    /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *
     * send the request to the service (1) *
     * *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
    SMDService.prototype.cacheList = [];
    SMDService.prototype.sendRequest = function ( queryString, HttpMethod, readyMethod, type) {

     
       if (!HttpMethod ) {
           HttpMethod="GET";
       }
      var flagEle = getElement('busy');
      var urlele = getElement ('url');
      var url = urlele.getAttribute ('server');
      if (type == 1)
         url = "http://beauheim-smd-stanford.edu/smd/ontology/SubmitService";

   
      /* wait if the server is busy */
      if (flagEle.getAttribute('flag') != 0 ) {
          return  0;
      }

       flagEle.setAttribute ('flag', 1 );
       //req = this.initXMLHTTPRequest();
       if (window.XMLHttpRequest) {
           req=new XMLHttpRequest()
       }
    // code for IE
    else if (window.ActiveXObject) {
       req=new ActiveXObject("Microsoft.XMLHTTP")
    }
    if (req!=null) {
        req.onreadystatechange=readyMethod;
        try {
           req.open("GET",url+queryString, true)
        } catch (e) {
          doDebug ("open " + e );
          }
        req.send(null)
        return 1;
     }
     else {
        alert("Your browser does not support XMLHTTP.");
        return 0;
     }

    }

    /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *
     * start up the process (2) 
     * *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */

      SMDService.prototype.initXMLHTTPRequest = function () {
         var xRequest = false;

         try {
             if (window.netscape && window.netscape.security.PrivilegeManager.enablePrivilege)
                  window.netscape.security.PrivilegeManager.enablePrivilege ("UniversalBrowserRead");
             } catch (e) {
                 doDebug ("exception in send request " + e );
             }

         if (window.XMLHttpRequest) {
               try {
                   xRequest = new XMLHttpRequest();
                   if (xRequest.overrideMimeType) {
                      xRequest.overrideMimeType ('text/xml');
                   }
               } catch (e) {
                   doDebug ("unable to create a XMLHttpRequest object " );
                 }

         }
         else {
             // IE specifics
             /****try {
                xRequest = new ActiveXObject ("Msxml2.XMLHTTP.3.0");
             } catch (e) { ****/
                 try {
                    xRequest = new ActiveXObject ("Microsoft.XMLHTTP");
                 } catch (e1) {
                    xRequest = false;
                    doDebug (" ie part failed to get a request object " );
                 }
             //}
             if (xRequest ==null )
                alert ("This browser does not support XMLHTTP");
         }
         return xRequest;
         }



     /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
       SMDService.prototype.getOntologyId = function (ontologyName ) {


           if (ontologyList == null ) {
                doDebug ("getOntologyId failed for lack of list ");
                return;
           }
           var i=0;
           var found = false;
           while (i< ontologyList.length && !found ) {
              if (ontologyList[i].name == ontologyName ) {
                  doDebug (ontologyList[i].name + ", " + ontologyList[i].id );
                 return ontologyList[i].id;
              }
              else
                 i++;
           }
           doDebug ("seems we could not find the ontology name " + ontologyName );
           return 0;
       }

     /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
   
     SMDService.prototype.queryForAllOntologies = function (widget, where, uid ) {
        var widget = widget;
        widgetplace = where+uid;
        this.sendRequest ( "?func=getOntologyList&uid="+uid, "GET" , SMDService.prototype.parseOntologyList);
     }

     /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *
      * get the uid from the xml doc                                                    *
      * *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
        getUID = function (xmldoc ) {
        var uid = 0;

           if (xmldoc.hasChildNodes() && xmldoc.childNodes[0].nodeName == "TermList") {
              uid = xmldoc.childNodes[0].getAttribute ("uid");
           }
           else if (xmldoc.hasChildNodes() ){
              uid = xmldoc.childNodes[0].getAttribute("uid");
           }
           return uid;
        }


     /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *
        SMDService.prototype.reqError (msg) {
            document.body.style.cursor='auto';
            getElement ('busy').setAttribute ('flag', 0);
            alert (msg);

        }
      * *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
     /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *
      * called when the readyState is complete.                                         *
      * *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */

        SMDService.prototype.buildTreeFromRootsResponse = function () {

        if (req == null ) {
          reqError (" Req Error:  buildTreeFromRootsResponse " );
          return;
        } 
        var ready = req.readyState;
            if (ready == READY_STATE_COMPLETE ) {
                 document.body.style.cursor='auto';
                 getElement ('busy').setAttribute ('flag', 0);
                if (req.status == 200 ) {
                    xmldoc = req.responseXML;
                    var uid = getUID(xmldoc);
                    var rootNodeId = 0;
                    var el = getElement ('rootNodeId'+uid);
                    rootNodeId = el.getAttribute ('value');
 
                    OntologyTreeBrowser.prototype.buildTreeFromRootsResponse (xmldoc, rootNodeId, uid);

                }
            }
        }
 

     /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** * 
      * called when the readyState is complete.                                         * 
      * *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
        SMDService.prototype.getAncestorQueryResponse = function () {

        if (req == null ) {
          reqError (" Req Error:  getAncestorQueryResponse " );
          return;
        }
        var ready = req.readyState;
            if (ready == READY_STATE_COMPLETE ) {
               document.body.style.cursor='auto';
              getElement('busy').setAttribute ('flag', 0);
              try {
                if (req.status == 200 ) {
                    xmldoc = req.responseXML;
                    var uid = getUID (xmldoc);
                    var rootNodeId = getElement ('rootNodeId'+uid).getAttribute ('value');
                    OntologyTreeBrowser.prototype.getAncestorResponse(xmldoc, rootNodeId, uid);
                }
              } catch (e) {
                 doDebug ("SMDService. exception in getAncestorQueryResponse " + e );
                 }
            }

        }
     /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** * 
      * called when the readyState is complete.                                         * 
      * *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
        SMDService.prototype.getNewChildrenResponse = function () {

        if (req == null ) {
          reqError (" Req Error:  getNewChildrenResponse " );
          return;
        }
        var ready = req.readyState;
            if (ready == READY_STATE_COMPLETE ) {
               document.body.style.cursor='auto';
              getElement('busy').setAttribute ('flag', 0);
              try {
                if (req.status == 200 ) {
                    xmldoc = req.responseXML;
                    var uid = getUID(xmldoc);
                    var rootNodeId = getElement ('rootNodeId'+uid).getAttribute ('value');
                    OntologyTreeBrowser.prototype.getNewChildrenResponse(xmldoc, rootNodeId, uid);
                }
              } catch (e) {
                 doDebug ("SMDService. exception in getNewChildrenResponse " + e );
                 }
            }
        }

     /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *
        stashChildren.  query for the children, but don't display then.  Just create
        them and leave the + icon closed.  the ... icon should not appear
      * *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
     
        SMDService.prototype.stashChildren = function () {

        if (req == null ) {
          reqError (" Req Error:  stashChildren " );
          return;
        }

           var ready = req.readyState;
            if (ready == READY_STATE_COMPLETE ) {
               document.body.style.cursor='auto';
              getElement('busy').setAttribute ('flag', 0);
                if (req.status == 200 ) {
                    xmldoc = req.responseXML;
                    var uid = getUID(xmldoc);
                    var rootNodeId = getElement ('rootNodeId'+uid).getAttribute ('value');
                    OntologyTreeBrowser.prototype.stashChildren(xmldoc, rootNodeId, uid);
                }
            }

        }

     /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** * 
      * parse the xml into a list object 
      * *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */

     SMDService.prototype.parseOntologyList =  function () {

        if (req == null ) {
          reqError (" Req Error:  parseOntoloygList " );
          return;
        } 

   if (req.readyState == 4 ) {
        document.body.style.cursor='auto';
           if (req.status == 200 ) {
               var xmldoc = req.responseXML;
               if ( xmldoc.getElementsByTagName ("Ontology")) {
                   var xmlList = xmldoc.getElementsByTagName("Ontology");
                   //ontologyList=[];
                   for (var i = 0; i < xmlList.length; i++) {
                       var one = xmlList.item(i);
                       var pair = [];
                       var name = one.getAttribute('name');
                       var id = one.getAttribute ('id');
                       pair['id'] = one.getAttribute ('id');
                       pair['name'] = one.getAttribute ('name');
                      ontologyList[ontologyList.length]= pair;
                   }
               }
               else {
                   doDebug (" hmmmm no elements by tag name ");
               }
         }
         else {
              doDebug ("what is the status?  " + req.status);
         }
         getElement ('busy').setAttribute ('flag', 0);
         getElement('init').setAttribute ('flag', 2);
       }
 }


    /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *
     * given the list of available ontologies in the ontologyList, create the
     * widget to show the list.
     * @param Array of ontology objects.
     * *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
       createWidgetList = function(ontologyList, uid) {

          var id = 'buttonId' +uid;
          Widget.prototype.createSelectList (getElement('widget'+uid), getElement('ontSelected'), ontologyList);
       }

    /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */

       SMDService.prototype.getOntologyList = function () {
          return ontologyList;
       }

    /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
       waiting = function (w ) {
          if ( checkQueue()  == 1) {
            clearInterval (waitqueue[w]);
            wait++;
            if (wait == waitqueue.length ) {
               SMDService.prototype.makePreselectQueries();
            }
          }
          else
            return false; 
       }
    
    /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
      SMDService.prototype.makePreselectQueries = function() {

//doDebug ("make Preselect queries " );
         for (var i = 0; i < queuedQueries.length; i++) {
            if (getElement ('busy').getAttribute('flag') == 1) {
                var idx = queuedIntervals.length;
                //var s = 'sendQueryAgain(\''+queuedQueries[i]+'\', '+idx +', \'preSelectResponse\')' ;
                var s = 'sendQueryAgain(\''+queuedQueries[i]+'\', '+idx +', \'SMDService.prototype.preSelectResponse\')' ;
                queuedIntervals[idx] = setInterval ('sendQueryAgain(\''+queuedQueries[i]+'\', '+idx+', \'SMDService.prototype.preSelectResponse\')', 100);
            }
            else {
               this.sendRequest (queuedQueries[i], "GET", SMDService.prototype.preSelectResponse );
            }
         }
       }
    /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *
     * after the widget is set up, highlight a term in the tree and the text box
     * that was selected the last time.  have to query for the id by name, then
     * get the term id, call updateHighlight and put it in the text box as well.
     * *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
       SMDService.prototype.preSelectTerm = function (ontId, term, uid, rootId) {
           var string = "?func=getTerm&ontologyId=" + ontId + "&term=" + term + "&uid=" + uid;
//doDebug ("preselect term " + string );
           if (rootId )
             string += "&rootId=" + rootId;

           // I need to wait until all the widgets load  before doing this.
           // so I am just going to push them into queuedQueries
           // when the widgets are loaded, then figure it out.
           var end = queuedQueries.length;
           queuedQueries[queuedQueries.length] = string;
//doDebug (" end of queue " + end + " " + checkQueue());
           if (! checkQueue() ) {
             waitqueue[end] = setInterval ('waiting('+end+')', 200 ); 
           }
           else {
               //doDebug (" ready to send it " );
               SMDService.prototype.makePreselectQueries();
           }
         
       }

     /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
       SMDService.prototype.preSelectResponse = function () {
        if (req == null ) {
          reqError (" Req Error:  typeInTermResponse  " );
          return;
        }

         var ready = req.readyState;
         var id;
         var accession;
         var  name;
         var i = 0;
         var found = 0;
         var termList= new Array();
         var parentList;
         var uid;

         if (ready == READY_STATE_COMPLETE ) {
              document.body.style.cursor='auto';
              ele =  getElement('busy');
              ele.setAttribute ('flag', 0);
               if (req.status == 200 ) {
                   xmldoc = req.responseXML;
                   uid = getUID(xmldoc);
                   xmlList = xmldoc.getElementsByTagName ("Term");
                   var idx = 0;
                   for (var i = 0; i < xmlList.length; i++) {
                       var one = xmlList.item(i);
                       if (one.hasChildNodes() ) {
                           id = one.getAttribute ("id");
                           for (var j = 0; j < one.childNodes.length; j++ ) {
                               var node = one.childNodes.item(j);
                               if (node.nodeName == "name" )
                                    name = node.childNodes.item(0).nodeValue;
                               else if (node.nodeName == "id" )
                                    id = node.childNodes.item(0).nodeValue;
                               else if (node.nodeName == "accession" ) {
                                    accession = node.childNodes.item(0).nodeValue;
                               }
                               else if (node.nodeName == "parentIds") {
                                    pids = node.childNodes.item(0).nodeValue;
                                    parentList = new Array();
                                    parentList = pids.split(",");
                                    if (parentList.length == 0 )
                                         parentList[0] = pids;
                               }
                           }
                       termList[termList.length] = new Term (id, name, accession, parentList );

                       }
                   }
               }
          //hopefully in this case, there is only one term on the list.  this
          // is the one we want to preselect.
          if (termList.length > 1 ) {
             doDebug (" oh dear I found more than one term ");
          }
          var node = termList[0];
          var ta = getElement ('TA'+uid);
          ta.value = node.name+" " + node.accession;
          ta.setAttribute ('value', node.name+" " + node.accession);
          ta.setAttribute ('termId', node.id );
          OntologyTreeBrowser.prototype.updateHighlighting (node.id, uid );
          Widget.prototype.updateHiddenAreas (node, uid);
          OntologyTreeBrowser.prototype.getTree (uid).draw();
          }
       }

    /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *
     * @param ontId  the ontology that we are interested in                        *
     * @param term   what has been typed in so far                                 *
     * @param namespace  the namespace that has been selected                      *
     * *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */

       SMDService.prototype.typeInTermRequest = function (ontId, term, uid, rootId) {
          var subset=[];
          var useCache = 0;
          var flagg = 0;

          /** is there a cache list and if so is this 'term' within it? **/
                var string = "?func=getTermsByName&ontologyId=" + ontId + "&term=" + term + "&uid=" + uid;
                if (rootId )
                   string += "&rootId=" + rootId;
                var ele = getElement('busy');
                if (ele.getAttribute('flag') == 1) {
                    return 1;
                }
                document.body.style.cursor='wait';
                this.sendRequest ( string, "GET", typeInTermResponse);
                   
             return 0;
       }

    /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
       compare = function (str1, str2) {
            var res=0 ;

            if (str1.length > str2.length )
                return 1;
            var st = str2.slice (0, str1.length);
            str1 = str1.toLowerCase();
            st = st.toLowerCase();
            if (str1 < st)
               res = -1;
            else if (str1>st)
                res = 1;
           return res;

       }
    /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
    /* not being used                                                              */
    /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
       inCache = function (term, uid ) {

          var flag = false;
          if (SMDService.prototype.cacheList[uid] == null || SMDService.prototype.cacheList[uid].length == 0 )
              return flag;
          var beg = compare (term, SMDService.prototype.cacheList[uid][0].name );
          var tend = SMDService.prototype.cacheList[uid].length-1;
          var moreterms = compare ("More", SMDService.prototype.cacheList[uid][tend].name);
          if (moreterms == 0)
              tend--;
          
          var end = compare (term, SMDService.prototype.cacheList[uid][tend].name );
             
          if (beg >=0 && end < 0 && moreterms !=0 ) 
              flag = true;
          return flag;  
       }
    /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */

       typeInTermResponse = function () {

        if (req == null ) {
          reqError (" Req Error:  typeInTermResponse  " );
          return;
        } 

         var ready = req.readyState;
         var id; 
         var accession;
         var  name;
         var i = 0;
         var found = 0;
         //var TA;
         var termList= new Array();

         if (ready == READY_STATE_COMPLETE ) {
              document.body.style.cursor='auto';
              ele =  getElement('busy');
              ele.setAttribute ('flag', 0);
               if (req.status == 200 ) {
                   xmldoc = req.responseXML;
                   var uid = getUID(xmldoc);
                   xmlList = xmldoc.getElementsByTagName ("Term");
                   var idx = 0;
                   for (var i = 0; i < xmlList.length; i++) {
                       found = 0;
                       var one = xmlList.item(i);
                       id = one.getAttribute ("id");
                       if (one.hasChildNodes() ) {
                           for (var j = 0; j < one.childNodes.length; j++ ) {
                               var node = one.childNodes.item(j);
                               if (node.nodeName == "name" )
                                    name = node.childNodes.item(0).nodeValue;
                               else if (node.nodeName == "id" )
                                    id = node.childNodes.item(0).nodeValue;
                               else if (node.nodeName == "accession" ) {
                                    accession = node.childNodes.item(0).nodeValue;
                               } 
                               else if (node.nodeName == "parentIds") {
                                    pids = node.childNodes.item(0).nodeValue;
                                    parentList = new Array();
                                    parentList = pids.split(",");
                                    if (parentList.length == 0 )
                                         parentList[0] = pids;
                               }
                           }
                       termList[termList.length] = new Term (id, name, accession, parentList );
                       }
                   }
               }
          //SMDService.prototype.cacheList[uid] = termList;
          Widget.prototype.typeAheadResponse (termList, uid);
          }

       }


    /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *
     * response from query to create a widget starting with a named root
     * *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
       SMDService.prototype.createWidgetAtThisRoot = function () {

        if (req == null ) {
          reqError (" Req Error:  createWidgetAtThisRoot  " );
          return;
        }

          var ready = req.readyState;
          var uid;
          var xmlList;
          var one;
          var i = 0;
          var found = 0;
          var accession;
          var id;
          if (ready == READY_STATE_COMPLETE ) {
              getElement('busy').setAttribute ('flag', 0);
              document.body.style.cursor='auto';
              if (req.status == 200 ) {
                  var xmldoc = req.responseXML;
                  uid = getUID(xmldoc);
                  xmlList = xmldoc.getElementsByTagName ("Term");
                  //for the widgetList.lookup object that matches this uid in order to get the
                  //other pieces.
                  var lookup = findLookup (uid );
                  while (i <xmlList.length && found == 0 ) {
                      var one  = xmlList.item(i);
                      id = one.getAttribute ("id");   
                      if (one.hasChildNodes() ) {
                         for (var j = 0; j < one.childNodes.length; j++ ) {
                             var node = one.childNodes.item(j);
                             if (node.nodeName == "name" && node.childNodes.item(0).nodeValue == lookup.termName ) {
                                found = true;
                                lookup.termId = id;
                                //break;
                             }
                             else if (node.nodeName == "accession" )
                                accession = node.childNodes.item(0).nodeValue ;
                         }
                      }
                      else {
                        doDebug ("Error condition 8888 " );
                      }
                      if (found == false ) {
                          i++;
                       }
                  }
                  if (found ) {
                      var widget = new Widget (lookup.label, lookup.ontId,  lookup.ontName,
                                               id, lookup.title, lookup.uid, lookup.termName, accession);

                      var el = getElement('widget'+lookup.uid);
                      var html = widget.createHTML (getElement('widget'+lookup.uid));
                      el.innerHTML = html;
                      var nodelabel = lookup.termName+" " + accession;
                      OntologyTreeBrowser.prototype.initTopNode ( id, lookup.ontId, nodelabel, lookup.uid);
                  }
                  else {
                    alert (" Could not find the term name " + lookup.termName + " for the ontology " + lookup.ontName); 
                    doDebug ("Error condition 8888-1 ");
                  } 
              }
          }

      }
 
    /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */

       findLookup = function (uid )  {
         var i = 0;
         var found = false;
         while (i < widgetList.lookups.length && found == 0 ) {
             if (widgetList.lookups[i].uid == uid )
                found = true;
             else 
                i++;
         }
         if (found == false )
            return null;
         return widgetList.lookups[i];
       }

    /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** * 
     * set off all the queries.  when all the queries have returned, then set the init
     * attribute flag = 3 to indicate that init process is finished                    * 
     * *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
       SMDService.prototype.loadWidgets = function (termNames) {

         widgetList = termNames;
         var idx = 0;

         for (var i=0; i < widgetList.lookups.length; i++) {
              if (widgetList.lookups[i].ontId == 0 ) {
                  alert (" Unable to locate an ontology with the name " + widgetList.lookups[i].ontName );
              }
              else if (widgetList.lookups[i].termName == 0 ) {
//doDebug ("term name is 0 " + widgetList.lookups[i].label + ", " + widgetList.lookups[i].ontId );
                 var widget = new Widget (widgetList.lookups[i].label, 
                                          widgetList.lookups[i].ontId,
                                          widgetList.lookups[i].ontName,
                                          0,
                                          //widgetList.lookups[i].termId,
                                          widgetList.lookups[i].title,
                                          widgetList.lookups[i].uid );

                 var widgeti = widgetList.lookups[i];
                 var el = getElement ('widget'+widgeti.uid);
                 var html = widget.createHTML (el);
                 el.innerHTML = html;
                 var label=widgeti.termName;
                 OntologyTreeBrowser.prototype.initTopNode ( 0, widgeti.ontId, label, widgeti.uid, widgeti.termName, 0);
              }
              else {
                //var query = "?func=getTermsByName&ontologyId="+widgetList.lookups[i].ontId+"&term="+widgetList.lookups[i].termName+"&uid="+widgetList.lookups[i].uid;
                var query = "?func=getTerm&ontologyId="+widgetList.lookups[i].ontId+"&term="+widgetList.lookups[i].termName+"&uid="+widgetList.lookups[i].uid;

                if ( getElement('busy').getAttribute ('flag') == 1 ) {

                   queuedIntervals[idx] = setInterval ('sendQueryAgain(\''+query+'\', '+idx+')', 100);
                   queue[idx] = false;
                   idx++;
                }
                else {
                    this.sendRequest (query, "GET", this.createWidgetAtThisRoot);
                 }
              }
         }
         getElement('init').setAttribute ('flag', 3);
       }

    /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
       sendQueryAgain = function (query, idx, responseMethod) {

          var busyele = getElement('busy');
          if (busyele ) {
           if (getElement('busy').getAttribute ('flag') == 0 ) {
             if (responseMethod == null )
                 smdService.sendRequest (query, "GET", smdService.createWidgetAtThisRoot );
             else 
                 smdService.sendRequest (query, "GET", smdService.preSelectResponse);
             clearInterval (queuedIntervals[idx] );  
             queue[idx] = true;
             checkQueue();
          }
         }
         else {
            doDebug (" can't find the busy element ");
            return;
          }
       }
    /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
       checkQueue = function () {
         var total = true;
         for (var i = 0; i < queue.length; i++ ) {
             total = total & queue[i];
         }
         return total;
       }
    /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
    /*  for debugging                                                              */
    /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
    printNode = function (node ) {

       string = "--  print node --";
       string += node.nodeType + ", " + node.nodeName + ", " + node.nodeValue ;
       if (node.hasChildNodes() ) {
           string += " n child nodes = " + node.childNodes.length;
           string += " First child is " + printNode (node.firstChild );
       }
       else
           string += " no children";    
       return string;
    }

/*Term.js*/

  function Term (id , name, accession, parentIds ) {
      this.id = id;
      this.name = name;
      this.accession = accession;
      this.parentIds = parentIds;
     }

   /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
      Term.prototype.addChildren = function (nodes ) {

         this.children = new Array();
         for (var i = 0; i < nodes; i++ ) {
             this.children[i] = nodes[i];
         }
      }

   /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
      getElement = function (id ) {
         return (document.getElementById) ? document.getElementById (id)
                                          : document.all[id];
     }
   /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
    function doDebug(str) {
       var console = getElement ('console') ;             
       newline = document.createElement ('div');
       console.appendChild (newline);
       text = document.createTextNode("smd: " + str);
       newline.appendChild (text);
    }
   /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
      Term.prototype.addParent = function (node) {

         this.parent = node;
      }
   /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
      Term.prototype.describe = function () {
         string = "Term Id: " + this.id ;
           string += " " +  this.name  + " " + this.accession;
         return string;
      }
 
   /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** 
    * this toString method is used in the select list

    * *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
      Term.prototype.toString = function() {
          return this.accession +  "  " + this.name;
      }



