text: /*
  Stylish Select 0.4.1 - $ plugin to replace a select drop down box with a stylable unordered list
  http://github.com/sko77sun/Stylish-Select
  
  Requires: jQuery 1.3 or newer
  
  Contributions from Justin Beasley: http://www.harvest.org/ & Anatoly Ressin: http://www.artazor.lv/
  
  Dual licensed under the MIT and GPL licenses.
  
  */
  (function($){
  	//add class to html tag
  	$('html').addClass('stylish-select');
  
  	//create cross-browser indexOf
  	Array.prototype.indexOf = function (obj, start) {
  		for (var i = (start || 0); i < this.length; i++) {
  			if (this[i] == obj) {
  				return i;
  			}
  		}
  	}
  
  	//utility methods
  	$.fn.extend({
  		getSetSSValue: function(value){
  			if (value){
  				//set value and trigger change event
  				$(this).val(value).change();
  				return this;
  			} else {
  				return $(this).find(':selected').val();
  			}
  		},
  		//added by Justin Beasley
  		resetSS: function(){
  			var oldOpts = $(this).data('ssOpts');
  			$this = $(this);
  			$this.next().remove();
  			//unbind all events and redraw
  			$this.unbind('.sSelect').sSelect(oldOpts);
  		}
  	});
  
  	$.fn.sSelect = function(options) {
  
  		return this.each(function(){
  
  		var defaults = {
  			defaultText: 'Please select',
  			animationSpeed: 0, //set speed of dropdown
  			ddMaxHeight: '', //set css max-height value of dropdown
  			containerClass: '' //additional classes for container div
  		};
  
  		//initial variables
  		var opts = $.extend(defaults, options),
  		$input = $(this),
  		$containerDivText = $('<div class="selectedTxt"></div>'),
  		$containerDiv = $('<div class="newListSelected ' + opts.containerClass + '"></div>'),
  		$newUl = $('<ul class="newList" style="visibility:hidden;"></ul>'),
  		itemIndex = -1,
  		currentIndex = -1,
  		keys = [],
  		prevKey = false,
  		prevented = false,
  		$newLi;
  
  		//added by Justin Beasley
  		$(this).data('ssOpts',options);
  
  		//build new list
  		$containerDiv.insertAfter($input);
  		$containerDiv.attr("tabindex", $input.attr("tabindex") || "0");
  		$containerDivText.prependTo($containerDiv);
  		$newUl.appendTo($containerDiv);
  		$input.hide();
  
  		//added by Justin Beasley (used for lists initialized while hidden)
  		$containerDivText.data('ssReRender',!$containerDivText.is(':visible'));
  
              //test for optgroup
              if ($input.children('optgroup').length == 0){
                  $input.children().each(function(i){
                      var option = $(this).html();
                      var key = $(this).val();
  
                      //add first letter of each word to array
                      keys.push(option.charAt(0).toLowerCase());
                      if ($(this).attr('selected') == true){
                          opts.defaultText = option;
                          currentIndex = i;
                      }
                      $newUl.append($('<li><a href="JavaScript:void(0);">'+option+'</a></li>').data('key', key));
  
                  });
                  //cache list items object
                  $newLi = $newUl.children().children();
  
              } else { //optgroup
                  $input.children('optgroup').each(function(){
  
                      var optionTitle = $(this).attr('label'),
                      $optGroup = $('<li class="newListOptionTitle">'+optionTitle+'</li>');
  
                      $optGroup.appendTo($newUl);
  
                      var $optGroupList = $('<ul></ul>');
  
                      $optGroupList.appendTo($optGroup);
  
                      $(this).children().each(function(){
                          ++itemIndex;
                          var option = $(this).html();
                          var key = $(this).val();
                          //add first letter of each word to array
                          keys.push(option.charAt(0).toLowerCase());
                          if ($(this).attr('selected') == true){
                              opts.defaultText = option;
                              currentIndex = itemIndex;
                          }
                          $optGroupList.append($('<li><a href="JavaScript:void(0);">'+option+'</a></li>').data('key',key));
                      })
                  });
                  //cache list items object
                  $newLi = $newUl.find('ul li a');
              }
  
              //get heights of new elements for use later
              var newUlHeight = $newUl.height(),
              containerHeight = $containerDiv.height(),
              newLiLength = $newLi.length;
  
              //check if a value is selected
              if (currentIndex != -1){
                  navigateList(currentIndex, true);
              } else {
                  //set placeholder text
                  $containerDivText.text(opts.defaultText);
              }
  
              //decide if to place the new list above or below the drop-down
              function newUlPos(){
                  var containerPosY = $containerDiv.offset().top,
                  docHeight = jQuery(window).height(),
                  scrollTop = jQuery(window).scrollTop();
  
                  //if height of list is greater then max height, set list height to max height value
                  if (newUlHeight > parseInt(opts.ddMaxHeight)) {
                      newUlHeight = parseInt(opts.ddMaxHeight);
                  }
  
                  containerPosY = containerPosY-scrollTop;
                  if (containerPosY+newUlHeight >= docHeight){
                      $newUl.css({
                          top: '-'+newUlHeight+'px',
                          height: newUlHeight
                      });
                      $input.onTop = true;
                  } else {
                      $newUl.css({
                          top: containerHeight+'px',
                          height: newUlHeight
                      });
                      $input.onTop = false;
                  }
              }
  
              //run function on page load
              newUlPos();
  
              //run function on browser window resize
  			$(window).bind('resize.sSelect scroll.sSelect', newUlPos);
  
              //positioning
              function positionFix(){
                  $containerDiv.css('position','relative');
              }
  
              function positionHideFix(){
                  $containerDiv.css('position','static');
              }
  
              $containerDivText.bind('click.sSelect',function(event){
                  event.stopPropagation();
  
  				//added by Justin Beasley
  				if($(this).data('ssReRender')) {
  					newUlHeight = $newUl.height('').height();
  					containerHeight = $containerDiv.height();
  					$(this).data('ssReRender',false);
  					newUlPos();
  				}
  
                  //hide all menus apart from this one
  				$('.newList').not($(this).next()).hide()
                      .parent()
                          .css('position', 'static')
                          .removeClass('newListSelFocus');
  
                  //show/hide this menu
                  $newUl.toggle();
                  positionFix();
                  //scroll list to selected item
                  $newLi.eq(currentIndex).focus();
  
              });
  
              $newLi.bind('click.sSelect',function(e){
                  var $clickedLi = $(e.target);
  
                  //update counter
                  currentIndex = $newLi.index($clickedLi);
  
                  //remove all hilites, then add hilite to selected item
                  prevented = true;
                  navigateList(currentIndex);
                  $newUl.hide();
                  $containerDiv.css('position','static');//ie
  
              });
  
              $newLi.bind('mouseenter.sSelect',
  				function(e) {
  					var $hoveredLi = $(e.target);
  					$hoveredLi.addClass('newListHover');
  				}
  			).bind('mouseleave.sSelect',
  				function(e) {
  					var $hoveredLi = $(e.target);
  					$hoveredLi.removeClass('newListHover');
  				}
  			);
  
              function navigateList(currentIndex, init){
                  $newLi.removeClass('hiLite')
                  .eq(currentIndex)
                  .addClass('hiLite');
  
                  if ($newUl.is(':visible')){
                      $newLi.eq(currentIndex).focus();
                  }
  
                  var text = $newLi.eq(currentIndex).html();
                  var val = $newLi.eq(currentIndex).parent().data('key');
  
                  //page load
                  if (init == true){
                      $input.val(val);
                      $containerDivText.text(text);
                      return false;
                  }
  
  		try {
  		    $input.val(val)
  		} catch(ex) {
  		    // handle ie6 exception
  		    $input[0].selectedIndex = currentIndex;
  		}
  
                  $input.change();
                  $containerDivText.text(text);
              }
  
              $input.bind('change.sSelect',function(event){
                  $targetInput = $(event.target);
                  //stop change function from firing
                  if (prevented == true){
                      prevented = false;
                      return false;
                  }
                  $currentOpt = $targetInput.find(':selected');
  
                  //currentIndex = $targetInput.find('option').index($currentOpt);
                  currentIndex = $targetInput.find('option').index($currentOpt);
  
                  navigateList(currentIndex, true);
  			});
  
              //handle up and down keys
              function keyPress(element) {
                  //when keys are pressed
                  $(element).unbind('keydown.sSelect').bind('keydown.sSelect',function(e){
                      var keycode = e.which;
  
                      //prevent change function from firing
                      prevented = true;
  
                      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:
                          case 27:
                              $newUl.hide();
                              positionHideFix();
                              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;
                          return false;
                      }
                  });
              }
  
              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(){
                  currentIndex = newLiLength-1;
                  navigateList(currentIndex);
              }
  
              $containerDiv.bind('click.sSelect',function(e){
                  e.stopPropagation();
                  keyPress(this);
              });
  
              $containerDiv.bind('focus.sSelect',function(){
                  $(this).addClass('newListSelFocus');
                  keyPress(this);
              });
  
              $containerDiv.bind('blur.sSelect',function(){
                  $(this).removeClass('newListSelFocus');
              });
  
              //hide list on blur
              $(document).bind('click.sSelect',function(){
                  $containerDiv.removeClass('newListSelFocus');
                  $newUl.hide();
                  positionHideFix();
              });
  
              //add classes on hover
              $containerDivText.bind('mouseenter.sSelect',
  				function(e) {
  					var $hoveredTxt = $(e.target);
  					$hoveredTxt.parent().addClass('newListSelHover');
  				}
  			).bind('mouseleave.sSelect',
  				function(e) {
  					var $hoveredTxt = $(e.target);
  					$hoveredTxt.parent().removeClass('newListSelHover');
  				}
              );
  
              //reset left property and hide
              $newUl.css({
                  left: '0',
                  display: 'none',
                  visibility: 'visible'
              });
  
          });
  
      };
  
  })(jQuery);
  