// An autosuggest textbox control.

// Known bugs: safari fires onkeydown twice
// Known bugs: safari doesn't change div layer background color on mouse over

// TODO: relevance count



function ax_suggest(oTextbox, oProvider) {
    
    this.cur = -1; // The currently selected suggestions.
    this.layer = null; // The dropdown list layer.
    this.provider = oProvider; // Suggestion Provider
    this.textbox = oTextbox;
    this.currentTimeout = null;
   
    this.init();
}

ax_suggest.prototype.autosuggest = function (aSuggestions, bTypeAhead) {
	if (this.currentTimeout) {
		clearTimeout(this.currentTimeout);
	}

    if (aSuggestions.length > 0) {
        this.showSuggestions(aSuggestions);

        if (bTypeAhead) {
           //this.typeAhead(aSuggestions[0]);
           var rFunctRef = this.callLaterTypeAhead (this, aSuggestions[0]);
           this.currentTimeout = setTimeout (rFunctRef, 1000)
        }
    } else {
        this.hideSuggestions();
    }
};

ax_suggest.prototype.callLaterTypeAhead = function (oThis, suggestion){
    return (function(){
        oThis.typeAhead(suggestion);
    });
}

ax_suggest.prototype.createDropDown = function () {

    var oThis = this;

    this.layer = document.createElement("div");
    this.layer.id = "WordPrompter"
    this.layer.className = "suggestions";
    this.layer.style.visibility = "hidden";
    this.layer.style.width = this.textbox.offsetWidth;
        
    this.layer.onmousedown = 
    this.layer.onmouseup = 
    this.layer.onmouseover = function (oEvent) {
        oEvent = oEvent || window.event;
        oTarget = oEvent.target || oEvent.srcElement;

        if (oEvent.type == "mousedown") {
            //oThis.textbox.value = oTarget.firstChild.nodeValue;
            oThis.textbox.value = oTarget.innerHTML.replace('<B>','').replace('</B>','').replace('<b>','').replace('</b>','');
            oThis.hideSuggestions();
            oThis.SubmitMyParentForm();
        } else if (oEvent.type == "mouseover") {
            oThis.highlightSuggestion(oTarget);
        } else {
            oThis.textbox.focus();
        }
    };

    document.body.appendChild(this.layer);
};

ax_suggest.prototype.SubmitMyParentForm = function () {
	var obj = this.textbox;

	while (obj.nodeName != 'FORM' && obj.nodeName != 'form' && obj)
	{
		obj = obj.parentNode;
	}
	if (obj) obj.submit();
}

ax_suggest.prototype.getLeft = function () {

		var obj = this.textbox;

		var curleft = 0;
		if (obj.offsetParent)
		{
			while (obj.offsetParent)
			{
				curleft += obj.offsetLeft
				obj = obj.offsetParent;
			}
		}
		else if (obj.x)
			curleft += obj.x;
		return curleft;
};

ax_suggest.prototype.getTop = function () {

		var obj = this.textbox;

		var curtop = 0;
		if (obj.offsetParent)
		{
			while (obj.offsetParent)
			{
				curtop += obj.offsetTop
				obj = obj.offsetParent;
			}
		}
		else if (obj.y)
			curtop += obj.y;
		return curtop;
};

ax_suggest.prototype.handleKeyDown = function (oEvent) {
	if (this.currentTimeout) {
		clearTimeout(this.currentTimeout);
	}
 
    switch(oEvent.keyCode) {
        case 38: //up arrow
            this.previousSuggestion();
            break;
        case 40: //down arrow 
            this.nextSuggestion();
            break;
        case 13: //enter
            this.hideSuggestions();
            break;
    }
};

ax_suggest.prototype.handleKeyUp = function (oEvent) {
	if (this.currentTimeout) {
		clearTimeout(this.currentTimeout);
	}

    var iKeyCode = oEvent.keyCode;

    //for backspace (8) and delete (46), shows suggestions without typeahead
    if (iKeyCode == 8 || iKeyCode == 46) {
        this.provider.requestSuggestions(this, false);
        
    //make sure not to interfere with non-character keys
    } else if (iKeyCode < 32 || (iKeyCode >= 33 && iKeyCode < 46) || (iKeyCode >= 112 && iKeyCode <= 123)) {
        //ignore
    } else {
        this.provider.requestSuggestions(this, true);
    }
    
   if (iKeyCode == 13) FormSearchSubmit()
};

ax_suggest.prototype.hideSuggestions = function () {
   this.layer.style.visibility = "hidden";
};

ax_suggest.prototype.highlightSuggestion = function (oSuggestionNode) {
    
    for (var i=0; i < this.layer.childNodes.length; i++) {
        var oNode = this.layer.childNodes[i];
        if (oNode == oSuggestionNode) {
            oNode.className = "current"
        } else if (oNode.className == "current") {
            oNode.className = "";
        }
    }
};

ax_suggest.prototype.init = function () {

    var oThis = this;
    
    this.textbox.onkeyup = function (oEvent) {
        if (!oEvent) {
            oEvent = window.event;
        }    
        oThis.handleKeyUp(oEvent);
    };
    
    this.textbox.onkeydown = function (oEvent) {
        if (!oEvent) {
            oEvent = window.event;
        }    
        oThis.handleKeyDown(oEvent);
    };
    
    this.textbox.onblur = function () {
        oThis.hideSuggestions();
    };
    
   	window.onresize = function () {
   		oThis.handleWindowResize();
   	}
    
    this.createDropDown();
};

ax_suggest.prototype.nextSuggestion = function () {

    var cSuggestionNodes = this.layer.childNodes;

    if (cSuggestionNodes.length > 0 && this.cur < cSuggestionNodes.length-1) {
        var oNode = cSuggestionNodes[++this.cur];
        this.highlightSuggestion(oNode);
        //this.textbox.value = oNode.firstChild.nodeValue; 
        this.textbox.value = oNode.innerHTML.replace('<B>','').replace('</B>','').replace('<b>','').replace('</b>','');
    }
};

ax_suggest.prototype.previousSuggestion = function () {
    var cSuggestionNodes = this.layer.childNodes;

    if (cSuggestionNodes.length > 0 && this.cur > 0) {
        var oNode = cSuggestionNodes[--this.cur];
        this.highlightSuggestion(oNode);
       // this.textbox.value = oNode.firstChild.nodeValue;
       this.textbox.value = oNode.innerHTML.replace('<B>','').replace('</B>','').replace('<b>','').replace('</b>','');
    }
};

ax_suggest.prototype.selectRange = function (iStart, iLength) {

    // IE
    if (this.textbox.createTextRange) {
        var oRange = this.textbox.createTextRange(); 
        oRange.moveStart("character", iStart); 
        oRange.moveEnd("character", iLength - this.textbox.value.length);      
        oRange.select();
        
    // Mozilla
    } else if (this.textbox.setSelectionRange) {
        this.textbox.setSelectionRange(iStart, iLength);
    }     

    this.textbox.focus();      
}; 

ax_suggest.prototype.showSuggestions = function (aSuggestions) {
    
	var oDiv = null;
	this.layer.innerHTML = "";
	var iTextBoxLen = this.textbox.value.replace(/\s*$/g,"").length;

	for (var i=0; i < aSuggestions.length; i++) 
		{
		oDiv = document.createElement("div");
		oDiv.style.width = this.textbox.offsetWidth;
		oDiv.innerHTML = "<B>" + aSuggestions[i].substr(0, iTextBoxLen) + "</B>" + aSuggestions[i].substr(iTextBoxLen);
		this.layer.appendChild(oDiv);
		}

	this.handleWindowResize();
	
	if (document.formsearch.keywordsuggestions.checked) 
		{
		this.layer.style.visibility = "visible"
		this.layer.style.display = "block"
	//	document.formsearch.txtkeys1.setAttribute('autocomplete', 'off')
		}
	else
		{
		this.layer.style.visibility = "hidden"
		this.layer.style.display = "none"
	//	document.formsearch.txtkeys1.setAttribute('autocomplete', 'on')
		}
		
	this.handleWindowResize();
};

ax_suggest.prototype.handleWindowResize = function () 
	{
	var safari = 0
	var thetop
	
	if (navigator.userAgent.indexOf("Safari") != -1) safari = 0
	
	this.layer.style.left = this.getLeft() + "px"
	thetop = (this.getTop() + this.textbox.offsetHeight) + safari

	try {thetop = thetop - document.getElementById("ResultsContainer").scrollTop}
	catch(er) {}

	this.layer.style.top = thetop + "px"
	}


ax_suggest.prototype.typeAhead = function (sSuggestion) {

	if (document.formsearch.keywordsuggestions.checked)
		{
		//check for support of typeahead functionality
		if (this.textbox.createTextRange || this.textbox.setSelectionRange)
			{
			var iLen = this.textbox.value.length;
			this.textbox.value = sSuggestion;
			this.selectRange(iLen, sSuggestion.length);
			}
		}
};