/*
Stylish Select 0.1b - jQuery plugin to replace a select drop down box with a stylable unordered list
http://scottdarby.com/

Copyright (c) 2009 Scott Darby

Requires: jQuery 1.3

Licensed under the GPL license:
http://www.gnu.org/licenses/gpl.html
*/

//create browser consistent indexOf
Array.prototype.indexOf = function (obj, start) {
	for (var i = (start || 0); i < this.length; i++) {
		if (this[i] == obj) {
			return i;
		}
	}
}

jQuery.fn.selectOptionOnText = function(text){
    return jQuery(this).each(function(){
        jQuery(this).children().each(function(){
            if(jQuery(this).is('optgroup')){
                if(jQuery(this).attr('label') === text){
                    jQuery(this).find('option:first').attr('selected','selected');
                }else{
                    jQuery(this).selectOptionOnText(text);
                }
            }else{
                if(jQuery(this).text() === text){
                    jQuery(this).attr('selected','selected');
                }
            }
        });
    });
}

jQuery.fn.getOptGoupValues = function(){
    var result = [];
    jQuery(this).children().each(function(){
        if(jQuery(this).is('optgroup')){
            result.push(jQuery(this).getOptGoupValues());
        }else{
           result.push(jQuery(this).attr('value'));
        }
    });
    return result.join(',');
}

jQuery.fn.sSelect = function(options) {
  return this.each(function(){

    var defaults = {
		defaultText: 'Please select'
    };

	//initial variables
    var opts = jQuery.extend(defaults, options);
    var $input = jQuery(this);
	var $containerDivText = jQuery('<div class="selectedTxt"></div>');
	var $newUl = jQuery('<ul class="newList"></ul>');
	var $containerDiv = jQuery('<div class="newListSelected" tabindex="0"></div>');
	var itemIndex = -1;
    var currentIndex = -1;
	var keys = [];
	var prevKey = false;

	//build new list
    $containerDiv.insertAfter($input);
	$containerDivText.prependTo($containerDiv);
	$newUl.appendTo($containerDiv);
    $input.hide();

	//test for optgroup
	//if ($input.children('optgroup').length == 0){
		$input.children().each(function(i){
            if(jQuery(this).is('optgroup')){
                var optionTitle = jQuery(this).attr('label');
                var $optGroup = jQuery('<li class="newListOptionTitle"><div class="title">'+optionTitle+'</div></li>');
                $optGroup.appendTo($newUl);
                var $optGroupList = jQuery('<ul></ul>');
                $optGroupList.appendTo($optGroup);

                jQuery(this).children().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;
                    }
                    jQuery('<li><span class="name">'+option+'</span></li>').appendTo($optGroupList);
                });

                var values = jQuery(this).getOptGoupValues();
                var optionGroupOption = jQuery('<option value="'+values+'">--</option>');
                optionGroupOption.prependTo(jQuery(this));
            }else{
                var option = jQuery(this).text();
                var classes = jQuery(this).attr('class');
                //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;
                }
                jQuery('<li class="'+classes+'"><span class="name">'+option+'</span></li>').appendTo($newUl);
            }
		});
		//cache list items object
		var $newLi = $newUl.find('li:not(.newListOptionTitle)');
        var $optionsGroups = $newUl.find('li.newListOptionTitle .title');

	if (currentIndex != -1){
		navigateList(currentIndex);
	} else {
		//set placeholder text
		$containerDivText.text(opts.defaultText);
	}

	var newLiLength = $newLi.length;

	//decide if to place the new list above or below the drop-down
	function newUlPos(){
       // console.log($containerDiv.parent().width());
		var containerPosY = $containerDiv.offset().top;
        var containerPosX = $containerDiv.offset().left;
		var containerHeight = $containerDiv.height()+3;
		var docHeight = jQuery(document).height();
		var newUlHeight = $newUl.height()+3;

		/*if (containerPosY+newUlHeight >= docHeight){
			$newUl.css('top', '-'+newUlHeight+'px');
		} else {
			$newUl.css('top', containerHeight+'px');
		}*/
        if( (containerPosX+$newUl.width()) >  $containerDiv.parent().width()){
            $newUl.css('right', '4px');
        }
	}

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

	//positioning
	function positionFix(){
		$containerDiv.css('position','relative');
	}

	function positionHideFix(){
		$containerDiv.css('position','static');
	}
	
    $containerDivText.click(function(){
		$containerDiv.addClass('active');
		
		if ($newUl.is(':visible')){
			$containerDiv.removeClass('active');
			$newUl.hide();
			positionHideFix()
			return false;
		}
		
		$containerDiv.focus();
		
		
		//show list
		$newUl.slideDown('fast');
		positionFix();
		
		//when keys are pressed
		document.onkeydown = function(e){
			if (e == null) { // ie
				var keycode = event.keyCode;
			} else { // everything else
				var keycode = e.which;
			}
			//enter key or esc key pressed, hide list
			if(keycode == 13 || keycode == 27){
				$containerDiv.removeClass('active');
				$newUl.hide();
				positionHideFix();
				//e.preventDefault();
				return false;
			}
		}
	});
		
	//hide list on blur
    $containerDiv.blur(function(){
		$containerDiv.removeClass('active');
       	$newUl.hide();
	   	positionHideFix();
    });

    $containerDivText.hover(function () {
        jQuery(this).addClass('newListSelHover');
      }, 
      function () {
        jQuery(this).removeClass('newListSelHover');
      }
    );

    $newLi.hover(
      function () {
        jQuery(this).addClass('newListHover');
      },
      function () {
        jQuery(this).removeClass('newListHover');
      }
    );

    $newLi.click(function(){
        //update counter
        currentIndex = $newLi.index(this);
        //remove all hilites, then add hilite to selected item
        $newLi.removeClass('hiLite');
        $optionsGroups.parent().removeClass('hiLite');
        jQuery(this).addClass('hiLite');
        var text = jQuery(this).text();
		setSelectText(text);
		$containerDiv.removeClass('active');
        $newUl.hide();
		$containerDiv.css('position','static');//ie
    });

    $optionsGroups.click(function(){
        //update counter
        //currentIndex = $newLi.index(this);
        //remove all hilites, then add hilite to selected item
        $newLi.removeClass('hiLite');
        $optionsGroups.parent().removeClass('hiLite');
        jQuery(this).parent('li').addClass('hiLite');
        var text = jQuery(this).text();
		setSelectText(text);
		$containerDiv.removeClass('active');
        $newUl.hide();
		$containerDiv.css('position','static');//ie
    });

	function setSelectText(text){
		//set text of select box
        //$input.val(text);
        var $option = $input.selectOptionOnText(text);
        $containerDivText.text(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;
				if (keycode != 9) {
					//everything else
					e.preventDefault(); //allow tab key
				}
            }

            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;
            }

			//check for keyboard shortcuts
			keyPressed = String.fromCharCode(keycode).toLowerCase();
			var currentKeyIndex = keys.indexOf(keyPressed);
			if (typeof currentKeyIndex != 'undefined') { //if key code found in array
				++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){
		$newLi.removeClass('hiLite');
		$newLi.eq(currentIndex).addClass('hiLite');
        var text = $newLi.eq(currentIndex).text();
		setSelectText(text);
	}
	
    $containerDiv.focus(function(){
        keyPress(this);
    });

    $containerDiv.click(function(){
        keyPress(this);
    });
	
  });
};