(function($) {

    var keyup = 38, keydown= 40, enter = 13, tab = 9;
    var activeOptions = null;

    $.fn.dropdown = function() {

        this.each(function() {
            var selectControl = this;

            var selected = $('<input>').addClass('dropdown').click(function(event) {
                event.stopPropagation();
                var dropdown = $(this).prev(); // the ol with options
                if (activeOptions && activeOptions.context == dropdown.context && !activeOptions.hasClass('hidden')) {
                    hideActiveDropdown();
                    return;
                }
                hideActiveDropdown();
                var p = $(this).position();
                selected.focus();
                dropdown.css('left', (p.left - 3) + 'px').css('top', p.top + $(this).outerHeight() + 'px').removeClass('hidden');
                activeOptions = dropdown;
                // $(#invisibleStretcher).css('height', dropdown.css('height'));
            }).keydown(function(event) {

                if (event.keyCode != tab) event.preventDefault();

                switch (event.keyCode) {
                    case keyup:
                        selectItem($('option:selected', selectControl).prev());
                        break;
                    case keydown:
                        selectItem($('option:selected', selectControl).next());
                        break;
                    case enter:
                        $(selectControl).parents('form').submit();
                        break;
                }
            });

            var options = $('<ol>').addClass('hidden plain options');
            $('option', this).each(function() {
                var option = this
                $('<li>').text($(this).text()).click(function(event) { event.stopPropagation();
                    selectItem($(option));
                    hideActiveDropdown();
                }).appendTo(options);
            });

            function hideActiveDropdown() {
                if (activeOptions) activeOptions.addClass('hidden');
            }

            function selectItem(item) {
                if (item.length > 0) {
                    var currentSelectedItem = $('option:selected', selectControl);
                    currentSelectedItem.removeAttr('selected');
                    item.attr('selected', 'selected');
                    selected.val(item.text()).trigger('change');

                    var index = $('option', selectControl).index(item);
                    var elems = $('li', options).removeClass('selected');
                    $(elems.get(index)).addClass('selected');
                }
            }

            $(document).click(hideActiveDropdown);

            selectItem($('option:selected', selectControl));

            var wrapper = $('<div>').addClass('selectBox').append(
                $('<div>').addClass('wrapper').append(options).append(selected).click(function(event) {
                     event.stopPropagation();
                     selected.click();
                })
            );
            $(selectControl).addClass('hidden').after(wrapper);
        });
    }

})(jQuery);
