var getFunctionsUrl = "/suggest/suggest.php?keyword=";
var httpRequestKeyword = "";
var userKeyword = "";
var suggestions = 0;
var suggestionMaxLength = 30;
var isKeyUpDownPressed = false;
var autocompletedKeyword = "";
var hasResults = false;
var timeoutId = -1;
var position = -1;
var oCache = new Object();
var minVisiblePosition = 0;
var maxVisiblePosition = 9;
var debugMode = true;
var xmlHttpGetSuggestions = createXmlHttpRequestObject();
var Keywords="";

/*window.onload = init;*/

function createXmlHttpRequestObject() 
{
  var xmlHttp;
  try
  {
    xmlHttp = new XMLHttpRequest();
  }
  catch(e)
  {
    var XmlHttpVersions = new Array("MSXML2.XMLHTTP.6.0","MSXML2.XMLHTTP.5.0","MSXML2.XMLHTTP.4.0","MSXML2.XMLHTTP.3.0","MSXML2.XMLHTTP","Microsoft.XMLHTTP");
    for (var i=0; i<XmlHttpVersions.length && !xmlHttp; i++) 
    {
      try 
      { 
        xmlHttp = new ActiveXObject(XmlHttpVersions[i]);
      } 
      catch (e) {}
    }
  }
  if (xmlHttp)
    return xmlHttp;
}

function init() 
{  
  var oKeyword = document.getElementById("keyword");    
  oKeyword.setAttribute("autocomplete", "off");  
  oKeyword.value = "";
  /*oKeyword.focus();*/
  setTimeout("checkForChanges()", 500);
} 

function addToCache(keyword, values)
{
  oCache[keyword] = new Array();
  for(i=0; i<values.length; i++)
    oCache[keyword][i] = values[i];
}

function checkCache(keyword)
{
  if(oCache[keyword])
    return true;
  /*for(i=keyword.length-2; i>=0; i--)
  {
    var currentKeyword = keyword.substring(0, i+1);
    if(oCache[currentKeyword])
    {            
      var cacheResults = oCache[currentKeyword];
      var keywordResults = new Array();
      var keywordResultsSize = 0;            
      for(j=0;j<cacheResults.length;j++)
      {
        if(cacheResults[j].indexOf(keyword) == 0)               
          keywordResults[keywordResultsSize++] = cacheResults[j];
      }      
      addToCache(keyword, keywordResults);      
      return true;  
    }
  }*/else
  return false;
}

function getSuggestions(keyword) 
{  
  var pos=-1;
  var lastpos=0;
  var lastKey=keyword;
  Keywords="";
/*  var i=0;*/
  while ((pos=keyword.indexOf(' ',pos+1))>0)
  {
	  lastpos=pos;
  }
  if (lastpos!=0)
  {
	  lastKey=keyword.substr(lastpos+1);
	  Keywords=keyword.substr(0,lastpos+1);
  }
  keyword=lastKey;
  
  if(keyword != "" && !isKeyUpDownPressed)
  {
    isInCache = checkCache(keyword);
    if(isInCache == true)          
    {   
      httpRequestKeyword=keyword;
      userKeyword=keyword;     
      displayResults(keyword, oCache[keyword]);                          
    }
    else    
    {    
      if(xmlHttpGetSuggestions)
      { 
        try
        {
          if (xmlHttpGetSuggestions.readyState == 4 || 
              xmlHttpGetSuggestions.readyState == 0) 
          {    
            httpRequestKeyword = keyword;
            userKeyword = keyword;
            /*alert(keyword + "GET" + encode(keyword) + '&lang=' + encode(document.getElementById('DefaultLang').value));*/
            xmlHttpGetSuggestions.open("GET", getFunctionsUrl + /*encode*/(keyword) + '&lang=' + encode(document.getElementById('DefaultLang').value), true);
            xmlHttpGetSuggestions.onreadystatechange = handleGettingSuggestions; 
            xmlHttpGetSuggestions.send(null);
          }
          else
          {
            userKeyword = keyword;
            if(timeoutId != -1)
              clearTimeout(timeoutId);          
            timeoutId = setTimeout("getSuggestions(userKeyword);", 500);
          }
        }
        catch(e)
        {
          displayError("Can't connect to server:\n" + e.toString());
        }
      }
    }    
  }
}

function xmlToArray(resultsXml)
{
  var resultsArray= new Array();  
  for(i=0;i<resultsXml.length;i++)
    resultsArray[i]=resultsXml.item(i).firstChild.data;
  return resultsArray;
}

function handleGettingSuggestions() 
{
  if (xmlHttpGetSuggestions.readyState == 4) 
  {
    if (xmlHttpGetSuggestions.status == 200) 
    { 
      try
      {
        updateSuggestions();
      }
      catch(e)
      {
        displayError(e.toString()); 
      }  
    } 
    else
    {
      displayError("There was a problem retrieving the data:\n" + xmlHttpGetSuggestions.statusText);
    }       
  }
}

function updateSuggestions()
{
  var response = xmlHttpGetSuggestions.responseText;
  /*alert(response);*/
  if (response.indexOf("ERRNO") >= 0 
      || response.indexOf("error:") >= 0
      || response.length == 0)
    throw(response.length == 0 ? "Void server response." : response);
  response = xmlHttpGetSuggestions.responseXML.documentElement;
  nameArray = new Array();
  
  if(response.childNodes.length)
  {
    nameArray= xmlToArray(response.getElementsByTagName("name"));       
  }
  if(httpRequestKeyword == userKeyword)    
  {
    displayResults(httpRequestKeyword, nameArray);
  }
  else
  {
    addToCache(httpRequestKeyword, nameArray);              
  }
}

/* populates the list with the current suggestions */
function displayResults(keyword, results_array) 
{  
  // start building the HTML table containing the results  
  var div = "<table>"; 
  // if the searched for keyword is not in the cache then add it to the cache
  if(!oCache[keyword] && keyword)
    addToCache(keyword, results_array);
  // if the array of results is empty display a message
  if(results_array.length == 0)
  {
    div += "<tr><td>žiadne výsledky pre <strong>" + keyword + 
           "</strong></td></tr>";
    // set the flag indicating that no results have been found 
    // and reset the counter for results
    hasResults = false;
    suggestions = 0;
  }
  // display the results
  else
  {
    // resets the index of the currently selected suggestion
    position = -1;
    // resets the flag indicating whether the up or down key has been pressed
    isKeyUpDownPressed = false;
    /* sets the flag indicating that there are results for the searched 
       for keyword */
    hasResults = true;
    // get the number of results from the cache
    suggestions = oCache[keyword].length;
    // loop through all the results and generate the HTML list of results
    for (var i=0; i<oCache[keyword].length; i++) 
    {  
      // retrieve the current function
      crtFunction = oCache[keyword][i];
      // set the string link for the for the current function 
      // to the name of the function
      crtFunctionLink = crtFunction;
      // replace the _ with - in the string link
      while(crtFunctionLink.indexOf("_") !=-1)
        crtFunctionLink = crtFunctionLink.replace("_","-");
      // start building the HTML row that contains the link to the 
      // PHP help page of the current function
 
      div += "<tr id='tr" + i + 
             "' onclick='{document.getElementById(\"keyword\").value=document.getElementById(\"a" + i + 
             "\").innerHTML;document.getElementById(\"form_searchform\").submit();return false;}' onmouseover='handleOnMouseOver(this);' " + 
             "onmouseout='handleOnMouseOut(this);'>" + 
             "<td align='left'><a id='a" + i + 
             "' href='";
      // check to see if the current function name length exceeds the maximum 
      // number of characters that can be displayed for a function name
      if(crtFunction.length <= suggestionMaxLength)
      {
        // bold the matching prefix of the function name and of the keyword
        div += "'>" + Keywords +
               crtFunction.substring(0, httpRequestKeyword.length) + 
               ""
        div += crtFunction.substring(httpRequestKeyword.length, 
                                     crtFunction.length) + 
               "</a></td></tr>";
      }
      else
      {
        // check to see if the length of the current keyword exceeds 
        // the maximum number of characters that can be displayed
        if(httpRequestKeyword.length < suggestionMaxLength)
        {
          /* bold the matching prefix of the function name and that of the 
             keyword */
          div += "'>" + Keywords +
                 crtFunction.substring(0, httpRequestKeyword.length) + 
                 ""
          div += crtFunction.substring(httpRequestKeyword.length,
                                       suggestionMaxLength) + 
                 "</a></td></tr>";   
        }
        else
        {
          // bold the entire function name
          div += "'>" + Keywords +
                 crtFunction.substring(0,suggestionMaxLength) + 
                 "</td></tr>"          
        }
      }
    }
  }
  // end building the HTML table
  div += "</table>";
  // retrieve the suggest and scroll object
  var oSuggest = document.getElementById("suggest");  
  var oScroll = document.getElementById("scroll");
  // scroll to the top of the list
  oScroll.scrollTop = 0;
  // update the suggestions list and make it visible
  oSuggest.innerHTML = div;
  oScroll.style.visibility = "visible";
  // if we had results we apply the type ahead for the current keyword
  if(results_array.length > 0)
    autocompleteKeyword();      
}

/* function that periodically checks to see if the typed keyword has changed */
function checkForChanges()
{
  // retrieve the keyword object
 
  var keyword = document.getElementById("keyword").value;
  // check to see if the keyword is empty
  if(keyword == "")
  {
    // hide the suggestions
    hideSuggestions();
    // reset the keywords 
    userKeyword="";
    httpRequestKeyword="";
  }
  // set the timer for a new check 
  setTimeout("checkForChanges()", 500);
  // check to see if there are any changes
  if((userKeyword != keyword) && 
     (autocompletedKeyword != keyword) && 
     (!isKeyUpDownPressed))
    // update the suggestions
    getSuggestions(keyword);
}

/* function that handles the keys that are pressed */
function handleKeyUp(e) 
{
  // get the event
  e = (!e) ? window.event : e;
  // get the event's target
  target = (!e.target) ? e.srcElement : e.target;
  if (target.nodeType == 3) 
    target = target.parentNode;
  // get the character code of the pressed button
  code = (e.charCode) ? e.charCode :
       ((e.keyCode) ? e.keyCode :
       ((e.which) ? e.which : 0));
  // check to see if the event was keyup
  if (e.type == "keyup") 
  {    
    isKeyUpDownPressed =false; 
    // check to see we if are interested in the current character
    if ((code < 13 && code != 8) || 
        (code >=14 && code < 32) || 
        (code >= 33 && code <= 46 && code != 38 && code != 40) || 
        (code >= 112 && code <= 123)) 
    {
      // simply ignore non-interesting characters
    }
    else
    /* if Enter is pressed we jump to the PHP help page of the current 
       function */
    if(code == 13)
    {
      // check to see if any function is currently selected
      /*if(position>=0)
      {
        location.href = document.getElementById("a" + position).href;
      }  */      
    }        
    else
    // if the down arrow is pressed we go to the next suggestion
      if(code == 40)
      {                   
        newTR=document.getElementById("tr"+(++position));
        oldTR=document.getElementById("tr"+(--position));
        // deselect the old selected suggestion   
        if(position>=0 && position<suggestions-1)
          oldTR.className = "";
 
        // select the new suggestion and update the keyword
        if(position < suggestions - 1)
        {
          newTR.className = "highlightrow";
          updateKeywordValue(newTR);
          position++;         
        }     
        e.cancelBubble = true;
        e.returnValue = false;
        isKeyUpDownPressed = true;        
        // scroll down if the current window is no longer valid
        if(position > maxVisiblePosition)
        {   
          oScroll = document.getElementById("scroll");
          oScroll.scrollTop += 18;
          maxVisiblePosition += 1;
          minVisiblePosition += 1;
        }
      }
      else
      // if the up arrow is pressed we go to the previous suggestion
      if(code == 38)
      {       
        newTR=document.getElementById("tr"+(--position));
        oldTR=document.getElementById("tr"+(++position));
        // deselect the old selected position
        if(position>=0 && position <= suggestions - 1)
        {       
          oldTR.className = "";
        }
        if(position > 0)
        {
          newTR.className = "highlightrow";
          updateKeywordValue(newTR);
          position--;
          if(position<minVisiblePosition)
          {
            oScroll = document.getElementById("scroll");
            oScroll.scrollTop -= 18;
            maxVisiblePosition -= 1;
            minVisiblePosition -= 1;
          }   
        }     
        else
          if(position == 0)
            position--;
        e.cancelBubble = true;
        e.returnValue = false;
        isKeyUpDownPressed = true;  
      }     
  }
}

function updateKeywordValue(oTr)
{
  var oKeyword = document.getElementById("keyword");
/*  var crtLink = document.getElementById("a" + oTr.id.substring(2,oTr.id.length)).toString();*/
  var crtLink = document.getElementById("a"+oTr.id.substring(2,oTr.id.length)).innerHTML;
  /*crtLink = crtLink.replace("-", "_");
  crtLink = crtLink.substring(0, crtLink.length - 4);*/
  oKeyword.value = unescape(crtLink/*.substring(phpHelpUrl.length, crtLink.length)*/);
}

function deselectAll()
{ 
  for(i=0; i<suggestions; i++)
  {
    var oCrtTr = document.getElementById("tr" + i);
    oCrtTr.className = "";    
  }
}

function handleOnMouseOver(oTr)
{
  deselectAll();  
  oTr.className = "highlightrow";  
  position = oTr.id.substring(2, oTr.id.length);
}

function handleOnMouseOut(oTr)
{
  oTr.className = "";   
  position = -1;
}

function encode(uri) 
{
  if (encodeURIComponent) 
  {
    return encodeURIComponent(uri);
  }

  if (escape) 
  {
    return escape(uri);
  }
}

function hideSuggestions()
{
  var oScroll = document.getElementById("scroll");
  oScroll.style.visibility = "hidden";  
}

function selectRange(oText, start, length)
{  
  if (oText.createTextRange) 
  {
    //IE
    var oRange = oText.createTextRange(); 
    oRange.moveStart("character", start); 
    oRange.moveEnd("character", length - oText.value.length); 
    oRange.select();
 
  }
  else 
    // FF
    if (oText.setSelectionRange) 
    {
      oText.setSelectionRange(start, length);
    } 
  oText.focus(); 
}

function autocompleteKeyword()
{
  var oKeyword = document.getElementById("keyword");
  position=0;
  deselectAll();
  document.getElementById("tr0").className="highlightrow";  
  updateKeywordValue(document.getElementById("tr0"));  
  selectRange(oKeyword,Keywords.length+httpRequestKeyword.length,oKeyword.value.length);  
  autocompletedKeyword=oKeyword.value;
}

function displayError(message)
{
  alert("Error accessing the server! "+
        (debugMode ? "\n" + message : ""));
}
