
if (typeof QQ === "undefined") {
    var QQ = {};
}
QQ.SearchSuggest = function() {
    //// common vars
    // div line height
    
    // index of selected entry
    var selectedEntryIndex = -1;
    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 = "";
	var suggestTimeOut = null;
    
    //// common functions
    // set search string
    function setSearchString(searchString) {
        
		// if searchString is HTML, look for div with className = searchSuggestName and take that content
		if (searchString.indexOf("qqSearchSuggestName") > -1) {
			searchString = searchString.replace(/[\s\S]*?qqSearchSuggestName["]?>([\s\S]*?)<\/[\s\S]*/gi, "$1");
		}
		
		obj(QQ.SearchSuggest.inputBoxID).value = searchString;        
    }
	
	function submitForm() {
		obj(QQ.SearchSuggest.inputBoxID).parentNode.submit();
	}
    
    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";
        }
    }
	
	function mouseLeaveSuggestBox(event) {
		if (event !== undefined) {
		
			var tg = (window.event) ? event.srcElement : event.target;
			if (tg.id != QQ.SearchSuggest.suggestBoxID) 
				return;
			var reltg = (event.relatedTarget) ? event.relatedTarget : event.toElement;
			while (reltg != tg && reltg.nodeName != 'BODY') {
				reltg = reltg.parentNode
			}
			if (reltg == tg) 
				return;
			
			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 = -1;
			selectedEntryText = "";
		}
		
		// set suggest box width
		suggestDiv.style.width = QQ.SearchSuggest.width + "px";
		
		// set max height
		if (suggestResults.length > 5) {
			suggestDiv.style.height = QQ.SearchSuggest.maxHeight + "px";
		}
		else {
			suggestDiv.style.height = suggestResults.length * QQ.SearchSuggest.entryHeight + "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
		var l = suggestResults.length;
        for (var i = 0; i < l; ++i) {
            var suggestEntry = document.createElement("div");
            suggestEntry.id = "QQ_SearchSuggest_Entry" + i;
            suggestEntry.innerHTML = suggestResults[i];
			suggestEntry.className = "deselected";
			
			//if (i==1) alert("_"+suggestResults[i])
            
            // create eventhandle object
            var o = {
                searchResult: suggestResults[i],
                handleEvent: function(){
                    setSearchString(this.searchResult);
					hideSuggestBox();
					submitForm();
                }
            }
            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(e){
                    this.className = "selected";
					selectedEntryIndex = (1*this.id.replace("QQ_SearchSuggest_Entry",""));
					setSearchString(obj("QQ_SearchSuggest_Entry" + selectedEntryIndex).innerHTML);
					markSelection();
                });
                addEvent(suggestEntry, "mouseout", function(){
                    this.className = "deselected";
					selectedEntryIndex = (1*this.id.replace("QQ_SearchSuggest_Entry",""));
					setSearchString(obj("QQ_SearchSuggest_Entry" + selectedEntryIndex).innerHTML);
					markSelection();
                });
            }
            suggestDiv.appendChild(suggestEntry);
            
            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 > 0) {
            selectedEntryIndex--;
            if (selectedEntryIndex * QQ.SearchSuggest.entryHeight <= (suggestDiv.scrollTop + 28)) 
                suggestDiv.scrollTop -= QQ.SearchSuggest.entryHeight;
        }
        else if (event.keyCode == 40 && selectedEntryIndex < lastResultLength - 1) {
            selectedEntryIndex++;
            if (selectedEntryIndex * QQ.SearchSuggest.entryHeight >= (parseInt(suggestDiv.style.height.substr(0, suggestDiv.style.height.length - 2)) + suggestDiv.scrollTop + 8)) {
				suggestDiv.scrollTop += QQ.SearchSuggest.entryHeight;
			}
        }
        
		setSearchString(obj("QQ_SearchSuggest_Entry" + selectedEntryIndex).innerHTML);

		markSelection();
    }
	
	function markSelection() {
		for (var i = 0; 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 = "deselected";
                }
            }
        }
	}
	
	function searchSuggestDelayed(event) {
		
		// scroll list when up or down is pressed
		if (event.keyCode == 38 || event.keyCode == 40) {
			scrollList(event);
		}
		else if (suggestTimeOut == null) {
			suggestTimeOut = setTimeout(function() {searchSuggest(event);}, QQ.SearchSuggest.delay);
		}
	}
    
    // 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;
				}
			}
			
			req.send(null);					
			
		} else {
			hideSuggestBox();
		}
		suggestTimeOut = null;
    }
    
    // return an object, through closure all methods keep bound to returned object
    return {
        inputBox: null,
        inputBoxID: "",
        suggestBoxID: "",
        url: null,
        width: 400,
        maxHeight: 150,
		entryHeight: 50,
        separator: "#",
        styleInformation: [],
		delay: 500,
        init: function(inputBox, inputBoxID, suggestBoxID, url, options) {
            this.inputBox = inputBox;
            this.inputBoxID = inputBoxID;
            this.suggestBoxID = suggestBoxID;
            this.url = url;
            
			if (options !== undefined) {
				if (options.width !== undefined) {
					this.width = options.width;
		        }
				if (options.maxHeight !== undefined) {
					this.maxHeight = options.maxHeight;
		        }
				if (options.entryHeight !== undefined) {
					this.entryHeight = options.entryHeight;
		        } 
				if (options.separator !== undefined) {
					this.separator = options.separator;
		        }
				if (options.delay !== undefined) {
					this.delay = options.delay;
		        }
				if (options.styleInformation !== undefined) {
					this.styleInformation = options.styleInformation;
		        }
			}
            
            // insert necessary values for inputfield
            inputBox.setAttribute("id", inputBoxID);
            inputBox.setAttribute("autocomplete", "off");

			// position the suggest box
			obj(suggestBoxID).style.position = "absolute";
			obj(suggestBoxID).style.left = QQ.Element.getX(inputBox) + "px";
			obj(suggestBoxID).style.top = QQ.Element.getY(inputBox) + QQ.Element.getHeight(inputBox) + 2 + "px";
						
            // add event listeners
            addEvent(inputBox, "keydown", hideSuggestBox);
            addEvent(inputBox, "keyup", searchSuggestDelayed);
			addEvent(obj(suggestBoxID), "mouseout", mouseLeaveSuggestBox);
        }
    }
}();

