    var __SUGGEST_AUTOSUBMIT = false;
    var __SUGGEST_LIMIT = 10;
    var __SUGGEST_WIDTH = 'auto';



    // ridici fce pro suggest //////////////////////////////////////////////////
    function suggest(input, action, settings)
    {

    
        var newAttr = document.createAttribute("autocomplete");
        newAttr.nodeValue = "off"
        input.setAttributeNode(newAttr);

        var sg = null;

        // ziska suggest ////////
        for(i = 0; i < suggests.length; i++)
            if(suggests[i].input == input)
            {
                sg = suggests[i];
                break;
            }

        if(sg == null)
        {
            suggests[suggests.length] = sg = new __suggest(input, action);
            sg.index = suggests.length - 1;
            sg.selectRow = -1;
            sg.over = false;
            sg.settings = settings;
            input.onblur = function() { if(!sg.over) sg.close(); };
            input.onkeydown = function(e)
            {
                key = (e)? e.keyCode: event.keyCode;
                //if(key == 13 && sg.state == 'open' && sg.settings.onSubmitSuggest) { sg.settings.onSubmitSuggest(sg.input, sg.dat[sg.selectRow]); }; // event onSubmitSuggest
                //if(key == 13 && (sg.state == 'close')) { sg.submitForm(); };
                if(key == 40 && input.value.length > 0 && sg.state == 'open' && sg.selectRow < sg.cntRow - 1) { sSelectRow(sg.selectRow+1, sg.index); };
                if(key == 38 && input.value.length > 0 && sg.state == 'open' && sg.selectRow > 0) { sSelectRow(sg.selectRow-1, sg.index); };
                if(key == 13 && sg.state == 'open') { if(sg.selectRow == -1) sg.selectRow = 0; sSelectValue(sg.index); }
            };
            input.onkeyup = function(e)
            {
                key = (e)? e.keyCode: event.keyCode;
                if((key == 13 || key == 27 || input.value.length == 0) && sg.state != 'close') { sg.close(); };
                if(key != 13 && key != 27 && input.value.length > 0 && input.value != sg.oldValue && sg.state == 'open') { sg.data(); };
                if(key != 13 && key != 27 && input.value.length > 0 && input.value != sg.oldValue && sg.state != 'open') { sg.open(); sg.data(); };
                sg.oldValue = input.value;
            };
            input.onkeypress = function(e)
            {
                key = (e)? e.keyCode: event.keyCode;
                if(key == 13 && !settings.autosubmit) return false;
            }
        }
    }


    // konstruktor /////////////////////////////////////////////////////////////
    function __suggest(input, action)
    {
        this.input = input;
        this.action = action;
        this.state = 'close';

        this.open = sOpen;
        this.close = sClose;
        this.data = sData;
        this.showData = sShowData;
        this.submitForm = sSubmitForm;
    }

    // prida suggest do html ///////////////////////////////////////////////////
    function sOpen()
    {
        if(this.state == 'open') return;
        this.state = 'open';

        var pos = [0, 0];
        var eo = this.input;
    	while (eo.offsetParent)
        {
           	pos[0] += eo.offsetLeft;
    		pos[1] += eo.offsetTop;
    		eo = eo.offsetParent;
    	}

    	pos[0] += eo.offsetLeft;
    	pos[1] += eo.offsetTop + this.input.offsetHeight;

        this.suggestBox = document.createElement("div");
        this.suggestBox.style.position = 'absolute';
        this.suggestBox.style.left = pos[0] + (this.settings.left? this.settings.left : 0) + 'px';

        this.suggestBox.style.top = pos[1] + 'px';
        this.suggestBox.style.zindex = '1000000';

        var w = this.input.offsetWidth;
        if(this.settings && this.settings.width > 0) w = this.settings.width;
        else if(__SUGGEST_WIDTH > 0) w = __SUGGEST_WIDTH;

        this.suggestBox.style.width = w + "px";

        this.suggestBox.className = (this.settings.className)
            ? 'suggestBox ' + this.settings.className
            : 'suggestBox';
        this.suggestBox.style.display = 'none';
        this.suggestBox.style.overflow = 'hidden';

        document.body.appendChild(this.suggestBox);


    }

    // odebere suggest z html //////////////////////////////////////////////////
    function sClose()
    {
        if(this.state == 'close') return;
        this.state = 'close';
        this.over = false;

        document.body.removeChild(this.suggestBox);
    }

    // nacte data do suggest ///////////////////////////////////////////////////
    function sData()
    {

        if(this.state != 'open') return;
        sg = this;

        var _data = {'value': this.input.value};
        if(this.settings && this.settings.limit > 0) _data.limit = this.settings.limit;
        else if(__SUGGEST_LIMIT > 0) _data.limit= __SUGGEST_LIMIT;

        var req = new Request({
            url: this.action,
            method: 'post',
            onSuccess: function(oRes){
                sg.showData(oRes);
    		},
    		data: _data

    	}).send();
    	
        
    }

    // zobrazeni dat ///////////////////////////////////////////////////////////
    function sShowData(oRes)
    {
        res = eval(oRes);
        this.suggestBox.style.display = (res.length > 0)? 'block': 'none';
        this.selectRow = -1;
        this.cntRow = res.length;
        this.dat = res;
        sg = this;
        var inr = '<table onmouseover="sg.over=true;" onmouseout="sg.over = false;" style="border-collapse: collapse; width: ' + this.suggestBox.style.width.toString() + '">';

        for(i = 0; i < res.length; i++)
        {
            inr += "<tr style='cursor: default' class='suggestRow' onclick='sSelectValue(" + this.index + ");suggests[" + this.index + "].input.focus();' onmouseover='sSelectRow(" + i + ", " + this.index + ")'>";

            inr += "<td>" + res[i][0] + "</td>";

            //if(res[i].length > 1)
            //    inr += "<td class='rightColumn'>" + res[i][1] + "</td>";

            inr += "</tr>";
        }

        inr += '</table>';
        this.suggestBox.innerHTML = inr;
        sSelectRow(0, sg.index);
    }

    //
    function sSelectRow(selectRow, instance)
    {
        _this = suggests[instance];
        _this.selectRow = selectRow;
        trList = _this.suggestBox.getElementsByTagName('tr');
        for(i = 0; i < trList.length; i++)
            trList[i].className = (i == selectRow)? 'suggestRowSelect' : 'suggestRow';
    }

    //
    function sSelectValue(instance)
    {
        _this = suggests[instance];

        // onSubmitSuggest
        if(_this.settings.onSubmitSuggest)
            _this.settings.onSubmitSuggest(_this.input, _this.dat[_this.selectRow]);

        _this.input.value = _this.dat[_this.selectRow][1];///////////////////// co se mazobrazit
        _this.oldValue = undefined;
        _this.close();
        if((_this.settings && _this.settings.autosubmit) || __SUGGEST_AUTOSUBMIT)
            _this.submitForm();
    }

    //
    function sSubmitForm()
    {
        /*var pr = _this.input.parentNode;
            while (pr.parentNode)
            {
               	if(pr.tagName.toString().toLowerCase() == 'form')
               	{
               	    pr.submit();
               	    break;
                }
                pr = pr.parentNode;
        	}*/
    }

    // pole instanci
    var suggests = [];