QQ.SearchSuggest = function(){
  //// common vars
  // div line height
  var ENTRY_DIV_HEIGHT = 16;
  
  // index of selected entry
  var selectedEntryIndex = 0;
  var selectedEntryText = "";
  var lastResultLength = 0;
  //var reqSave;									// hold a copy of last data that has been sent to move up and down the list without refreshing
  var inputBoxID = "";
  
  //// common functions
  // set search string
  function setSearchString(searchString) {
    obj(QQ.SearchSuggest.inputBoxID).value = searchString;
  	hideSuggestBox();	
  }
  
  function setActiveStyle(element,fontColor,backgroundColor){
    element.style.backgroundColor = backgroundColor;
    element.style.fontColor = fontColor
    element.style.cursor = "pointer";
  }
  
  function setInactiveStyle(element,fontColor,backgroundColor){
    element.style.backgroundColor = backgroundColor;
    element.style.fontColor = fontColor
  }
  
  // hide the search suggests
  function hideSuggestBox(event){
    if (event !== undefined){
      // write selected text in search box when enter is pressed
      if (event.keyCode == 13){
        obj(QQ.SearchSuggest.inputBoxID).value = selectedEntryText;
      }  
      // hide if tab or enter was pressed
      if (event.keyCode == 9 || event.keyCode == 13){
        obj(QQ.SearchSuggest.suggestBoxID).style.display = "none";
      }
    }else{
       obj(QQ.SearchSuggest.suggestBoxID).style.display = "none";
    }
  }
  
	// update suggest box when new data is given
	function updateSuggestBox(event,req){
		// construct the suggest results
    var suggestDiv = obj(QQ.SearchSuggest.suggestBoxID);
   
    // delete all elements first
    var listLength = suggestDiv.childNodes.length;
	  var divNode = suggestDiv.firstChild;
	  for (var j = 0; j < listLength; ++j){
	    var tmpNode = divNode;
	    divNode = divNode.nextSibling;
	    suggestDiv.removeChild(tmpNode);					  
	  }

	  // get result string into array
    var suggestResults = req.responseText.split(QQ.SearchSuggest.separator);
	 
	  // set selected entry back to first entry
	  if (lastResultLength != suggestResults.length){
      selectedEntryIndex = 0;
      selectedEntryText = "";
    }								 
	 
	  // set suggest box width
    suggestDiv.style.width = QQ.SearchSuggest.width + "px";
	 
	  // set max height
	  if (suggestResults.length > 5){
      suggestDiv.style.height = QQ.SearchSuggest.height + "px";
    }else suggestDiv.style.height = suggestResults.length * ENTRY_DIV_HEIGHT + "px";				

    // show the suggest box if there are suggests available
    if (req.responseText.length > 0){
      suggestDiv.style.display = "block";
    }else hideSuggestBox();	 
   
    // set styles if specified 
	  if (QQ.SearchSuggest.styleInformation.length > 0){    								  
	    suggestDiv.style.position = "absolute";
	 	  suggestDiv.style.border = "1px solid black";
	 	  suggestDiv.style.backgroundColor = "#ffffff";
	 	
	 	  fontNormal = QQ.SearchSuggest.styleInformation[0];
	 	  backgroundNormal = QQ.SearchSuggest.styleInformation[1];
      fontHighlight = QQ.SearchSuggest.styleInformation[2];
	 	  backgroundHighlight = QQ.SearchSuggest.styleInformation[3];								 	
	  }
	 
	  // if up or down arrows are pressed move selected entry
	  /*if (event.keyCode == 38 && selectedEntryIndex > 0){
      selectedEntryIndex--;
      obj(QQ.SearchSuggest.inputBoxID).value = selectedEntryText;
    }else if (event.keyCode == 40 && selectedEntryIndex < suggestResults.length-1){
      selectedEntryIndex++;
      obj(QQ.SearchSuggest.inputBoxID).value = selectedEntryText;
    }
		
		// scroll the list if necessary
		if (selectedEntryIndex * ENTRY_DIV_HEIGHT > suggestDiv.style.height) suggestDiv.scrollTop += ENTRY_DIV_HEIGHT;							 
	 */
	 
	  // render the search results
	  for (var i = 1; i < suggestResults.length; ++i){					 		
			var suggestEntry = document.createElement("div");
			suggestEntry.id = "QQ_SearchSuggest_Entry" + i;
			suggestEntry.innerHTML = suggestResults[i];
			//if (i==1) alert("_"+suggestResults[i])
			
      // create eventhandle object
      var o = {
        searchResult: suggestResults[i],
        handleEvent: function(){
          setSearchString(this.searchResult);
        }
      }
      addEvent(suggestEntry,"click",o);
      
      if (QQ.SearchSuggest.styleInformation.length > 0){
        addEvent(suggestEntry,"mouseover",function(){setActiveStyle(this,fontHighlight,backgroundHighlight);});
        addEvent(suggestEntry,"mouseout",function(){setInactiveStyle(this,fontNormal,backgroundNormal);});
      }else{
        addEvent(suggestEntry,"mouseover",function(){this.className = "selected";});
        addEvent(suggestEntry,"mouseout",function(){this.className = "";});
      }
      suggestDiv.appendChild(suggestEntry);
      
			selectedEntryText = suggestResults[i];
			
      /*if (i == selectedEntryIndex){
        if (QQ.SearchSuggest.styleInformation.length > 0){
          setActiveStyle(obj("QQ_SearchSuggest_Entry"+i),fontHighlight,backgroundHighlight);
        }else{
          obj("QQ_SearchSuggest_Entry"+i).className = "selected";
        }
        //selectedEntryText = suggestResults[i];
      } */
	  }	
   
    // set last result length
    lastResultLength = suggestResults.length;
	}
	
	function scrollList(event){
		var suggestDiv = obj(QQ.SearchSuggest.suggestBoxID);
		
		// if up or down arrows are pressed move selected entry
	  if (event.keyCode == 38 && selectedEntryIndex > 1){
      selectedEntryIndex--;
    	if (selectedEntryIndex * ENTRY_DIV_HEIGHT <= (suggestDiv.scrollTop+28)) suggestDiv.scrollTop -= ENTRY_DIV_HEIGHT;
		}else if (event.keyCode == 40 && selectedEntryIndex < lastResultLength-1){
      selectedEntryIndex++;
			if (selectedEntryIndex * ENTRY_DIV_HEIGHT >= (parseInt(suggestDiv.style.height.substr(0,suggestDiv.style.height.length-2))+suggestDiv.scrollTop+8)) suggestDiv.scrollTop += ENTRY_DIV_HEIGHT;	
    }
		
		obj(QQ.SearchSuggest.inputBoxID).value = obj("QQ_SearchSuggest_Entry"+selectedEntryIndex).innerHTML;
		
		
		for (var i = 1; i < lastResultLength; ++i){
		  if (i == selectedEntryIndex){
        if (QQ.SearchSuggest.styleInformation.length > 0){
          setActiveStyle(obj("QQ_SearchSuggest_Entry"+i),fontHighlight,backgroundHighlight);
        }else{
          obj("QQ_SearchSuggest_Entry"+i).className = "selected";
        }
        selectedEntryText = obj("QQ_SearchSuggest_Entry"+i).innerHTML;
      }else{
				if (QQ.SearchSuggest.styleInformation.length > 0){
          setInactiveStyle(obj("QQ_SearchSuggest_Entry"+i),fontColor,backgroundColor)
        }else{
					obj("QQ_SearchSuggest_Entry"+i).className = "";
        }
			} 
		}
	}
	
  // provide search suggests
  function searchSuggest(event){
    // get the request object
  	var req = QQ.Ajax.getRequestObject();
  			
  	// get the text input 
  	var searchBox = obj(QQ.SearchSuggest.inputBoxID); 
  	var inputText = searchBox.value;
  	
  	if ((req.readyState == 4 || req.readyState == 0) && inputText.length > 1 && inputText.indexOf("  ") == -1){
  
  	  req.open("GET", QQ.SearchSuggest.url+inputText, true);
  	  //req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  	  req.onreadystatechange = function handleSearchSuggest(){
  				switch (req.readyState){
  					case 4:// update the suggest box with new data
									 updateSuggestBox(event,req);
									 // save request to move up and down the list with arrow keys
									 //reqSave = req;	  				       				
  						   	 break;
  					default: return false;
  			}
  		}
      
      // only send if not only moving up and down
      if (event.keyCode != 38 && event.keyCode != 40) req.send(null);  		
  	  else scrollList(event);//updateSuggestBox(event,reqSave);
    
		}else hideSuggestBox();
  }  
  
  // return an object, through closure all methods keep bound to returned object
  return {
    inputBox: null,
    inputBoxID: "",
    suggestBoxID: "",
    url: null,
    width: 0,
    height: 0,
    separator : "#",
    styleInformation: [],
    init: function (inputBox,inputBoxID,suggestBoxID,url,width,height,separator,styleInformation){
      this.inputBox = inputBox;
      this.inputBoxID = inputBoxID;
      this.suggestBoxID = suggestBoxID;
      this.url = url;
      this.width = width;
      this.height = height;
      this.separator = separator;
      this.styleInformation = styleInformation;
      
      // insert necessary values for inputfield
      inputBox.setAttribute("id",inputBoxID);
      inputBox.setAttribute("autocomplete","off");
      
      // add event listeners
      addEvent(inputBox,"keydown",hideSuggestBox);
      addEvent(inputBox,"keyup",searchSuggest);
    }          
  }
}();
