/**
 * Update by Davide Redaelli
 * date: 13.01.2011
 */
//create cross-browser indexOf
if(!Array.prototype.indexOf){
    Array.prototype.indexOf=function(obj,start){
        for(var i=(start||0),j=this.length;i<j;i++){
            if(this[i]===obj){
                return i;
            }
        }
        return -1;
    }
}

jQuery.fn.sSelect = function(options) {

    return this.each(function(){

        var defaults = {
            defaultText: 'Please select',
            objWidth: false,
            fixPos: false
        };


        //initial variables
        var opts = jQuery.extend(defaults, options),
        $oldSelectBox = jQuery(this),
        $newSelectBox = jQuery('<input type="text" autocomplete="off" readonly="readonly" class="newSelectBox" id="newSelectBox_'+$oldSelectBox.attr("id")+'" name="newSelectBox_'+$oldSelectBox.attr("id")+'" />'),
        $containerSelectBox = jQuery('<div class="containerSelectBox" tabindex="0" ></div>'),
        $newUl = jQuery('<ul></ul>'),

        itemIndex = -1,
        currentIndex = -1,
        disabledIndex = -1,
        keys = [],
        prevKey = false,
        newListItems = ''

        //build new list
        $containerSelectBox.insertAfter($oldSelectBox);
        $newSelectBox.insertAfter($oldSelectBox);
        $newUl.appendTo($containerSelectBox);
        $oldSelectBox.hide();

        var $newLi;

        
            $oldSelectBox.children('option').each(function(i){
                var option = jQuery(this).text();
                //add first letter of each word to array
                keys.push(option.charAt(0).toLowerCase());
                if (jQuery(this).attr('selected') == true){
                    opts.defaultText = option;
                    currentIndex = i;
                }
                if (jQuery(this).attr('disabled') == true){
                    disabledIndex = i;
                }
                newListItems += '<li>'+option+'</li>';
            });
            //add new list items to ul
            $newUl.html(newListItems);


        //test for optgroup
        if ($oldSelectBox.children('optgroup').length == 0){            
            //cache list items object
            $newLi = $newUl.children();
        }else{                                 
            $oldSelectBox.children('optgroup').each(function(i){
                 newListItems = '';
                var optionTitle = jQuery(this).attr('label'),
                $optGroup = jQuery('<li><span class="newListOptionTitle">'+optionTitle+'</span></li>');

                $optGroup.appendTo($newUl);

                var $optGroupList = jQuery('<ul></ul>');

                $optGroupList.appendTo($optGroup);

                jQuery(this).children('option').each(function(){
                    ++itemIndex;
                    var option = jQuery(this).text();
                    //add first letter of each word to array
                    keys.push(option.charAt(0).toLowerCase());                    
                    if (jQuery(this).attr('selected') == true){
                        opts.defaultText = option;
                        currentIndex = itemIndex;
                    }
                    if (jQuery(this).attr('disabled') == true){
                        disabledIndex = itemIndex;
                    }                   
                    newListItems += '<li>'+option+'</li>';                    
                })
                //add new list items to ul
                $optGroupList.html(newListItems);
                newListItems = '';
            });
           
            //cache list items object
            $newLi = $newUl.find('li:not(:has(>ul))');
        }

         

       
        //check if a value is selected
        if (currentIndex != -1){
            navigateList(currentIndex);
        } else {
            //set placeholder text
            $newSelectBox.val(opts.defaultText);
        }

        if (disabledIndex != -1){
            $newLi.eq(disabledIndex).addClass('disabledItem');
        }

        var newLiLength = $newLi.length;
        

        //******************************************FIX WIDTH*****************************************
        if (defaults.objWidth){
            $containerSelectBox.css('width', defaults.objWidth+'px');
        }
        plr=parseInt($newSelectBox.css("padding-left"))+parseInt($newSelectBox.css("padding-right"));
        wTot=$containerSelectBox.width();
        $newSelectBox.css('width', (wTot-plr)+'px');
        $containerSelectBox.css('width', wTot+'px');
        //*******************************************************************************************


        //positioning
        function positionFix(){
            //****************FIX POSITION*****************
            var position = $newSelectBox.position();
            pl=position.left;
            ptb=$newSelectBox.outerHeight();
            if ($.browser.msie && $.browser.version.substr(0,1)<=7) {
                pl=pl+2;
                ptb=ptb+2;
            }
            $containerSelectBox.css('left' , pl + "px" );
            $containerSelectBox.css('top' , (position.top +ptb)+ "px");            
            //*********************************************
        }


        //decide if to place the new list above or below the drop-down
        function newUlPos(){
            positionFix();
            if (defaults.fixPos){
                var containerSelectBoxPosY = parseInt($containerSelectBox.css('top')),
                containerSelectBoxHeight = $containerSelectBox.height()+parseInt($containerSelectBox.css("padding-top"))+parseInt($containerSelectBox.css("padding-bottom")),
                newSelectBoxHeight= $newSelectBox.height()+parseInt($newSelectBox.css("padding-top"))+parseInt($newSelectBox.css("padding-bottom")),
                scrollTop = jQuery(window).scrollTop(),
                docHeight = jQuery(window).height(),
                containerSelectBoxPosY = containerSelectBoxPosY-scrollTop,
                newContainerSelectBoxPosY = containerSelectBoxPosY-containerSelectBoxHeight-newSelectBoxHeight


                if (containerSelectBoxPosY+containerSelectBoxHeight >= docHeight){
                    $containerSelectBox.css('top', newContainerSelectBoxPosY+'px');
                }
            }
        }

        //run function on page load
        newUlPos();

        //run function on browser window resize
        jQuery(window).resize(function(e){
            newUlPos(e);
        });

        jQuery(window).scroll(function(e){
            newUlPos(e);
        });

        $newSelectBox.click(function(){
            if ($containerSelectBox.is(':visible')){
                $containerSelectBox.hide();
                return false;
            }
            positionFix();
            if ($.browser.msie && $.browser.version.substr(0,1)<=6) {
                $containerSelectBox.show();
            }else{
                $containerSelectBox.slideDown("fast");
            }
            $containerSelectBox.focus();
            keyPress(this);
        });
        $newSelectBox.focus(function(){
            keyPress(this);
        });
        $containerSelectBox.focus(function(){
            $newSelectBox.addClass("newSelectBoxFocus");
            $containerSelectBox.addClass("newSelectBoxFocus");
            keyPress(this);
        });

        //hide list on blur
        $containerSelectBox.blur(function(){
            $newSelectBox.removeClass("newSelectBoxFocus");
            $containerSelectBox.removeClass("newSelectBoxFocus");
            $containerSelectBox.hide();
        });

        $newSelectBox.hover(function(e) {
            var $hoveredTxt = jQuery(e.target);
            $hoveredTxt.addClass('newSelectBoxHover');
        },
        function (e) {
            var $hoveredTxt = jQuery(e.target);
            $hoveredTxt.removeClass('newSelectBoxHover');
        }
        );

        $newLi.hover(
            function (e) {
                var $hoveredLi = jQuery(e.target);
                if(!$hoveredLi.hasClass('disabledItem')){
                    $hoveredLi.addClass('newListHover');
                }
            },
            function (e) {
                var $hoveredLi = jQuery(e.target);
                $hoveredLi.removeClass('newListHover');
            }
            );

        $newLi.click(function(e){
            var $clickedLi = jQuery(e.target),
            text = $clickedLi.text();            
            if(!$clickedLi.hasClass('disabledItem')){
                //update counter
                currentIndex = $newLi.index($clickedLi);
                //remove all hilites, then add hilite to selected item
                $newLi.removeClass('selectedItem');
                $clickedLi.addClass('selectedItem');

                setSelectText(text,currentIndex);
                $containerSelectBox.hide();
            }
        });

        function setSelectText(text,currentIndex){                        
            $oldSelectBox.find("option:eq("+currentIndex+")").attr("selected", true).change();
            //set text of select box
            $newSelectBox.val(text);
        }

        //handle up and down keys
        function keyPress(element) {
            //when keys are pressed
            element.onkeydown = function(e){
                if (e == null) { //ie
                    var keycode = event.keyCode;
                } else { //everything else
                    var keycode = e.which;
                }
                switch(keycode)
                {
                    case 40: //down
                    case 39: //right
                        incrementList();
                        return false;
                        break;
                    case 38: //up
                    case 37: //left
                        decrementList();
                        return false;
                        break;
                    case 33: //page up
                    case 36: //home
                        gotoFirst();
                        return false;
                        break;
                    case 34: //page down
                    case 35: //end
                        gotoLast();
                        return false;
                        break;
                    case 13: //return
                        $containerSelectBox.hide();
                        return false;
                        break;
                    case 27:
                        $containerSelectBox.hide();
                        return false;
                        break;
                }

                //check for keyboard shortcuts
                keyPressed = String.fromCharCode(keycode).toLowerCase();
                var currentKeyIndex = keys.indexOf(keyPressed);
                if (typeof currentKeyIndex == 'number' && currentKeyIndex!=-1) { //if key code found in array
                    if (e == null) { //ie
                    //nothing
                    }else{
                        e.preventDefault();
                    }
                    ++currentIndex;
                    currentIndex = keys.indexOf(keyPressed, currentIndex); //search array from current index
                    if (currentIndex == -1 || currentIndex == null || prevKey != keyPressed) currentIndex = keys.indexOf(keyPressed); //if no entry was found or new key pressed search from start of array
                    navigateList(currentIndex);
                    //store last key pressed
                    prevKey = keyPressed;
                }
            }
        }

        function incrementList(){
            if (currentIndex < (newLiLength-1)) {
                ++currentIndex;
                navigateList(currentIndex);
            }
        }

        function decrementList(){
            if (currentIndex > 0) {
                --currentIndex;
                navigateList(currentIndex);
            }
        }

        function gotoFirst(){
            currentIndex = 0;
            navigateList(currentIndex);
        }

        function gotoLast(e){
            currentIndex = newLiLength-1;
            navigateList(currentIndex);
        }

        function navigateList(currentIndex){
            if(!$newLi.eq(currentIndex).hasClass('disabledItem')){
                $newLi.removeClass('selectedItem')
                .eq(currentIndex).addClass('selectedItem');
                var text = $newLi.eq(currentIndex).text();
                setSelectText(text,currentIndex);
            }
        }


    });
};

