/*
  config format - part of a defined query.
 <suggestConfig>
    <suggestInput pdqfield="name" elementId="sqlQuery.OwnerSearch.nameInputField" resultElementId="sqlQuery.OwnerSearch.nameInputFieldSuggestList" timeout="500" dbid="AllenCoOHData" tablename="ALLJOINED" fieldname="ALLJOINED.OWNNAM1" resultlimit="10" />
 </suggestConfig>
*/


QuerySuggest = function(inputElement,resultElement,timeout,dbid,fieldname,tablename,resultlimit)
{
  this.linkElements=function(inputElement,resultElement){
    //make sure that the elements have appropriate data associated with them and that pointers are correct
    this.inputElement = inputElement;
    this.inputElement.suggestObject = this;
    this.inputElement.autocomplete = 'off';  //disable native browser autocomplete
    this.inputElement.objectManagerId = OBJECT_MANAGER.registerObject(this.inputElement.id,this);
    xAddEventListener(this.inputElement,'keyup',EVENT_LISTENER);
    xAddEventListener(this.inputElement,'change',EVENT_LISTENER);
    xAddEventListener(this.inputElement,'focus',EVENT_LISTENER);
    this.resultElement = resultElement;
  };

  //define event callback functions
  this.focusCallback=function(){
    focused = true;
    typing = false;
  };
  
  this.keyUpCallback = function(){
    typing=true;
    this.hideResults();
    setTimeout('document.SuggestControl.suggestIndex['+this.suggestIndexId+'].stopTyping()',this.timeout);
  };
  
  this.changeCallback=function(){
    //this only occurs after the focus has been lost.
    this.hideResults();
    typing=false;
    focused=false;
  };

  this.stopTyping=function(){
    typing=false;
  };
  
  this.runProcess = function()
  {
    setTimeout('document.SuggestControl.suggestIndex['+this.suggestIndexId+'].runProcess();',this.timeout);
    //only do something if the field has focus
    var searchString = this.inputElement.value;
    if (!typing&&focused&&(searchString.strtrim()!='')&&(searchString!=last_search))
    {
      this.hideResults();
      last_search = searchString;
      var whereClause = 'Upper('+this.fieldname+') like \''+searchString.toUpperCase()+'%\'';
      makeASyncPostRequest(this,'runquery',XMLRPC_URL,'SQL.query.limitselect',this.dbid,'distinct '+this.fieldname,this.tablename,whereClause,this.resultLimit,0);
    }
  };
  
  this.callback = function(serverReplyDoc)
  {
    var noResults = false;
    /* begin error checks */
    if (serverReplyDoc == null){return (null);}
    var xmlstr = (typeof(serverReplyDoc.xml)=='function')?serverReplyDoc.xml():serverReplyDoc.xml;
    if (xmlstr == ''){return (null);}
    if (serverReplyDoc.documentElement.nodeName == 'parsererror'){return (null);};
    var clientReply = new XMLRPCResponse();
    clientReply.setResponseByDoc(serverReplyDoc);
    if (clientReply.isFault()){
      dprintf(clientReply.getFaultString());
    }
    else{
      var results = clientReply.getObject();
      this.resultElement.innerHTML = '';
      for (var currentResult=0;currentResult < results.length; currentResult++)
      {
        var currentNode = document.createElement('DIV');
        currentNode.resultValue = String.unescapeHTML(results[currentResult][this.fieldname]);
        currentNode.appendChild(document.createTextNode(results[currentResult][this.fieldname]));
        currentNode.innerHTML = results[currentResult][this.fieldname];
        currentNode.searchInputElement = this.inputElement;
        xAddEventListener(currentNode,'mousedown',function(evt){if (evt.target==null){evt.target = event.srcElement};try{evt.target.searchInputElement.value=evt.target.resultValue;}catch(e){}});
        xAddEventListener(currentNode,'mouseover',function(evt){if (evt.target==null){evt.target = event.srcElement};try{setClass(evt.target,'querySuggestListRowActive');}catch(e){}});
        xAddEventListener(currentNode,'mouseout',function(evt){if (evt.target==null){evt.target = event.srcElement};try{setClass(evt.target,'querySuggestListRowInactive');}catch(e){}});
        this.resultElement.appendChild(currentNode);
      }
      if (useHiddenResults)
      {
        this.resultElement.style.display = 'block';
      }
    }
  };
  
  this.hideResults = function()
  {
    if (useHiddenResults)
      this.resultElement.style.display = 'none';
  };
  
  this.id = inputElement.id+'.suggestcontroller';
  var typing=false;
  var focused = false;
  var last_search = '';
  var useHiddenResults = resultElement.style.display == 'none';
  this.timeout = timeout;
  this.dbid=dbid;
  this.fieldname=fieldname;
  this.tablename=tablename;
  this.resultLimit = resultlimit;
  //Prepare input elements
  if ((inputElement!=null)&&(resultElement!=null))
    this.linkElements(inputElement,resultElement);
};

SuggestControl = function()
{
  this.suggestIndex = new Array;
  this.lookupTable = new Object; //find index by element name
  this.addSuggest = function(suggestConfigObject){
    if (this.lookupTable[suggestConfigObject.elementId]==null)
    {
      var newIndex = this.suggestIndex.length;
      this.suggestIndex[newIndex] = new QuerySuggest(document.getElementById(suggestConfigObject.elementId),document.getElementById(suggestConfigObject.resultElementId),suggestConfigObject.timeout,suggestConfigObject.dbid,suggestConfigObject.fieldname,suggestConfigObject.tablename,suggestConfigObject.resultlimit);
      this.suggestIndex[newIndex].suggestIndexId = newIndex;
      this.lookupTable[suggestConfigObject.elementId] = newIndex;
      this.suggestIndex[newIndex].runProcess();
    }
    else
    {
      this.suggestIndex[this.lookupTable[suggestConfigObject.elementId]].linkElements(document.getElementById(suggestConfigObject.elementId),document.getElementById(suggestConfigObject.resultElementId));
    }
  };
};

document.SuggestControl = new SuggestControl();

