(function($) {
	var sbCnt=0;
	$.fn.JSelectBox = function(opts){
		
		if($(this).length > 1){
			return $(this).each(function(){
				$(this).JSelectBox(opts);
			});
		}
		var rf = function() { return false; };
		var $select = $(this);
		var self = $select.get(0);
		var slf = this;
			opts = $.extend({}, $.fn.JSelectBox.defaults, opts);
		
		if($.nodeName(self, "select")){
			var inFocus = false;
			var hasfocus = 0;
			
			if(!$select.attr("id")){
				$select.attr("id","JSelectBox_"+sbCnt);
			}
			self.buildContainer=function(){
				self.originalSelectedIndex=self.selectedIndex;
			
				var $container = $(document.createElement("div"));
					$container.addClass(opts.containerClass);
					$container.css({
						'z-index':999
					});
				var $span = $(document.createElement("span"));
					$span.addClass(opts.inputClass);
					$span.css({
							width:parseInt($select.css('width'))-opts['image-width'],
							paddingRight:opts['image-width'],
							textAlign:$select.css('text-align'),
							height:$select.css('height')
							});
					
				var $input = $(document.createElement("input"));
					$input.attr("type", "text");
					$input.attr("autocomplete", "off");
					$input.attr("readonly", "readonly");
					$input.attr("tabIndex", $select.attr("tabindex")); // "I" capital is important for ie
					$input.css({
						border:"none",
						width:1,
						height:1,
						position:"absolute",
						top:-10000,
						left:-10000
					});	
				self.container = $container;
				self.span = $span;
				self.input = $input;
			};
			self.render=function(){
				self.container.html("");
				var select_options = [];
				var $scroll = $(document.createElement('div'));
				var ul = document.createElement('ul');
				var cnt=0;
				$select.children('option').each(function() {
					var li = document.createElement('li');
					li.setAttribute('id', $(this).val());
					li.innerHTML = $(this).html();
					if ($(this).is(':selected')) {
						self.span.html($(this).html());
					}
					ul.appendChild(li);
					$(li)
					.mouseover(function(event) {
						hasfocus = 1;
						$(event.target, self.container).addClass(opts.hoverClass);
					})
					.mouseout(function(event) {
						hasfocus = -1;
						$(event.target, self.container).removeClass(opts.hoverClass);
					})
					.click(function(event) {
						$(this).addClass(opts.hoverClass);
						slf._setCurrent();
						slf._hideMe();
					}).css({
							textAlign:$select.css('text-align')
					});
					opts.options[cnt] = $(this).get(0);
					cnt++;
				});
				self.container.append($scroll.append(ul));
				self.container.hide();
			};
			this._setCurrent=function() {	
				var li = $("li."+opts.hoverClass, self.container).get(0);
				self.span.html($(li).html());
				$select.val(li.id);
				try{
					window.setTimeout(function(){
						$select.change();
						slf._hideMe();
						var lis = $("li", self.container);
							lis.removeClass(opts.activeClass);
							$(lis[self.selectedIndex]).addClass(opts.activeClass);
					},50);
				} catch(e){}
				
				return true;
			};
			this._hideMe=function(){
				hasfocus = 0;
				self.container.hide(); 
			};
			this._moveSelect=function(step) {
				var lis = $("li", self.container);
				if (!lis) return;
				self.selectedIndex += step;
				if (self.selectedIndex < 0) {
					self.selectedIndex = 0;
				} else if (self.selectedIndex >= lis.size()) {
					self.selectedIndex = lis.size() - 1;
				}
				lis.removeClass(opts.hoverClass);
				$(lis[self.selectedIndex]).addClass(opts.hoverClass);
			};
			self.buildContainer();
			self.render();
			try{
				var lis = $("li", self.container);
				lis.removeClass(opts.hoverClass);
				$(lis[self.selectedIndex]).addClass(opts.hoverClass);
				$(lis[self.selectedIndex]).addClass(opts.activeClass);
			}catch(e){}
			$select.hide().before(self.input).before(self.span).before(self.container);
			
			var width = parseInt($select.css('width'))+(2*opts['border-width']);
			self.container.width(width+"px");
			/*
			// IE correction
			if($select.css('text-align')=='right')
				self.container.css({
					"margin-left":"-"+(parseInt(self.container.width())-(2*opts['border-width']))
				});
			*/
			if($.browser.opera)
				self.container.css({
					"margin-top":(opts['border-width']*-1)
				});
				
			if(opts.containerCss){
				try{
					self.container.css(opts.containerCss);
				}catch(e){}
			}
			// on reset parent form reset select too
			$("form:has(#"+$select.attr("id")+")").bind("reset",function(e){
				self.span.html($($select.children('option').get(self.originalSelectedIndex)).html());
				var lis = $("li", self.container);
					lis.removeClass(opts.hoverClass);
				$(lis[self.selectedIndex]).addClass(opts.hoverClass);
				$(lis[self.selectedIndex]).addClass(opts.activeClass);
			});
			
			self.span.click(function(){
				try{
					self.click();
				}catch(e){}
				self.input.focus();
			});
			
			self.input
			.click(function(){
					if (!inFocus) {
					  self.container.toggle();
					  for(var i=0; i<$.JSelectBox.items.length;i++){
						var t = $.JSelectBox.items[i];
						if(t!=slf) t._hideMe();
					  }
					}
				})
				.focus(function(){
				   if (self.container.not(':visible')) {
					   inFocus = true;
					   self.container.show();
					   for(var i=0; i<$.JSelectBox.items.length;i++){
						var t = $.JSelectBox.items[i];
						if(t!=slf) t._hideMe();
						};
				   }
				})
				.keydown(function(event) {	   
					switch(event.keyCode) {
						case 38:
							event.preventDefault();
							slf._moveSelect(-1);
							break;
						case 40:
							event.preventDefault();
							slf._moveSelect(1);
							break;
						case 13:
							event.preventDefault();
							event.stopPropagation();
							slf._setCurrent();
							slf._hideMe();
							break;
					}
				})
				.blur(function() {
					if (self.container.is(':visible') && hasfocus > 0 ) {
					} else {
						slf._hideMe();	
					}
				});
			$.JSelectBox.items[$.JSelectBox.items.length]=this;
			sbCnt++;
		}
		return $(this);
	};
	
	$.fn.extend({
		addOption:function(value,text,selected){
			if($.nodeName($(this).get(0), "select")){
				var self = $(this).get(0);
				$(this).append(
					$('<option></option>').val(value).html((text)?text:value).attr("selected",(selected)?true:false)
				);
				$(this).rebuildOptions();
			}
			return $(this);
		},
		clearOptions:function(){
			if($.nodeName($(this).get(0), "select")){
				var self = $(this).get(0);
					$(this).children("option").remove();
					self.span.html("");
					$(this).rebuildOptions();
			}
			return $(this);
		},
		setOption:function(val){
			if($.nodeName($(this).get(0), "select")){
				var self = $(this).get(0);
				if($(this).val()!=val)
					$(this).val(val).change();
				self.span.html(val);
			}
			return $(this);
		},
		rebuildOptions:function(){
			if($.nodeName($(this).get(0), "select")){
				var self = $(this).get(0);
				self.render();
			}
			return $(this);
		}
	});
	
	$.fn.JSelectBox.defaults = {
		options:[],
		inputClass:"selectbox",
		containerClass:"selectbox-wrapper",
		hoverClass:"selected",
		activeClass:"current",
		debug:false,
		onchange:false,
		onclick:false,
		'border-width':1, /* width of border */
		'image-width':20 /* width of dropdown image */
	};
	
	$.JSelectBox = {
		items : []
	};
})(jQuery);
