function TriveSuggest(textbox,classname,url,when,loadingMessage)
{
	if(textbox == null)
		return;
	
	this.textbox = textbox
	this.url = url;
	this.classname = classname;
	this.loadingMessage = loadingMessage || '<li>Laddar..</li>';
	this.xmlObject;
	this.resultArray = new Array();
	this.resultList;
	this.activeNode = -1;
	this.when = when;
	this.init();
}

TriveSuggest.prototype.init = function ()
{
	var tempThis = this;
	
	//create and append a resultList element
	var resultList = document.createElement('ul');
	resultList.className = this.classname	
	resultList.style.display = "none";
	this.resultList = resultList;
	
	this.textbox.parentNode.appendChild(this.resultList);
	
	this.updateResultListPosition(this.textbox, this.resultList);
	
	this.textbox.onblur = function(e)
	{
	    (!e)?e = window.event:false;
		tempThis.resultList.style.display = "none";
	}	

	this.textbox.onfocus = function(e)
	{
	    (!e)?e = window.event:false;
		tempThis.handleKeyUp(e);
	}
	
	this.textbox.onkeyup = function(e)
	{
		(!e)?e = window.event:false;
		tempThis.handleKeyUp(e);		
	}
}

TriveSuggest.prototype.updateResultListPosition = function(textbox, resultList)
{
	resultList.style.width = Element.getWidth(textbox) + 'px';
	resultList.style.position = "absolute";
	resultList.style.top = (this.findPos(textbox)[1] + Element.getHeight(textbox)) + 'px';
	resultList.style.left = this.findPos(textbox)[0] + 'px';
}

TriveSuggest.prototype.handleKeyUp = function(e)
{
	if(e != null)
	{
	    if(this.textbox.value.length <= this.when){
	        this.resultList.style.display = 'none';
	        location.href = "#foo";
	    }
	    
		var keyCode = e.keyCode;
		if (keyCode != 8 && keyCode < 32 || (keyCode >= 33 && keyCode <= 46) || (keyCode >= 112 && keyCode <= 123))
		{
			//handler for non-char keys
			(keyCode == 40)?this.makeNodeActive(this.activeNode + 1):false;
			(keyCode == 38)?this.makeNodeActive(this.activeNode - 1):false;
			(keyCode == 13)?this.selectActiveNode():false;
			return;
		}

	}
	
	(this.textbox.value.length == this.when)?this.populateXmlObject(this.textbox.value):false;
	(this.textbox.value.length >= this.when && this.xmlObject)?this.filterAndPublishXmlObject(this.textbox.value):false;
	this.activeNode = -1;
}

TriveSuggest.prototype.populateXmlObject = function(searchString)
{
	var tempThis = this;
	new Ajax.Request(this.url + this.textbox.value, {
	 	method: 'get',
	  	onLoading: function()
	 	{
			tempThis.resultList.style.display = "block";
			tempThis.resultList.innerHTML = '<li>' + tempThis.loadingMessage + '</li>';
	 	},
		onSuccess: function(transport) {
			if(transport.responseText != '') {
				tempThis.xmlObject = transport.responseXML;
				tempThis.filterAndPublishXmlObject(searchString);
			}
			else {
				tempThis.resultList.innerHTML = '';
				tempThis.resultList.style.display = 'none';
			}
		}
	});
}

TriveSuggest.prototype.filterAndPublishXmlObject = function(searchString)
{
	this.updateResultListPosition(this.textbox, this.resultList);
	
	var tempThis = this;
	var items = this.xmlObject.getElementsByTagName('item');
	
	//clear resultList
	while (this.resultList.hasChildNodes())
	{
	  this.resultList.removeChild(this.resultList.firstChild);
	}
	
	//iterate thru the xmlObject
	for (var i=0; i<items.length; i++) {
		var nodeValue = items.item(i).firstChild.nodeValue;
		
		//match nodes to the inputfield and filter
		if(nodeValue.toLowerCase().indexOf(this.textbox.value.toLowerCase()) == "0")
		{
      		var el = document.createElement('li');
			el.onmouseover = function(el)
			{
				this.className = "active";
			}
			el.onmouseout = function(el)
			{
				this.className = "";
			}
			el.onmousedown = function(el)
			{
				tempThis.textbox.value = this.innerHTML;
			}
			
			el.innerHTML = nodeValue;
			this.resultList.appendChild(el);
		}
		//(i == items.length -1)?typeAhead(searchString):false;
	}
	
	
	var p = 0;
	this.resultArray.clear();
	
	var tempThis = this;
	
	for(i=0;i<tempThis.resultList.childNodes.length;i++)
	{
		function registerHit()
		{
			tempThis.resultArray[p] = tempThis.resultList.childNodes[i];
			p++;
		}
			
		var hit = tempThis.resultList.childNodes[i].innerHTML;
		(hit != undefined)?registerHit():false;
	}
	
	(this.resultArray.length > 0)?this.resultList.style.display = 'block':this.resultList.style.display = 'none';
	
}

TriveSuggest.prototype.makeNodeActive = function(nodeId)
{
	//reset current
	(this.activeNode != "-1")?this.resultArray[this.activeNode].className = null:false;

	//update
	(nodeId >= this.resultArray.length)?nodeId=0:false;
	(nodeId <= -1)?nodeId=this.resultArray.length-1:false;
	
	this.resultArray[nodeId].className = 'active'; 
	this.textbox.value = this.resultArray[nodeId].innerHTML;
	this.activeNode = nodeId;
}

TriveSuggest.prototype.selectActiveNode = function()
{
	this.textbox.value = this.resultArray[this.activeNode].innerHTML;
	this.resultList.style.display = "none";
}

TriveSuggest.prototype.findPos = function(obj) {
	var curleft = curtop = 0;
	if (obj.offsetParent) {
		curleft = obj.offsetLeft
		curtop = obj.offsetTop
		while (obj = obj.offsetParent) {
			curleft += obj.offsetLeft
			curtop += obj.offsetTop
		}
	}
	return [curleft,curtop];
}
