if(!Control) var Control={};
Control.Slider = Class.create(
{
	initialize:function(handle,track,options){
		var slider=this;
		if(Object.isArray(handle)){
			this.handles=handle.collect(function(e){
				return $(e)
			});
		} else {
			this.handles=[$(handle)];
		}
		this.track=$(track);
		this.options=options||{};
		this.axis=this.options.axis||'horizontal';
		this.increment=this.options.increment||1;
		this.step=parseInt(this.options.step||'1');
		this.range=this.options.range||$R(0,1);
		this.value=0;
		this.values=this.handles.map(function(){
			return 0
		});
		this.spans=this.options.spans?this.options.spans.map(function(s){return $(s)}):false;
		this.options.startSpan=$(this.options.startSpan||null);
		this.options.endSpan=$(this.options.endSpan||null);
		this.restricted=this.options.restricted||false;
		this.maximum=this.options.maximum||this.range.end;
		this.minimum=this.options.minimum||this.range.start;
		this.alignX=parseInt(this.options.alignX||'0');
		this.alignY=parseInt(this.options.alignY||'0');
		this.trackLength=this.maximumOffset()-this.minimumOffset();
		
		this.handleLength=this.isVertical()?(this.handles[0].offsetHeight!=0?this.handles[0].offsetHeight:this.handles[0].style.height.replace(/px$/,"")):(this.handles[0].offsetWidth!=0?this.handles[0].offsetWidth:this.handles[0].style.width.replace(/px$/,""));
		
		this.active=false;
		this.dragging=false;
		this.disabled=false;
		if(this.options.disabled)this.setDisabled();
		
		this.allowedValues=this.options.values?this.options.values.sortBy(Prototype.K):false;
		if(this.allowedValues){
			this.minimum=this.allowedValues.min();
			this.maximum=this.allowedValues.max();
		}
		this.eventMouseDown=this.startDrag.bindAsEventListener(this);
		this.eventMouseUp=this.endDrag.bindAsEventListener(this);
		this.eventMouseMove=this.update.bindAsEventListener(this);
		this.handles.each(function(h,i){
			
			i=slider.handles.length-1-i;
			
			slider.setValue(parseFloat((Object.isArray(slider.options.sliderValue)?slider.options.sliderValue[i]:slider.options.sliderValue)||slider.range.start),i);
			h.makePositioned().observe("mousedown",slider.eventMouseDown);
		});
		this.track.observe("mousedown",this.eventMouseDown);
		document.observe("mouseup",this.eventMouseUp);
		document.observe("mousemove",this.eventMouseMove);
		this.initialized=true;
	},
	dispose:function(){
		var slider=this;
		Event.stopObserving(this.track,"mousedown",this.eventMouseDown);
		Event.stopObserving(document,"mouseup",this.eventMouseUp);
		Event.stopObserving(document,"mousemove",this.eventMouseMove);
		this.handles.each(function(h){
			Event.stopObserving(h,"mousedown",slider.eventMouseDown);
		});
	},
	setDisabled:function(){
		this.disabled=true;
	},
	setEnabled:function(){
		this.disabled=false;
	},
	getNearestValue:function(value){
		if(this.allowedValues){
			if(value>=this.allowedValues.max())
				return(this.allowedValues.max());
			if(value<=this.allowedValues.min())
				return(this.allowedValues.min());
			var offset=Math.abs(this.allowedValues[0]-value);
			var newValue=this.allowedValues[0];
			this.allowedValues.each(function(v){
				var currentOffset=Math.abs(v-value);
				if(currentOffset<=offset){
					newValue=v;
					offset=currentOffset;
				}
			});
			return newValue;
		}
		if(value>this.range.end)
			return this.range.end;
		if(value<this.range.start)
			return this.range.start;
		return value;
	},
	setValue:function(sliderValue,handleIdx){
		
		if(!this.active){
			this.activeHandleIdx=handleIdx||0;
			this.activeHandle=this.handles[this.activeHandleIdx];
			this.updateStyles();
		}
		
		handleIdx=handleIdx||this.activeHandleIdx||0;
		if(this.initialized&&this.restricted){
			if((handleIdx>0)&&(sliderValue<this.values[handleIdx-1]))
				sliderValue=this.values[handleIdx-1];
			if((handleIdx<(this.handles.length-1))&&(sliderValue>this.values[handleIdx+1]))
				sliderValue=this.values[handleIdx+1];
		}
		
		sliderValue=this.getNearestValue(sliderValue);
		this.values[handleIdx]=sliderValue;	
		this.value=this.values[0];
		this.handles[handleIdx].style[this.isVertical()?'top':'left']=this.translateToPx(sliderValue);
		this.drawSpans();
		if(!this.dragging||!this.event)this.updateFinished();
		
	},
	setValueBy:function(delta,handleIdx){
		this.setValue(this.values[handleIdx||this.activeHandleIdx||0]+delta,handleIdx||this.activeHandleIdx||0);
	},
	translateToPx:function(value){
		return Math.round(((this.trackLength-this.handleLength)/(this.range.end-this.range.start))*(value-this.range.start))+"px";
	},
	translateToValue:function(offset){
		return((offset/(this.trackLength-this.handleLength)*(this.range.end-this.range.start))+this.range.start);
	},
	getRange:function(range){
		var v=this.values.sortBy(Prototype.K);
		range=range||0;
		return $R(v[range],v[range+1]);
	},
	minimumOffset:function(){
		return(this.isVertical()?this.alignY:this.alignX);
	},
	maximumOffset:function(){
		return(this.isVertical()?(this.track.offsetHeight!=0?this.track.offsetHeight:this.track.style.height.replace(/px$/,""))-this.alignY:(this.track.offsetWidth!=0?this.track.offsetWidth-10:this.track.style.width.replace(/px$/,""))-this.alignX-10);
	},
	isVertical:function(){
		return(this.axis=='vertical');
	},
	drawSpans:function(){
		var slider=this;
		if(this.spans)
			$R(0,this.spans.length-1).each(function(r){
				slider.setSpan(slider.spans[r],slider.getRange(r))
			});
		if(this.options.startSpan)
			this.setSpan(this.options.startSpan,$R(0,this.values.length>1?this.getRange(0).min():this.value));
		if(this.options.endSpan)
			this.setSpan(this.options.endSpan,$R(this.values.length>1?this.getRange(this.spans.length-1).max():this.value,this.maximum));
	},
	setSpan:function(span,range){
		if(this.isVertical()){
			span.style.top=this.translateToPx(range.start);span.style.height=this.translateToPx(range.end-range.start+this.range.start);
		} else {
			span.style.left=this.translateToPx(range.start);span.style.width=this.translateToPx(range.end-range.start+this.range.start);
		}
	},
	updateStyles:function(){
		this.handles.each(function(h){Element.removeClassName(h,'selected')});
		Element.addClassName(this.activeHandle,'selected');
	},
	startDrag:function(event){
		if(Event.isLeftClick(event)){
			if(!this.disabled){
				this.active=true;
				var handle=Event.element(event);
				var pointer=[Event.pointerX(event),Event.pointerY(event)];
				var track=handle;
				if(track==this.track){
					var offsets=Position.cumulativeOffset(this.track);
					this.event=event;
					this.setValue(this.translateToValue((this.isVertical()?pointer[1]-offsets[1]:pointer[0]-offsets[0])-(this.handleLength/2)));
					var offsets=Position.cumulativeOffset(this.activeHandle);
					this.offsetX=(pointer[0]-offsets[0]);
					this.offsetY=(pointer[1]-offsets[1]);
				} else {
					while((this.handles.indexOf(handle)==-1)&&handle.parentNode)
						handle=handle.parentNode;
					if(this.handles.indexOf(handle)!=-1){
						this.activeHandle=handle;
						this.activeHandleIdx=this.handles.indexOf(this.activeHandle);
						this.updateStyles();
						var offsets=Position.cumulativeOffset(this.activeHandle);
						this.offsetX=(pointer[0]-offsets[0])+this.activeHandleIdx*20;
						this.offsetY=(pointer[1]-offsets[1]);
					}
				}
			}
			Event.stop(event);
		}
	},
	update:function(event){
		if(this.active){
			if(!this.dragging)
				this.dragging=true;
			this.draw(event);
			if(Prototype.Browser.WebKit)
				window.scrollBy(0,0);
			Event.stop(event);
		}
	},
	draw:function(event){
		var pointer=[Event.pointerX(event),Event.pointerY(event)];
		var offsets=Position.cumulativeOffset(this.track);
		pointer[0]-=this.offsetX+offsets[0];pointer[1]-=this.offsetY+offsets[1];
		this.event=event;
		this.setValue(this.translateToValue(this.isVertical()?pointer[1]:pointer[0]));
		if(this.initialized&&this.options.onSlide)
			this.options.onSlide(this.values.length>1?this.values:this.value,this);
	},
	endDrag:function(event){
		if(this.active&&this.dragging){
			this.finishDrag(event,true);
			Event.stop(event);
		}
		this.active=false;
		this.dragging=false;
	},
	finishDrag:function(event,success){
		this.active=false;
		this.dragging=false;
		this.updateFinished();
	},
	updateFinished:function(){
		if(this.initialized&&this.options.onChange)
			this.options.onChange(this.values.length>1?this.values:this.value,this);
		this.event=null;
	}
}
);

