jQuery.fn.atl_slider = function(settings){

	 var config = {}; 
		if (settings) $.extend(config, settings);

	jQuery.fn.atl_slider.activeSlider = null;

	function slideUI(el){
	
		var wrapper = document.createElement('DIV');						
		var activeWrapper;
	
		//public methods
		wrapper.drag = function(e){							
			moveTo(e.clientY - wrapper.offsetTop);							
		};
		
		wrapper.snap = function(to){
			
			var a = jQuery.fn.atl_slider.activeSlider || wrapper;						
			var height = a.clientHeight;
			var number = a.previousSibling.options.length;
			
			var stepDistance = (height/(number -1));							
			pointerOffset = (a.firstChild.offsetTop - (a.firstChild.clientHeight/2));
			
			if(to == 'up')
				to = pointerOffset - stepDistance;							
			else if(to == 'down')
				to = pointerOffset + stepDistance;
			else if(typeof(to) == 'number')				
				to = (to * stepDistance);
			else	
				to = pointerOffset;
			
			var thisStep = null;
			
			for(var i = 0; i < number; i++){						
				if((stepDistance * i) - (stepDistance/2) > to){
					thisStep = i - 1;						
					break;
				};												
			};
			
			if(thisStep == null)
				thisStep = number-1;
				
			//set original select element to the correct value
			a.select.selectedIndex = thisStep;
			
			//call the callback function if we have one
			if(typeof(config.changeCallback) == 'function') 
				config.changeCallback(a.select);
			
			//move the pointer
			moveTo(thisStep * stepDistance,(stepDistance * 2)); //using stepDistance for the animation time means shorter steps will be quicker.
		}
		
		//private methods
		function moveTo(y,time){
			
			var a = jQuery.fn.atl_slider.activeSlider || wrapper;							
			var newPos = (y - (a.pointer.clientHeight/2)); 
			
			if(newPos < 1)
				newPos = 0
			else if(newPos >= (a.clientHeight - (a.pointer.clientHeight)))
				newPos = a.clientHeight - a.pointer.clientHeight;
			
			if(time)//time only needed when snapping not dragging.	
				$(a.pointer).animate({marginTop:newPos},time)
			else
				a.pointer.style.marginTop = parseInt(newPos)  + "px";
			
		}
		//constructor
		(function(){
			
			//create the html elements we need.
			//setting the pointer to 1px helps prevent errors, and adding a span into it lets us style it.			
			wrapper.pointer = document.createElement('A'); //this should be a button but webkit can't style buttons much.
			wrapper.pointer.href = "#";
			wrapper.pointer.style.position = "absolute";
			wrapper.pointer.style.height = "1px";
			wrapper.pointer.style.border = "0";
			wrapper.pointer.style.overflow = "visible";
			var pointerVisible = document.createElement('SPAN');
			wrapper.pointer.appendChild(pointerVisible);	
			
			wrapper.select = el;
			
			//give them some classes for styling later.
			wrapper.className = "atl_slide_wrapper";
			wrapper.pointer.className = "atl_slide_pointer";
			
			//put the wrapper in the dom immeadiately after the hidden select
			el.parentNode.insertBefore(wrapper,el.nextSibling);
			
			wrapper.appendChild(wrapper.pointer);
			
			//we're interested in where the mouse is relative to the wrapper then move the pointer there.
			$(wrapper).bind('mousedown', function(e){
				
				if(e.target.tagName == "DIV")
					jQuery.fn.atl_slider.activeSlider = e.target;
				else if(e.target.tagName == "A")
					jQuery.fn.atl_slider.activeSlider = e.target.parentNode;
				else if(e.target.tagName == "SPAN")
					jQuery.fn.atl_slider.activeSlider = e.target.parentNode.parentNode;
					
				$(document).bind('mousemove',jQuery.fn.atl_slider.activeSlider.drag);
				moveTo(e.clientY - wrapper.offsetTop); //move the pointer to where the wrapper was clicked.						
				$(jQuery.fn.atl_slider.activeSlider).addClass('active');
													
				return false;	
			});
		
			$(wrapper.pointer).bind('focus',function(e){
				
				var a = jQuery.fn.atl_slider.activeSlider = e.target.parentNode;
				
				$(e.target).bind('keydown',function(e){
					if (e.keyCode == 38)
						a.snap('up');
					if(e.keyCode == 40)
						a.snap('down');
					if(e.keyCode == 40 || e.keyCode == 38)
						return false;	
				});
				//page scroll happens on different events in different browsers so kill all of them.
				$(e.target).bind('keypress',function(e){
					return false;	
				});		
				$(e.target).bind('keyup',function(e){
					return false;	
				});		
			});	
			
			$(wrapper.pointer).bind('blur',function(e){
				$(e.target).unbind('keypress');
				$(e.target).unbind('keyup');
				$(e.target).unbind('keydown');								
			});
			
								
		})();
		
		//set slider to select's selected option		
		wrapper.snap(el.selectedIndex)
		
		//return object with public methods
		return wrapper;
	};


	this.each(function(){
		$(this).hide(); //hide the standard browser elements.
		this.ui = new slideUI(this); // build our own user interface.
	});	
	
	//we only need to clean up once so outside the loop.
	$(document).bind('mouseup', function(e){							
		if(jQuery.fn.atl_slider.activeSlider){
			jQuery.fn.atl_slider.activeSlider.snap();
			jQuery.fn.atl_slider.activeSlider.pointer.focus();							
			$(jQuery.fn.atl_slider.activeSlider).removeClass('active');
		}
		$(document).unbind('mousemove');							
	});

}



