function Slider(prefix,width,height,thumbWidth,thumbHeight,orientation,minValue,maxValue,initValue,tickSpacing,offsetX,offsetY,callback){
	this.CONSTRAINT_HORIZONTAL = "h";
	this.CONSTRAINT_NAMES = new Array();
	this.CONSTRAINT_NAMES["THUMB"] = "_bar";
	this.CONSTRAINT_NAMES["CONTAINER"] = "_container";
	
	this.valueToPixel = function(value){
		if(this.orientation == this.CONSTRAINT_HORIZONTAL)
			return Math.ceil(((value-minValue)/(maxValue-minValue))*(width-thumbWidth));
		else
			return Math.ceil(((value-minValue)/(maxValue-minValue))*(height-thumbHeight));
	}
	
	this.pixelToValue = function(value){
		if(this.orientation == this.CONSTRAINT_HORIZONTAL)
			return this.minValue + Math.round((value/(this.width-this.thumbWidth))*(this.maxValue-this.minValue));
		else
			return this.minValue + Math.round((value/(this.height-this.thumbHeight))*(this.maxValue-this.minValue));
	}
	
	this.setValue = function(value){
		var pixelValue = this.valueToPixel(value);
		if(this.orientation == this.CONSTRAINT_HORIZONTAL)
			this.setThumbLeft(pixelValue);
		else
			this.setThumbTop(pixelValue);
	
		this.updateValue(pixelValue);
	}
	
	this.updateValue = function(value){
		this.currentValue = this.pixelToValue(value);
		if(this.callback != null)
			this.callback(this);
	}
	
	this.getHTML = function(){
		var toReturn = "";
		
		toReturn += '<div id="'+this.prefix+this.CONSTRAINT_NAMES["CONTAINER"]+'" style="position:relative; width:'+this.width+'px; height:'+this.height+'px; background:#CCC;">';
		
		var top = this.thumbY;
		var left = this.thumbX;
		
		if(orientation=='h')
			top = Math.round((this.height-this.thumbHeight)/2);
		else
			left = Math.round((this.width-this.thumbWidth)/2);
		
		top += this.offsetY;
		left += this.offsetX;
		
		toReturn += '<p id="'+prefix+this.CONSTRAINT_NAMES["THUMB"]+'" style="position:absolute; top:'+top+'px; left:'+left+'px; width:'+this.thumbWidth+'px; height:'+this.thumbHeight+'px; background:url(gfx/slider/slider_'+this.orientation+'.gif) no-repeat;"></p>';
    	toReturn += '</div>';
		
		return toReturn;
	}
	
	this.setThumbLeft = function(value){
		if(this.pixelToValue(value)%this.tickSpacing == 0){
			setLeft(this.prefix+this.CONSTRAINT_NAMES["THUMB"],value);
			this.updateValue(value);
		}
	}
	
	this.setThumbTop = function(value){
		if(this.pixelToValue(value)%this.tickSpacing == 0){
			setTop(this.prefix+this.CONSTRAINT_NAMES["THUMB"],value);
			this.updateValue(value);
		}
	}
	
	this.updateThumbPosition = function(){
		var position = getPosition(this.prefix+this.CONSTRAINT_NAMES["THUMB"]);
		this.thumbX = position[0];
		this.thumbY = position[1];
	}
	
	this.getOuterWidth = function(){
		return getWidth(this.prefix+this.CONSTRAINT_NAMES["CONTAINER"]);
	}
	
	this.getOuterHeight = function(){
		return getHeight(this.prefix+this.CONSTRAINT_NAMES["CONTAINER"]);
	}
	
	this.getOuterPosition = function(){
		return getPosition(this.prefix+this.CONSTRAINT_NAMES["CONTAINER"]);
	}
	
	this.setOuterBackgroundStyle = function(bg){
		getStyle(this.prefix+this.CONSTRAINT_NAMES["CONTAINER"]).background = bg;
	}
	
	this.prefix = prefix;
	this.height = height;
	this.width = width;
	this.orientation = orientation;
	this.callback = callback;
	
	this.tickSpacing = tickSpacing;
	
	this.minValue = minValue;
	this.maxValue = maxValue;
	
	this.currentValue = 0;
	
	this.thumbX = 0;
	this.thumbY = 0;
	
	this.thumbWidth = thumbWidth;
	this.thumbHeight = thumbHeight;
	
	this.offsetX = offsetX;
	this.offsetY = offsetY;
	
	if(initValue >= 0 && initValue <= this.maxValue){
		if(this.orientation == this.CONSTRAINT_HORIZONTAL){
			this.thumbX = this.valueToPixel(initValue);
			this.updateValue(this.thumbX);
		}
		else{
			this.thumbY = this.valueToPixel(initValue);
			this.updateValue(this.thumbY);
		}	
	}
}

function SliderManager(){
	this.sliders = new Array();
	this.startDragX = -1;
	this.startDragY = -1;
	this.mouseDown = false;
	this.activeSliderId = -1;
		
	this.tmp = null;	
	
	this.init = function(){
		this.registerEvents();
	};
	
	this.getSlider = function(prefix){
		for(var i = 0; i < obj.sliders.length; i++)
			if(obj.sliders[i].prefix == prefix)
				return obj.sliders[i];
			
		return null;	
	}
	
	this.registerSlider = function(prefix,width,height,thumbWidth,thumbHeight,orientation,minValue,maxValue,initValue,tickSpacing,offsetX,offsetY,callback){
		var newSlider = new Slider(prefix,width,height,thumbWidth,thumbHeight,orientation,minValue,maxValue,initValue,tickSpacing,offsetX,offsetY,callback);
		getElement(prefix).innerHTML = newSlider.getHTML();
		this.sliders[this.sliders.length] = newSlider;
		
		return newSlider;
	};
	
	this.getEvent = function(ev){
		return ev ? ev : ((window.event) ? window.event : null);
	};
	
	this.captureDragEvent = function(ev, obj){
		if(obj.startDragX >= 0 && obj.startDragY >= 0 && obj.activeSliderId > -1){
			var activeSlider = obj.sliders[obj.activeSliderId];
			var mouseEvent = obj.getEvent(ev);
			
			if(obj.rectContains(activeSlider.thumbX,activeSlider.thumbY,activeSlider.thumbWidth,activeSlider.thumbHeight,obj.startDragX,obj.startDragY)){
				var containerPos = activeSlider.getOuterPosition();
				
				if(activeSlider.orientation == activeSlider.CONSTRAINT_HORIZONTAL){
					var curMouseX = mouseEvent.clientX + getLeftScrollOffset();
					var leftValue = activeSlider.thumbX + (curMouseX - obj.startDragX) - containerPos[0];
					var containerWidth = activeSlider.getOuterWidth();
					
					if(leftValue < 0)
						leftValue = 0;
					else if(leftValue > containerWidth-activeSlider.thumbWidth)
						leftValue =  containerWidth-activeSlider.thumbWidth;
						
					activeSlider.setThumbLeft(leftValue);
				}
				else{
					var curMouseY = mouseEvent.clientY + getTopScrollOffset();
					var topValue = activeSlider.thumbY + (curMouseY - obj.startDragY) - containerPos[1];
					var containerHeight = activeSlider.getOuterHeight();
					
					if(topValue < 0)
						topValue = 0;
					else if(topValue > containerHeight-activeSlider.thumbHeight)
						topValue = containerHeight-activeSlider.thumbHeight;
						
					activeSlider.setThumbTop(topValue);
				}
			}
		}
	};
	
	this.rectContains = function(x,y,width,height,px,py){
		return x <= px && x+width >= px && y <= py && y+height >= py;
	}
	
	this.onMouseUp = function(ev,obj){
		obj.mouseDown = false;
		obj.startDragX = -1;
		obj.startDragY = -1;
		obj.activeSliderId = -1;
	};
	
	this.onMouseDown = function(ev,obj){
		obj.mouseDown = true;
		var mouseEvent = obj.getEvent(ev);
		obj.startDragX = mouseEvent.clientX + getLeftScrollOffset();
		obj.startDragY = mouseEvent.clientY + getTopScrollOffset();
		
		for(var i = 0; i < obj.sliders.length; i++){
			var curSlider = obj.sliders[i];
			curSlider.updateThumbPosition();
			
			if(obj.rectContains(curSlider.thumbX,curSlider.thumbY,curSlider.thumbWidth,curSlider.thumbHeight,obj.startDragX,obj.startDragY)){
				obj.activeSliderId = i;
			}
		}
	};
	
	this.registerEvents = function(){
		var _this = this;
		document.onmousedown = function(ev){
			_this.onMouseDown(ev,_this);
		};
		
		document.onmouseup = function(ev){
			_this.onMouseUp(ev,_this);
		};
		
		document.onmousemove = function(ev){
			if(_this.mouseDown){
				_this.captureDragEvent(ev,_this);
			}
		};
	};
	
	this.init();
}
