(function($){
    $.fn.extend({
        sugguest: function(options) {
            var defaults = {
                minLength: 3,
                timeOut: 500,
                suggestCSS: {
                    width: "200px",
                    cursor: "pointer",
                    padding: "0 0 0 10px"
                }
            };
            var settings = $.extend({}, defaults, options);

            var object = $(this);
            var timer = undefined;

            var search = function() {
                // timer system: only trigger getResult after timeOut
                if (timer != undefined) {
                    clearTimeout(timer);
                }
                timer = setTimeout(function() {
                    getResult(object.val());
                }, settings.timeOut);
            };

            var getResult = function(keyword) {
                // get lastKeyword saved in data
                var lastKnownSearch = $("body").data("lastKeyword");
                // halt script if the keyword is the same as last searched
                if (lastKnownSearch === keyword) {
                    return false;
                }

                // make sure keyword is longer than minLength
                if (object.val().length < settings.minLength) {
                    object.next(".suggestion").html("<ul></ul>").hide();
                    return false;
                }

                // save current keyword to data before sending out ajax request
                $("body").data("lastKeyword", keyword);

                // now the moment of truth
                $.getJSON(
                        "/search.php",
                        {search: keyword, action: "suggest"},
                        function(data) {
                            if (data) {
                                object.next(".suggestion").html("<ul></ul>");
                                $.each(data, function(index, suggestion) {
                                    object.next(".suggestion").find("ul").append("<li>" + suggestion + "</li>");
                                });
                                object.next(".suggestion").show();
                            }
                        }
                );
            };

            // apply style on input
            $(this).attr("autocomplete", "off");

            // create autocomplete div
            var suggestion = $("<div />")
                           .addClass("suggestion")
                           .hide()
                           .css(settings.suggestCSS);
            $(this).after(suggestion);

            // bind suggestion click behavior
            $(".suggestion").delegate("li", "click", function() {
                $(this).parents(".suggestion").prev().val($(this).html());
            });

            // bind on keyup
            $(this).bind("keyup", function(data, obj) {
                if (data.keyCode != 37 && data.keyCode != 38 && data.keyCode != 39 && data.keyCode != 40) {
                    search();
                }
            });

            $(this).bind("keydown", function(data, obj) {
                if ($(".suggestion li").length > 0) {
                    if (data.keyCode == 38) {
                        $(".suggestion .current").removeClass("current").prev().addClass("current");
                        $(this).val($(".suggestion .current").html());
                    } else if (data.keyCode == 40) {
                        if ($(".suggestion .current").length > 0) {
                            $(".suggestion .current").removeClass("current").next().addClass("current");
                        } else {
                            $(".suggestion li").first().addClass("current");
                        }
                        $(this).val($(".suggestion .current").html());
                    }


                }
            });
        }
    });
})(jQuery);

// usage
// $("input[name=search]").sugguest();
