(function($) {
	$.fn.selectmore = function() {
		var index = -1;
		$(this).each(function() {
			index++;
			var theName = index;
			var xthis = $(this);
			
			/* CREATE HIDDEN FORM ELEMENT FOR TABBING AND SERVER PASSING */
			xthis.before('<input type="text" class="'+theName+'-tab cs-tab" style="position: absolute; top: -9999px;" />');
			$('input.'+theName+'-tab').attr("autocomplete","off");
			
			/* CREATE CUSTOM SELECT */
			xthis.after('<ul class="'+theName+'-select cs-select"><li class="current"></li><ol></ol></ul>');
			var xthisList = $('ul.' + theName + '-select ol');
			
			/* POPULATE OPTIONS */
			var opPopIndex = 0;
			xthis.children().each(function() {
				/* GENERATE SELECTED OPTION */
				if($(this).attr("selected")) {
					xthisList.append('<li class="' + theName + '-option cs-option cs-selected cs-highlight cs-o' + opPopIndex + '" title="' + $(this).val() + '"><div>' + $(this).text() + '</div></li>');
				}
				/* GENERATE OTHER OPTIONS */
				else 
					xthisList.append('<li class="' + theName + '-option cs-option cs-o' + opPopIndex + '" title="' + $(this).val() + '"><div class="cs-option-content">' + $(this).text() + '</div></li>');
				opPopIndex++;
			});
			
			/* FUNCTIONAL SELECT LIST STYLES */
			xthisList.css("opacity","0");
			
			//xthisList.css("margin-top",$('.'+theName+'-select .current').outerHeight()*-1+"px");
			//if($.browser.safari && ($(this).parents("li").css("float") == "left" || $(this).parents("li").css("float") == "right"))
				//xthisList.css("margin-top",$('.'+theName+'-select .current').outerHeight()+"px");
			//xthisList.css("left",$('.'+theName+'-select .current').position().left+"px");
			//xthisList.css("left","0");
			
			/* IF OPTIONS DO NOT EXCEED LIST HEIGHT, SHORTEN LIST HEIGHT */
			var opHeight = 0;
			$.each($('ul.'+theName+'-select ol li'), function() {
				opHeight+=$(this).outerHeight();
			});
			
			
			if(xthisList.height() > opHeight) {
				xthisList.height(opHeight);
				xthisList.css("overflow","hidden");
			} else {
				xthisList.width(xthisList.width()+15);
			}

			/* RESET SELECT LIST SCROLL */
			xthisList.scrollTop(0);
			//xthisList.scrollTop($('.'+theName+'-select ol .cs-highlight').position().top);
			//xthisList.scrollLeft($('.'+theName+'-select ol .cs-highlight').position().left);
			
			/* DISPLAY DEFAULT SELECTED ITEM */
			$('ul.'+theName+'-select .current').text($('.'+theName+'-select ol li.cs-selected').text());
			
			/* OPTION-LIST-DISPLAY-RELATED CLICK EVENTS */
			xthis.siblings('input.'+theName+'-tab').focus(function() {
				toggleCS($('ul.'+theName+'-select'), true);
			});
			xthis.focus(function() {
				if(!shift) {
					$(':input').eq($(':input').index(this)+1).focus();	
				}
			});
			
			/**********
			 * 
			 * UPGRADE THIS TO ADJUST THE FAKE SELECT ON CHANGE OF THE REAL SELECT, NOT THE OTHER WAY AROUND
			 * 
			 **********/
			
			$('ul.'+theName+'-select').click(function(e) {
				if(!$(e.target).is('div.cs-option-content') && !$(this).hasClass("cs-open")) {
					toggleCS('.cs-open');
					$('input.' + theName + '-tab').focus();
				}
			});
			$('ul.'+theName+'-select .current').click(function(e) {
				if($(this).parent().hasClass("cs-open")) {
					var opa = parseFloat($('ul.cs-open ol').css("opacity")) ? "0" : "1";
					var top = opa == "1" ? $(this).parent().children('li.current').height() + "px" : "-9999px";
					$('ul.cs-open ol').css("opacity",opa);
					$('ul.cs-open ol').css("top",top);
				}
			});
			
			/* OPTION ITEMS MOUSE EVENTS */
			$(this).siblings('ul.'+theName+'-select').children('ol').children('li').click(function() {
				selectCS(this);
				var opa = parseFloat($('ul.cs-open ol').css("opacity")) ? "0" : "1";
				var top = opa == "1" ? $(this).parent().siblings('.current').height() + "px" : "-9999px";
				$('ul.cs-open ol').css("opacity",opa);
				$('ul.cs-open ol').css("top",top);
			});
			$(this).siblings('ul.'+theName+'-select').children('ol').children('li').mouseover(function() {
				if (!held) {
					$('li.cs-highlight').removeClass("cs-highlight");
					$(this).addClass("cs-highlight");
				}
			});
			xthisList.css("display","none");
			
			// HIDE ORIGINAL SELECT
			$(this).css("position","absolute");
			$(this).css("top","-9999px");
		});
		
		/* KEYBOARD CONTROLS */
		var chars = new Array();
		chars[48] = "0";
		chars[49] = "1";
		chars[50] = "2";
		chars[51] = "3";
		chars[52] = "4";
		chars[53] = "5";
		chars[54] = "6";
		chars[55] = "7";
		chars[56] = "8";
		chars[57] = "9";
		chars[65] = "a";
		chars[66] = "b";
		chars[67] = "c";
		chars[68] = "d";
		chars[69] = "e";
		chars[70] = "f";
		chars[71] = "g";
		chars[72] = "h";
		chars[73] = "i";
		chars[74] = "j";
		chars[75] = "k";
		chars[76] = "l";
		chars[77] = "m";
		chars[78] = "n";
		chars[79] = "o";
		chars[80] = "p";
		chars[81] = "q";
		chars[82] = "r";
		chars[83] = "s";
		chars[84] = "t";
		chars[85] = "u";
		chars[86] = "v";
		chars[87] = "w";
		chars[88] = "x";
		chars[89] = "y";
		chars[90] = "z";

		var keybinder = $.browser.msie ? document : window;
		var held = false;
		var shift;

		$(keybinder).keydown(function(e) {
			shift = e.shiftKey;
			
			if(!e.ctrlKey && !e.altKey && !e.metaKey) {
				switch(e.keyCode) {
					case 37: //LEFT
						if(!held) {
							$('ul.cs-open ol').css("opacity",1);
							$('ul.cs-open ol').css("top",$('ul.cs-open li.current').height()+"px");
							held = setInterval(function() { scrollCS('ul.cs-open',true) }, 50);
						}
						break;
					case 38: //UP
						if(!held) {
							$('ul.cs-open ol').css("opacity",1);
							$('ul.cs-open ol').css("top",$('ul.cs-open li.current').height()+"px");
							held = setInterval(function() { scrollCS('ul.cs-open',true) }, 50);
						}
						break;
					case 39: //RIGHT
						if(!held) {
							$('ul.cs-open ol').css("opacity",1);
							$('ul.cs-open ol').css("top",$('ul.cs-open li.current').height()+"px");
							held = setInterval(function() { scrollCS('ul.cs-open',false) }, 50);
						}
						break;
					case 40: //DOWN
						if(!held) {
							$('ul.cs-open ol').css("opacity",1);
							$('ul.cs-open ol').css("top",$('ul.cs-open li.current').height()+"px");
							held = setInterval(function() { scrollCS('ul.cs-open',false) }, 50);
						}
						break;
					case 9: //TAB
						if($('.cs-open').length > 0) {
							selectCS($('ul.cs-open ol li.cs-highlight'));
							toggleCS('ul.cs-open');
						}
						break;
					case 13: //ENTER
						if($('.cs-open').length > 0) {
							var opa = parseFloat($('ul.cs-open ol').css("opacity")) ? "0" : "1";
							var top = opa == "1" ? $('ul.cs-open li.current').height() + "px" : "-9999px";
							if(opa == "0") {
								selectCS($('ul.cs-open ol li.cs-highlight'));
								$('ul.cs-open ol').css("opacity",opa);
								$('ul.cs-open ol').css("top",top);
							}
							else 
								$('ul.cs-open').parents('form').submit();
						}
						break;
					case 32: //SPACEBAR
						if($('ul.cs-open').length > 0) {
							var opa = parseFloat($('ul.cs-open ol').css("opacity")) ? "0" : "1";
							var top = opa == "1" ? $('ul.cs-open li.current').height() + "px" : "-9999px";
							if(opa == "0")
								selectCS($('ul.cs-open ol li.cs-highlight'));
							$('ul.cs-open ol').css("opacity",opa);
							$('ul.cs-open ol').css("top",top);
						}
						break;
					case 27: //ESC
						if($('ul.cs-open').length > 0) {
							toggleCS('.cs-open');
						}
						break;
					default:
						break;
				}
				
				if((e.keyCode >= 65 && e.keyCode <= 90 || e.keyCode >= 48 && e.keyCode <= 57) && $('ul.cs-open').length > 0) {
					var theList = $('ul.cs-open ol');
					
					$('ul.cs-open li.cs-option').each(function() {
						if(($(this).text().split('')[0] == chars[e.keyCode] || $(this).text().split('')[0] == chars[e.keyCode].toUpperCase()) && $(this).attr('title') != '') {
							$(this).addClass("cs-match");
						}
					});
					
					if($('li.cs-match.cs-highlight').length == 0) {
						$('ul.cs-open li.cs-highlight').removeClass("cs-highlight");
						$('li.cs-match:first').addClass('cs-highlight');
						//selectCS($('ul.cs-open ol li.cs-highlight'));
						$('ul.cs-open li.current').text($('ul.cs-open ol li.cs-highlight').text());
						theList.scrollTop(0);
						//$('.cs-open ol').scrollLeft(0);
						theList.scrollTop($('ul.cs-open ol li.cs-highlight').position().top);
						//$('.cs-open ol').scrollLeft($('.cs-open ol .cs-highlight').position().left);
					} else if($('li.cs-match:last').hasClass('cs-highlight') && $('li.cs-match').length - 1 != 0) {
						$('ul.cs-open li.cs-highlight').removeClass('cs-highlight');
						$('li.cs-match:first').addClass("cs-highlight");
						//selectCS($('ul.cs-open ol li.cs-highlight'));
						$('ul.cs-open li.current').text($('ul.cs-open ol li.cs-highlight').text());
						theList.scrollTop(0);
						//$('.cs-open ol').scrollLeft(0);
						theList.scrollTop($('ul.cs-open ol li.cs-highlight').position().top);
						//$('.cs-open ol').scrollLeft($('.cs-open ol .cs-highlight').position().left);
					} else {
						if($('li.cs-match.cs-highlight').nextAll('.cs-match').eq(0).hasClass('cs-match')) {
							$('li.cs-match.cs-highlight').nextAll('.cs-match').eq(0).addClass('cs-highlight');
							$('li.cs-match.cs-highlight:first').removeClass('cs-highlight');
							//selectCS($('ul.cs-open ol li.cs-highlight'));
							$('ul.cs-open li.current').text($('ul.cs-open ol li.cs-highlight').text());
							if($('ul.cs-open ol li.cs-highlight').position().top > $('ul.cs-open ol').height()) {
								theList.scrollTop(0);
								//$('.cs-open ol').scrollLeft(0);
								theList.scrollTop($('ul.cs-open ol li.cs-highlight').position().top);
							}
							//$('.cs-open ol').scrollLeft($('.cs-open ol .cs-highlight').position().left);
						}
					}
					$('.cs-match').removeClass('cs-match');
				}
			}
		});
		$(keybinder).keyup(function(e) {
			clearInterval(held);
			held = false;
		});
		$(keybinder).keydown(function(e) {
			if($('ul.cs-open').length > 0 && (!e.ctrlKey && !e.altKey && !e.metaKey)) {
				return false;
			}
		});
		$(keybinder).keypress(function(e) {
			if($('ul.cs-open').length > 0 && (!e.ctrlKey && !e.altKey && !e.metaKey)) {
				return false;
			}
		});
		
		$(document).click(function(e) {
			if($('ul.cs-open').length > 0) {
				var target = $(e.target);
				
				if(!target.is('ul.cs-select') && !target.is('li.current') && !target.is('ul.cs-open') && !target.is('div.cs-option-content')) {
					var openList = $('ul.cs-open ol');
					
					if(openList.css("opacity") == "0")
						toggleCS('ul.cs-open');
					else {
						openList.css("opacity","0");
						openList.css("top","-9999px");
						$('ul.cs-open ol li.cs-highlight').removeClass('cs-highlight');
						$('ul.cs-open ol li.cs-selected').addClass('cs-highlight');
						$('ul.cs-open li.current').text($('ul.cs-open ol li.cs-selected').text());
						openList.scrollTop($('ul.cs-open ol li.cs-selected').position().top + $('ul.cs-open ol').scrollTop());	
					}
				}
			}
		});

		
		/* EVENT : OPEN / CLOSE CUSTOM SELECT OPTION LIST */
		function toggleCS(obj, picked) {
			/* MAIN TOGGLE ACTIONS */
			var theSelect = $(obj);
			var theOptions = theSelect.children('ol');
			if(!theSelect.hasClass("cs-open") || picked) {
				theSelect.addClass("cs-open");
				theOptions.css("top",theSelect.children('li.current').height() + "px");
				theOptions.css("display","block").animate({
					//marginTop: theSelect.children('.current').outerHeight() + "px",
					opacity: "1"
				}, 'fast', function() {
					if(theOptions.children('li.cs-selected').position().top > theOptions.height() || theOptions.children('li.cs-selected').position().top < 0) {
						theOptions.children('li.cs-highlight').removeClass('cs-highlight');
						theOptions.children('li.cs-selected').addClass('cs-highlight');
						theOptions.scrollTop(theOptions.children('li.cs-selected').position().top + theOptions.scrollTop());
					}
				});
			} else {
				theSelect.removeClass("cs-open");
				theOptions.children('li.cs-highlight').removeClass('cs-highlight');
				theOptions.children('li.cs-selected').addClass('cs-highlight');
				theOptions.css("display","none");
				
				/* We've changed the functionality, only fade in once.
				 * theOptions.animate({
					//marginTop: theSelect.children('.current').outerHeight()*-1 + "px",
					opacity: "0"
				}, 'fast', function() {
					theSelect.removeClass("cs-open");
					theOptions.children('.cs-highlight').removeClass('cs-highlight');
					theOptions.children('.cs-selected').addClass('cs-highlight');
					theOptions.css("display","none");
				});*/
			}
		}
		/* EVENT : SCROLL THROUGH OPTIONS */
		var btnDown = false;
		function scrollCS(obj, up) {
			var curHighlight = $(obj).children('ol').children('li.cs-highlight');
			var opIndex = $(obj).children('ol').children().length - $(obj).children('ol').children('li.cs-highlight').nextAll().length - 1;
			if(up && opIndex > 0 && !btnDown) {
				btnDown = true;
				setTimeout(function() {
					curHighlight.removeClass('cs-highlight');
					curHighlight.prev().addClass("cs-highlight");
					$(obj).children('ol').scrollTop($(obj).find('li.cs-highlight').position().top + $(obj).children('ol').scrollTop());
					$(obj).children('li.current').text($('ul.cs-open ol li.cs-highlight').text());
					btnDown = false;
				}, 50);
			} else if(!up && opIndex < $(obj).children('ol').children().length-1 && !btnDown) {
				btnDown = true;
				setTimeout(function() {
					curHighlight.removeClass('cs-highlight');
					curHighlight.next().addClass("cs-highlight");
					$(obj).children('ol').scrollTop($(obj).find('li.cs-highlight').position().top + $(obj).children('ol').scrollTop());
					$(obj).children('li.current').text($('ul.cs-open ol li.cs-highlight').text());
					btnDown = false;
				}, 50);
			}
		}
		/* EVENT : SELECT AN OPTION */
		function selectCS(obj) {
			var theRef = $(obj);
			if(theRef.parents('ul.cs-open').length == 1) {
				theRef.parents('ul.cs-open').children('li.current').text(theRef.text());
				theRef.parents('ul.cs-open').children('li.current').attr("style",theRef.attr("style"));
				$('ul.cs-open li.cs-selected').removeClass("cs-selected");
				$('ul.cs-open li.cs-highlight').removeClass("cs-highlight");
				theRef.addClass("cs-selected cs-highlight");
				var opIndex = (theRef.parent().children().length - theRef.nextAll().length) - 1;
				theRef.parent().parent().siblings('select').val(theRef.attr("title"));
				theRef.parent().parent().siblings('select').children('option').eq(opIndex).attr("selected","selected");
				theRef.parent().parent().siblings('select').change();
			}
		}
	}
})(jQuery);
