var br= /<\S[^><]*>/g;
var VK_UP = 38,
	VK_DOWN = 40,
    VK_RETURN = 13,
    VK_RIGHT = 39;

SuggestMenu = function(textBox, layerName, dataSource)
{
    var layer = document.createElement("ul");
    layer.className = "suggestion_menu";
    layer.id = layerName;
    layer.style.position = 'absolute';
    layer.style.display = 'none';
    
    var inBody = document.getElementsByTagName("body").item(0);
    inBody.insertBefore(layer, inBody.firstChild);
    
    this.textBox = $(textBox);
	this.layer = $(layer);
	this.dataSource = dataSource;
	this.controlKeys = new Array(VK_UP, VK_DOWN, VK_RETURN);
    
    this.textBox.setAttribute("autocomplete", "off");
    this.textBox.addEvent("keypress", this.keyPress.handler(this));
    this.textBox.addEvent("keydown", this.keyDown.handler(this));
    this.textBox.addEvent("blur", this.blur.handler(this));
}

SuggestMenu.prototype =
{
	textBox: null,
	layer: null,
	dataSource: null,
	controlKeys: null,
    timeoutId: null,

    lighted: -1,
	itemList: new Array(),
	
	classLight: 'highlight',
	classUnLight: '',
    typingTimeout: 50,
    isOpen: false,
	
	selectRange: function (iStart, iLength)
	{
        if(this.textbox.createTextRange)
    	{
            var oRange = this.textbox.createTextRange(); 
            oRange.moveStart("character", iStart); 
            oRange.moveEnd("character", iLength - this.textBox.value.length); 
            oRange.select();
        } 
    	else if (this.textBox.setSelectionRange)
    	{
            this.textbox.setSelectionRange(iStart, iLength);
        } 
    
        this.textBox.focus(); 
	},

    updateLayer: function()
    {
        this.dataSource.query(this.textBox.value, this.dataSourceSuccess.handler(this));
    },
    
    dataSourceSuccess: function(sugestionArray)
    {
        this.lighted = -1;
        this.layer.innerHTML = "";
        this.itemList.length = 0;

        for(var i = 0; i < sugestionArray.length; i++)
        {
		    var row = sugestionArray[i]; 
            var suggestionItem = $(document.createElement("li"));

            suggestionItem.innerHTML = row.word;
			suggestionItem.itemIndex = i;
            suggestionItem.word = row.word;
			suggestionItem.addEvent("mouseover", this.mouseOver.handler(this));
			suggestionItem.addEvent("mousedown", this.mouseDown.handler(this));
            
            this.layer.appendChild(suggestionItem);
			this.itemList[i] = suggestionItem;
        }
      
        if(sugestionArray.length > 0)
        {
            var pos = this.textBox.findPos();
            var height = this.textBox.getHeight();
            this.layer.setPos(pos.x, pos.y + height - 1);
        
            this.layer.show();
        }
        else
        {
            this.layer.hide();
        } 
    },
    
    handleEventDefault: function(event)
    {
        if(event.keyCode == VK_RETURN)return true;
        
        event.stopPropagation();
        event.preventDefault();
        return false;
    },
    
    keyPress: function (event)
    {
        if(inArray(event.keyCode, this.controlKeys))
        {
            this.handleEventDefault(event);
        }
    },
    
    keyDown: function (event)
    {
        if(inArray(event.keyCode, this.controlKeys))
        {
            this.isOpen = (this.layer.style.display != "none");
            
            if(this.handleEventDefault(event) == false)
            {
                this.navi(event.keyCode);
            } 
        }
        else
        {
            if(this.timeoutId)window.clearTimeout(this.timeoutId);
            this.timeoutId = window.setTimeout(this.updateLayer.handler(this), this.typingTimeout);
        }
    },
	
	mouseOver: function (event)
	{
         this.highlightSuggestion(event.obj.itemIndex);
    },
	
	blur: function (event)
	{
		this.layer.hide();
    },
	
	mouseDown: function (event)
	{
        this.textBox.value = event.obj.word;
    },
	
	navi: function(pKey)
	{
		switch(pKey)
		{
			case VK_UP: this.highlightSuggestion(Math.max(this.lighted - 1, 0)); break;
			case VK_DOWN: this.highlightSuggestion(Math.min(this.lighted + 1, this.itemList.length - 1));break;
            case VK_RIGHT:
            case VK_RETURN: this.textBox.value = this.itemList[this.lighted].word; this.layer.hide(); break; 
		}
	},
	
	highlightSuggestion : function(curIndex)
	{
		if(this.itemList.length == 0)return;
        
        this.layer.show();
        if(curIndex == this.lighted)return;
		
		if(this.lighted != -1)
		{
			this.itemList[this.lighted].className = this.classUnLight;
		}
        
		this.itemList[curIndex].className = this.classLight;
		this.lighted = curIndex;
        
        this.textBox.value = this.itemList[this.lighted].word;
	}
}