jQuery.fn.autocomplete = function(u, valueInput, s) {
    return this.each(function() {
        var t = $(this);
        var v = $(this).next();
        v.after('<ul class="ac"></ul>');
        var list = v.next().css({ top: t.offset().top + t.outerHeight(), left: t.offset().left, width: t.width() });
        var o = '', to, z = 0, l = 0;

        s = jQuery.extend(
		{
		    minChars: 3,
		    timeout: 250,
		    after: null,
		    before: null,
		    vs: true,
		    parameters: {}
		}, s);

        function getData(text) {
            window.clearInterval(to);
            if (text != o && (s.minChars != null && text.length >= s.minChars)) {
                clear();
                if (s.before != null) {
                    s.before(s.parameters);
                }
                t.addClass('acl');
                s.parameters.t = text;
                $.getJSON(u, s.parameters, function(d) {
                    var items = '';
                    if (d) {
                        z = d.length;
                        for (i = 0; i < d.length; i++) {
                            for (key in d[i]) {
                                items += '<li val="' + key + '">' + d[i][key].replace(new RegExp("(" + text + ")", "i"), "<b>$1</b>") + '</li>';
                            }
                            list.html(items);
                            list.show().children().
						        hover(function() { $(this).addClass("s").siblings().removeClass("s"); }, function() { $(this).removeClass("s") }).
						        click(function() { valueInput.val($(this).attr('val')); t.val($(this).text()); clear(); });
                        }
                        if (s.after != null) {
                            s.after(t, text);
                        }
                    }
                    t.removeClass('acl');
                });
                o = text;
            }
        }

        function clear() {
            list.hide();
            z = 0;
            l = 0;
        }

        $(document).click(function() { clear(); });
        t.keydown(function(e) {
            window.clearInterval(to);
            if (e.which == 27) {
                clear();
            } else if (e.which == 46 || e.which == 8) {
                clear();
                if (s.vs) valueInput.val('');
            }
            else if (e.which == 13) {
                if (list.css("display") == "none") {
                    getData(t.val());
                } else {
                    clear();
                }
                e.preventDefault();
                return false;
            }
            else if (e.which == 40 || e.which == 9 || e.which == 38) {
                switch (e.which) {
                    case 40:
                    case 9:
                        l = l >= z - 1 ? 0 : l + 1; break;
                    case 38:
                        l = l <= 0 ? z - 1 : l - 1; break;
                    default: break;
                }
                t.val(list.children().removeClass('s').eq(l).addClass('s').text());
                valueInput.val(list.children().eq(l).attr('val'));
            } else {
            if (s.vs) valueInput.val('');
                to = window.setTimeout(function() { getData(t.val()) }, s.timeout);
            }
        });
    });
};