function AutoSuggestControl(oTextbox,oProvider){
	this.cur = -1
	this.layer = null;
	this.provider = oProvider;
	this.textbox = oTextbox;
	this.userText = oTextbox.value;
	this.timeoutId = null;
	this.init(oProvider);
}

AutoSuggestControl.prototype.selectRange = function(iStart,iEnd){
	if(this.textbox.createTextRange){
		var oRange = this.textbox.creatTextRange();
		oRange.moveStart("character",iStart);
		oRange.moveEnd("character", iEnd-this.textbox.value.length);
		oRange.select();
	}else if(this.textbox.setSelectionRange){
		this.textbox.setSelectionRange(iStart,iEnd);
	}
	this.textbox.focus();
};

AutoSuggestControl.prototype.typeAhead = function(sSuggestion){
	if(this.textbox.createTextRange || this.textbox.setSelectionRange){
		var iLen = this.textbox.value.length;
		this.textbox.value = sSuggestion;
		this.selectRange(iLen,sSuggestion.length);
	}
};

AutoSuggestControl.prototype.autosuggest = function(aSuggestions, bTypeAhead){
	this.cur = -1;
	
	if(aSuggestions.length > 0){
		if(bTypeAhead){
			this.typeAhead(aSuggestions[0]);
		}
		this.showSuggestions(aSuggestions);
	}else{
		this.hideSuggestions();
	}
};

AutoSuggestControl.prototype.handleKeyUp = function(oEvent){
	var iKeyCode = oEvent.keyCode;
	var oThis = this;
	this.userText = this.textbox.value;

	clearTimeout(this.timeoutId);

	if(iKeyCode == 8 || iKeyCode == 46){ //bcksp or delete
		this.timeoutId = setTimeout(function(){
				oThis.provider.requestSuggestions(oThis,false); //don't typeahead
			},250);
	}else if(iKeyCode < 32 || (iKeyCode >= 33 && iKeyCode <= 46)
		|| (iKeyCode >= 112 && iKeyCode <=123)){
		//ignore
	}else{
		this.timeoutId = setTimeout(function(){
				oThis.provider.requestSuggestions(oThis,true); //do typeahead
			},250);
	}
};

AutoSuggestControl.prototype.handleKeyDown = function(oEvent){
	var oThis = this;
	switch(oEvent.keyCode){
		case 38: //up arrow
			this.goToSuggestion(-1);
			break;
		case 40: //down arrow
			this.goToSuggestion(1);
			break;
		case 27: //esc
			this.textbox.value = this.userText;
			this.selectRange(this.userText.length,0);
			/* falls through */
		case 9: //tab
			this.hideSuggestions();
			oEvent.returnValue = false;
			if(oEvent.preventDefault){
				oEvent.preventDefault();
			}
			oThis.provider.submitSearch(this.userText); //add search to list
			break;
		case 13: //enter
			oThis.hideSuggestions();
			oEvent.returnValue = false;
			if(oEvent.preventDefault){
				oEvent.preventDefault();
			}
			oThis.provider.submitSearch(this); //add search to list
			ajaxSearch(this.userText,'articleresults');
			$('#searchdiv').toggle();
                        //showhide('searchdiv');
			break;
	}	
};

AutoSuggestControl.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();
	};

	this.createDropDown();
};

AutoSuggestControl.prototype.hideSuggestions = function(){
	this.layer.hide();
};

AutoSuggestControl.prototype.highlightSuggestion = function($oSuggestionNode){
	$oSuggestionNode.siblings().removeClass("current");
        $oSuggestionNode.addClass("current");
};

AutoSuggestControl.prototype.createDropDown = function(){
        this.layer = $('<div class="suggestions" style="display:none;width:'+$(this.textbox).css("width")+'"></div>').appendTo("body");

        var oThis = this;

        this.layer.mousedown(function(e){
            oThis.textbox.value = $(e.target).html();
        }).mouseup(function(){
            oThis.textbox.focus();
        }).mouseover(function(e){
            oThis.highlightSuggestion($(e.target));
        })
};

AutoSuggestControl.prototype.getLeft = function(){
	var oNode = this.textbox;

	var pos = $(oNode).position();
        return pos.left;
};

AutoSuggestControl.prototype.getTop = function(){
	var oNode = this.textbox;

	var pos = $(oNode).position();
        return pos.top;
};

AutoSuggestControl.prototype.showSuggestions = function(aSuggestions){
        this.layer.empty();
	for(var i=0; i < aSuggestions.length; i++){
		$(this.layer).append("<div>"+aSuggestions[i]+"</div>");
	}

        this.layer.css("left",this.getLeft()+"px");
        this.layer.css("top",(this.getTop()+this.textbox.offsetHeight)+"px");
        this.layer.show();
};

AutoSuggestControl.prototype.goToSuggestion = function(iDiff){
	var cSuggestionNodes = this.layer.childNodes;

	if(cSuggestionNodes.length > 0){
		var oNode = null;
		
		if(iDiff > 0){
			if(this.cur < cSuggestionNodes.length -1){
				oNode = cSuggestionNodes[++this.cur];
			}
		}else{
			if(this.cur > 0){
				oNode = cSuggestionNodes[--this.cur];
			}
		}
		
		if(oNode){
			this.highlightSuggestion(oNode);
			this.textbox.value = oNode.firstChild.nodeValue;
		}
	}
};
