(function($) {
    
    $.fn.selectreplace = function () {
        return $(this).each(function() {
            var select = $(this);
            select.hide(0);
            
            var optlist = $(document.createElement('ul')); // list for select options
            var optdiv = $(document.createElement('div')).attr('class', 'replace').append(optlist); // holds the list
            var actval = $(document.createElement('div')).attr('class', 'actval'); // holds the actual selected value
            var fs = $(document.createElement('div')).attr('class', 'form-select') // overall element
                .append(actval)
                .append(optdiv);
                
            select.children('option').each(function() {
                var option = $(this);
                var lia = $(document.createElement('a'))
                        .attr('href', option.val())
                        .addClass(option.attr('class'))
                        .text(option.text());
                        
                if(option.hasClass('external'))
                    lia.attr('target', '_blank');
                    
                var optli = $('<li></li>').append(lia);
                
                if (option.attr('disabled')) {
                    optli.addClass('disabled');
                    lia.click(function() { return false; });
                }
                else {
                    optli.mouseover(function(){
                        $(this).siblings('.hover').removeClass('hover');
                        $(this).addClass('hover');
                    });
                    optli.mouseout(function(){
                        $(this).removeClass('hover');
                    });
                }
                
                optlist.append(optli);
            });
            
            if(actval.text() == '')
                actval.text(select.children(':first').text());
            
            $(document).click(function(e) {
                if(optdiv.css('display') == 'block')
                    actval.trigger('click');
            });
            actval.click(function (e) {
                e.stopPropagation();
                if (optdiv.css('display') == 'block') {
                    $(document).unbind('keydown');
                    optlist.children('.hover').removeClass('hover');
                }
                else 
                    $(document).bind('keydown', function(e){
                        $.select.keyHandler(e, optlist);
                    });
                
                d = optdiv.css('display') == 'block' ? optdiv.fadeOut(650) : optdiv.fadeIn(650);
            });
            
            select.after(fs);
            optdiv.hide(0);
        });
    }
    
    $.select = function() {}
    
    $.select.keyHandler = function(e, list) {
        
        if ((65 <= e.keyCode && e.keyCode <= 90) || e.keyCode == 13 || e.keyCode == 27 || e.keyCode == 38 || e.keyCode == 40) {
            e.stopPropagation();
            e.preventDefault();
        }
        else 
            return;
        
        if (65 <= e.keyCode && e.keyCode <= 90) {
            actElem = $.select.getElemByChar(e.keyCode, list);
            
            if (actElem == false)
                return;
            
            actElem.siblings('.hover').removeClass('hover');
            actElem.addClass('hover');
        }
        
        switch (e.keyCode) {
        
            case 13: // enter key
                window.location = list.children('.hover').children('a').attr('href');
                break;
                
            case 27: // esc key
                actval.trigger('click');
                break;
                
            case 38: // arrow up key
                if (list.children('.hover:not(.disabled)').length == 0)
                    list.children(':last').addClass('hover');
                else {
                    if (list.children('.hover:not(.disabled)').prev(':not(.disabled)').length > 0)
                        list.children('.hover:not(.disabled)').removeClass('hover').prev(':not(.disabled)').addClass('hover');
                    else
                        list.children('.hover:not(.disabled)').removeClass('hover').siblings(':last').addClass('hover');
                }
            break;
                
            case 40: // arrow down key
                if (list.children('.hover:not(.disabled)').length == 0)
                    list.children(':not(.disabled)').eq(0).addClass('hover');
                else {
                    if (list.children('.hover:not(.disabled)').next(':not(.disabled)').length > 0)
                        list.children('.hover:not(.disabled)').removeClass('hover').next(':not(.disabled)').addClass('hover');
                    else
                        list.children('.hover:not(.disabled)').removeClass('hover').siblings(':not(.disabled)').eq(0).addClass('hover');
                }
            break;
        }
        
        /*_to = null;
        
        if(actElem != null && actElem != false && selectNeedToScroll(actElem)) {
            if(selectNeedToScrollUp(actElem)) {
                //_to = setTimeout(function() { selectScrollDown(); }, 20);
                var _newTop = actElem.position().top - optdiv.children('.moreLeft').height();
                
                if (_newTop < 0)
                    _newTop = 0;
                
                optlist.css('top', -_newTop);
                $.scroller.scrollUp(optlist, 0);
            }
            if(selectNeedToScrollDown(actElem)) {
                var _newTop = actElem.position().top - optdiv.height() + optdiv.children('.moreRight').height() + actElem.height();
                
                if (_newTop > optlist.height() - optdiv.height())
                    _newTop = optlist.height() - optdiv.height();
                
                optlist.css('top', -_newTop);
                $.scroller.scrollUp(optlist, 0);
            }
        }*/
        
        //return false;
    }
    
    $.select.getElemByChar = function(key, list) {
        var elem = false;
        
        if (list.children('li.hover:not(.disabled)').length > 0 &&
            list.children('li.hover:not(.disabled)').next().text().toLowerCase().charCodeAt(0) == key + 32) {
            elem = list.children('li.hover:not(.disabled)').next();
        }
        else {
            list.children('li:not(.disabled)').each(function(){
                if ($(this).text().toLowerCase().charCodeAt(0) == key + 32) 
                    if (elem == false && !$(this).hasClass('hover')) 
                        elem = $(this);
            });
        }
        return elem;
    }
    
})(jQuery)

