/* URL to the PHP page called for receiving suggestions for a keyword*/
var getFunctionsUrl = "search_suggest.php?keyword=";
/* URL for seeing the results for the selected suggestion */
//var phpHelpUrl="<?php echo tep_href_link(FILENAME_ADVANCED_SEARCH_RESULT,'keywords=');?>";
/* the keyword for which an HTTP request has been initiated */
var httpRequestKeyword = "";
/* the last keyword for which suggests have been requested */
var userKeyword = "";
/* number of suggestions received as results for the keyword */
var suggestions = 0;
/* the maximum number of characters to be displayed for a suggestion */
var suggestionMaxLength = 30;
/* flag that indicates if the up or down arrow keys were pressed
   the last time a keyup event occurred  */
var isKeyUpDownPressed = false;
/* the last suggestion that has been used for autocompleting the keyword */
var autocompletedKeyword = "";
/* flag that indicates if there are results for the current requested keyword*/
var hasResults = false;
/* the identifier used to cancel the evaluation with the clearTimeout method. */
var timeoutId = -1;
/* the currently selected suggestion (by arrow keys or mouse)*/
var position = -1;
/* cache object containing the retrieved suggestions for different keywords */
//var oCache = new Object();
//var urlCache = new Object();
/* the minimum and maximum position of the visible suggestions */
var minVisiblePosition = 0;
var maxVisiblePosition = 3;
// when set to true, display detailed error messages
var debugMode = false;
/* the XMLHttp object for communicating with the server */
var xmlHttpGetSuggestions = createXmlHttpRequestObject();

/* Intervall in dem nach veränderungen im Keyword-eld geschaut wird.*/
var check_intervall = 1000;

/* the onload event is handled by our init function */
// creates an XMLHttpRequest instance
function createXmlHttpRequestObject() 
{
  // will store the reference to the XMLHttpRequest object
  var xmlHttp;
  // this should work for all browsers except IE6 and older
  try
  {
    // try to create XMLHttpRequest object
    xmlHttp = new XMLHttpRequest();
  }
  catch(e)
  {
    // assume IE6 or older
    var XmlHttpVersions = new Array("MSXML2.XMLHTTP.6.0",
                                    "MSXML2.XMLHTTP.5.0",
                                    "MSXML2.XMLHTTP.4.0",
                                    "MSXML2.XMLHTTP.3.0",
                                    "MSXML2.XMLHTTP",
                                    "Microsoft.XMLHTTP");
    // try every prog id until one works
    for (var i=0; i<XmlHttpVersions.length && !xmlHttp; i++) 
    {
      try 
      { 
        // try to create XMLHttpRequest object
        xmlHttp = new ActiveXObject(XmlHttpVersions[i]);
      } 
      catch (e) {}
    }
  }
  // return the created object or display an error message
  if (!xmlHttp){
    displayError("Error creating the XMLHttpRequest object.");
  	return false;
  }else 
    return xmlHttp;
}

/* function that initializes the page */
function init() 
{  
  // retrieve the input control for the keyword
  var oKeyword = document.getElementById("keyword");    
  // prevent browser from starting the autofill function
  oKeyword.setAttribute("autocomplete", "off");  
  // reset the content of the keyword and set the focus on it
  userKeyword = oKeyword.value;
  // set the timeout for checking updates in the keyword's value
  setTimeout("checkForChanges()", check_intervall);
} 

/* initiate HTTP request to retrieve suggestions for the current keyword */
function getSuggestions(keyword) 
{  
  /* continue if keyword isn't null and the last pressed key wasn't up or 
     down */
  if(keyword != "" && !isKeyUpDownPressed)
  { 
      if(xmlHttpGetSuggestions)
      { 
        try
        {
          /* if the XMLHttpRequest object isn't busy with a previous request... */
          if (xmlHttpGetSuggestions.readyState == 4 || xmlHttpGetSuggestions.readyState == 0) 
          {    
            httpRequestKeyword = keyword;
            userKeyword = keyword;
            xmlHttpGetSuggestions.open("GET", getFunctionsUrl + encode(keyword), true);
            xmlHttpGetSuggestions.onreadystatechange = handleGettingSuggestions; 
            xmlHttpGetSuggestions.send(null);
          }
          // if the XMLHttpRequest object is busy...
          else
          {
            // retain the keyword the user wanted             
            userKeyword = keyword;
            // clear any previous timeouts already set
            if(timeoutId != -1)
              clearTimeout(timeoutId);          
            // try again in 0.5 seconds     
            timeoutId = setTimeout("getSuggestions(userKeyword);", check_intervall);
          }
        }
        catch(e)
        {
          displayError("Can't connect to server:\n" + e.toString());
        }
    }    
  }
}

/* transforms all the children of an xml node into an array */
function xmlToArray(resultsXml)
{
  // initiate the resultsArray
  var resultsArray= new Array();  
  // loop through all the xml nodes retrieving the content  
  for(i=0;i<resultsXml.length;i++)
    resultsArray[i]= resultsXml.item(i).firstChild.data;
  // return the node's content as an array
  return resultsArray;
}

/* handles the server's response containing the suggestions 
   for the requested keyword  */
function handleGettingSuggestions() 
{
  //if the process is completed, decide what to do with the returned data
  if (xmlHttpGetSuggestions.readyState == 4) 
  {
    // only if HTTP status is "OK"
    if (xmlHttpGetSuggestions.status == 200) 
    { 
      try
      {
        // process the server's response
        updateSuggestions();
      }
      catch(e)
      {
        // display the error message
        displayError(e.toString()); 
      }  
    } 
    else
    {
      displayError("There was a problem retrieving the data:\n" + 
                   xmlHttpGetSuggestions.statusText);
    }       
  }
}

/* function that processes the server's response */
function updateSuggestions()
{
  // retrieve the server's response 
  var response = xmlHttpGetSuggestions.responseText;
  // server error?
  if (response.indexOf("ERRNO") >= 0 || response.indexOf("error:") >= 0 || response.length == 0)
    throw(response.length == 0 ? "Void server response." : response);
  // retrieve the document element
  response = xmlHttpGetSuggestions.responseXML.documentElement;
  // initialize the new array of functions' names
  nameArray = new Array();
  urlArray = new Array();
  // check to see if we have any results for the searched keyword
 
  if(response.childNodes.length)
  {
    /* we retrieve the new functions' names from the document element as 
       an array */
    nameArray= xmlToArray(response.getElementsByTagName("name"));
    urlArray= xmlToArray(response.getElementsByTagName("url"));              
  }
  // check to see if other keywords are already being searched for
  if(httpRequestKeyword == userKeyword)    
  {
    // display the results array
    displayResults(httpRequestKeyword, nameArray, urlArray);
  }
}

/* populates the list with the current suggestions */
function displayResults(keyword, results_array, url_array) 
{  
  // start building the HTML table containing the results  
  var div = "<table>"; 
  // if the array of results is empty display a message
  if(results_array.length == 0)
  {
	hideSuggestions();
    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 = results_array.length;
    // loop through all the results and generate the HTML list of results
	for (var i=0; i<suggestions; i++) 
    {  
      // retrieve the current function
	  crtFunction = results_array[i];
	  url = url_array[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("_","-");
	  while(crtFunction.indexOf("+") != -1)	
		crtFunction = crtFunction.replace("+"," ");
	
	  //crtFunction = crtFunction.replace("%E4","ä");
      // start building the HTML row that contains the link to the 
      div += "<tr id='tr" + i + 
             "' onclick='location.href=document.getElementById(\"a" + i + 
             "\").href;' onmouseover='handleOnMouseOver(this);' " + 
             "onmouseout='handleOnMouseOut(this);'>" + 
             "<td align='left'><a class='suggest_link' id='a" + i + 
             "' href='" + url ;
             
      // 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 += "'><b>" + 
               (crtFunction.substring(0, httpRequestKeyword.length)) + 
               "</b>";
        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 += "'><b>" + 
                 (crtFunction.substring(0, httpRequestKeyword.length)) + 
                 "</b>";
          div += (crtFunction.substring(httpRequestKeyword.length,
                                       suggestionMaxLength)) + 
                 "</a></td></tr>";   
        }
        else
        {
          // bold the entire function name
          div += "'><b>" + 
                 crtFunction.substring(0,suggestionMaxLength) + 
                 "</b></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
  }
  
}

/* 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()", check_intervall);
  // check to see if there are any changes
  if((userKeyword != keyword) && (!isKeyUpDownPressed))
    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; 

    /* 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)
      {
		//document.getElementById("keyword").value = document.getElementById("a" + position).innerHTML;
        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 = "moduleRowOver";
        //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 = "";
      }
      // select the new suggestion and update the keyword
      if(position > 0)
      {
        newTR.className = "moduleRowOver";
        //updateKeywordValue(newTR);
        position--;
        // scroll up if the current window is no longer valid
        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;  
    }//else
	// the ESC-Key has been pressed
	if (code == 27){
	  hideSuggestions();
	}
  }
}

/* function that removes the style from all suggestions*/
function deselectAll()
{ 
  for(i=0; i<suggestions; i++)
  {
    var oCrtTr = document.getElementById("tr" + i);
    oCrtTr.className = "";    
  }
}

/* function that handles the mouse entering over a suggestion's area 
   event */
function handleOnMouseOver(oTr)
{
  deselectAll();  
  oTr.className = "moduleRowOver";  
  position = oTr.id.substring(2, oTr.id.length);
}

/* function that handles the mouse exiting a suggestion's area event */
function handleOnMouseOut(oTr)
{
  oTr.className = "";   
  position = -1;
}

/* function that escapes a string */
function encode(uri) 
{
  if (encodeURIComponent) 
  {
    return encodeURIComponent(uri);
  }
  if (escape) 
  {
    return escape(uri);
  }else{
	return false;
  }
}

/* function that hides the layer containing the suggestions */
function hideSuggestions()
{
  var oScroll = document.getElementById("scroll");
  oScroll.style.visibility = "hidden";  
}

/* function that displays an error message */
function displayError(message)
{
  // display error message, with more technical details if debugMode is true
  if (debugMode == true)
	alert("Error accessing the server! "+ "\n" + message);
}



