var MultiSlider = function(name, values,labels, pAutoStepWidth, pFirstTickerWidth){

	this.slider = document.getElementById(name+'Slider');
	this.slider.slider = this;
	this.area = document.getElementById(name+'SliderArea');
	this.sliderLeft = document.getElementById(name+'SliderKnobLeft');
	this.sliderRight = document.getElementById(name+'SliderKnobRight');
	this.hiddenLeft = document.getElementById(name+'Max');
	this.viewLeft = document.getElementById(name+'MaxView');
	this.hiddenRight = document.getElementById(name+'Min');
	this.viewRight = document.getElementById(name+'MinView');
	this.areasArrayLeftPos = new Array();
	this.autoStepWidth = pAutoStepWidth;
	this.dataNodes = [];

	var innerNodes = this.area.getElementsByTagName('a');
	for (i in innerNodes) {
		var node = innerNodes[i];
		var className = node.className;
		if(className && className.indexOf('sliderData') >= 0)
		{
			this.dataNodes[this.dataNodes.length] = node;
		}
	}

	this.area.parent = this;
	this.sliderLeft.parent = this;
	this.sliderRight.parent = this;

	this.length = this.area.offsetWidth;
	this.values = values;
	this.labels = labels;
	this.step = this.values.length;
	this.stepWidth = (this.area.offsetWidth) / this.step;

	
	var wTotal = 0;
	var wCounter = 0;
	
	var innerNodes = this.area.getElementsByTagName('a');
	for (i in innerNodes) {
		var node = innerNodes[i];
		var className = node.className;
		if(className && className.indexOf('sliderData') >= 0) {
			if ( !this.autoStepWidth ) {
				node.style.left = wTotal+"px";
				this.areasArrayLeftPos[wCounter++] = wTotal;
				wTotal += eval((node.style.width).replace(/px/,''));
			}
		}
	}
	//Last one at the edge of the border
	this.areasArrayLeftPos[wCounter++] = wTotal;

	this.dragObject = null;
	this.mouseOffset = null;
	this.updateCallBack = null;

	this.updateFromHidden();
	
	disableSelection(this.area);
	disableSelection(this.sliderLeft);
	disableSelection(this.sliderRight);

	if(typeof MultiSlider.all == 'undefined'){
		MultiSlider.all = [this]; 
	}else{
		MultiSlider.all[MultiSlider.all.length] = this;
	} 
		
	this.sliderLeft.onmousedown = this.mouseDown;
	this.sliderRight.onmousedown = this.mouseDown;
	this.area.onmousedown = this.mouseDownArea;
	this.area.onmousemove = this.mouseMove;
	document.onmouseup = MultiSlider.mouseUp;
};
MultiSlider.prototype.stepCalculator = function(pos){
	if ( this.autoStepWidth ) {
		return Math.round(pos / this.stepWidth + 0.5);
	} else {
		for (var i=1; i<this.areasArrayLeftPos.length; i++) {
			if(pos < this.areasArrayLeftPos[i]) {
				return i-1;
			}
		}
		return this.areasArrayLeftPos.length-1;
	}
};
MultiSlider.prototype.updateHidden = function(){
	var updated = false;
	if(this.values.length > 0) {
		if ( this.sliderLeft.step==undefined || this.sliderLeft.step < 0 || this.sliderLeft.step >= this.step ) {
			this.sliderLeft.step = 0;
		}
		if ( this.sliderRight.step==undefined || this.sliderRight.step < 0 || this.sliderRight.step >= this.step ) {
			this.sliderRight.step = eval(this.sliderRight.step-1);
		}
		var leftValue = this.values[this.sliderLeft.step];
		var rightValue = this.values[this.sliderRight.step]; 

		var leftLabel = this.labels[this.sliderLeft.step];
		var rightLabel = this.labels[this.sliderRight.step]; 

		if(leftValue != this.hiddenLeft.value){
			this.hiddenLeft.value = leftValue;
			this.viewLeft.value = leftLabel;
			updated = true;
		}
		if(rightValue != this.hiddenRight.value)
		{
			this.hiddenRight.value = rightValue;
			this.viewRight.value = rightLabel;
			updated = true;
		}
	}
	return updated;
};
MultiSlider.prototype.updateFromHidden = function(){
	var leftIndex = this.step - 1;
	var rightIndex = this.step - 1;
	var leftFound = false;
	var rightFound = false;
	for (i in this.values) {
		if (this.values.hasOwnProperty(i)) {
			if(this.hiddenLeft.value == this.values[i]){
				leftIndex = parseInt(i);
				this.viewLeft.value = this.labels[leftIndex];
				leftFound = true;
			}
			if(this.hiddenRight.value == this.values[i]){
				rightIndex = parseInt(i);
				this.viewRight.value = this.labels[rightIndex];
				rightFound = true;
			}
		}
	}
	
	if(!leftFound) {
		this.viewLeft.value = this.hiddenLeft.value.replace(/[0-9]+?_/,'');
	}
	if(!rightFound) {
		this.viewRight.value = this.hiddenRight.value.replace(/[0-9]+?_/,'');
	}

	this.setLeftStep(leftIndex);
	this.setRightStep(rightIndex);

	this.updateDataClasses();
};	
MultiSlider.prototype.setCallback = function(fx){
	this.updateCallback = fx;
};
MultiSlider.prototype.callback = function(){
	if(this.updateCallback){
		this.updateCallback(this);
	}
};
MultiSlider.prototype.setLeftStep = function(step){
	step = Math.max(0,step);
	step = Math.min(this.step,step);
	this.sliderLeft.step = step;

	var moveX;
	if (this.autoStepWidth) {
		moveX = this.stepWidth * step - (this.sliderLeft.offsetWidth/2.0);
	} else {
	    if(step == 0){
    		moveX = this.areasArrayLeftPos[step];
		}else{
       		moveX = this.areasArrayLeftPos[step] - (this.sliderLeft.offsetWidth/2.0);
		}
	}

	this.sliderLeft.style.left  = moveX+"px";
	this.sliderLeft.pos = moveX;
};
MultiSlider.prototype.setRightStep = function(step){
	step = Math.max(0,step);
	step = Math.min(this.step,step);
	this.sliderRight.step = step;
	
	var moveX;
	if (this.autoStepWidth) {
		moveX = this.stepWidth * (step+1) - (this.sliderRight.offsetWidth/2.0);
	} else {
	    if(step == this.step-1){
            moveX = this.areasArrayLeftPos[step+1] - (this.sliderRight.offsetWidth);
        }else{
            moveX = this.areasArrayLeftPos[step+1] - (this.sliderRight.offsetWidth/2.0);
        }
	}

	this.sliderRight.style.left = moveX+"px";
	this.sliderRight.pos = moveX;
};
MultiSlider.prototype.getAbsolutePosition = function(e){
	var left = 0;
	var top  = 0;
	while (e.offsetParent){
		left += e.offsetLeft;
		top  += e.offsetTop;
		e     = e.offsetParent;
	}
	left += e.offsetLeft;
	top  += e.offsetTop;
	return {x:left, y:top};
};
MultiSlider.prototype.getMouseOffset = function(target, ev){
	var docPos    = this.getAbsolutePosition(target);
	var mousePos  = this.getMouseCoords(ev);
	return {x:mousePos.x - docPos.x, y:mousePos.y - docPos.y};
};
MultiSlider.prototype.getMouseCoords = function(ev){
	if(ev.pageX || ev.pageY){
		return {x:ev.pageX, y:ev.pageY};
	}
	return {
		//http://www.softcomplex.com/docs/get_window_size_and_scrollbar_position.html
		//Good for IE 6 + 7 w and w/o. DTD
		x:ev.clientX + document.body.clientLeft + document.documentElement.scrollLeft + document.body.scrollLeft,
		y:ev.clientY + document.body.clientTop + document.documentElement.scrollTop + document.body.scrollTop
	};
};
MultiSlider.prototype.updateDataClasses = function(){
	for (i in this.dataNodes) {
		var node = this.dataNodes[i];
		if(i < this.sliderLeft.step || i > this.sliderRight.step) {
			MultiSlider.addNodeClass(node, 'outOfScope');
		}else{
			MultiSlider.removeNodeClass(node, 'outOfScope');
		}
	}
};
MultiSlider.addNodeClass = function(node, className){
	if(!node.className){
		node.className = className;
	}
	if(node.className.indexOf(className)==-1){
		node.className = node.className + ' ' + className;
	}
};
MultiSlider.removeNodeClass = function(node, className){
	if(node.className){
		if(node.className.indexOf(className)!=-1){
			node.className = node.className.replace(className,'');
		}
	}
};
MultiSlider.prototype.mouseDownArea = function(ev){
	ev = ev || window.event;
	var multiSlider = this.parent;
	if(!multiSlider.dragObject){
		var mouseOffset = multiSlider.getMouseOffset(multiSlider.area, ev);
		var step = multiSlider.stepCalculator(mouseOffset.x);
		multiSlider.setLeftStep(step);
		multiSlider.setRightStep(step);
		multiSlider.updateDataClasses();
		var updated = multiSlider.updateHidden();
		if(updated){
			multiSlider.callback();
		}		
	}
	return false;
};
MultiSlider.prototype.mouseDown = function(ev){
	ev = ev || window.event;
	var multiSlider = this.parent;
	multiSlider.dragObject = this;
	multiSlider.mouseOffset = multiSlider.getMouseOffset(this, ev);
	return false;
};
MultiSlider.prototype.mouseMove = function(ev){
	ev = ev || window.event;
	if(!this.parent){
		return;
	}
	var multiSlider = this.parent;
	if(multiSlider.dragObject){
		var minStep = 0;
		var maxStep = multiSlider.step - 1;
		
		if(multiSlider.dragObject == multiSlider.sliderLeft){
			maxStep = multiSlider.sliderRight.step;
		}else if(multiSlider.dragObject == multiSlider.sliderRight){
			minStep = multiSlider.sliderLeft.step;
		}
		
		var mousePos = multiSlider.getMouseCoords(ev);
		var absAreaPos = multiSlider.getAbsolutePosition(multiSlider.slider); 
		var nextX = (mousePos.x - absAreaPos.x) - multiSlider.mouseOffset.x;
		
		var nextStep = 0;
		//Get the nearest separation
		if (this.autoStepWidth) {
			nextStep = multiSlider.stepCalculator(nextX);
		} else {
			var closeDiff = Math.abs(nextX - multiSlider.areasArrayLeftPos[0]);
			var closeLeftStep = 0;
			for (var i=1; i<multiSlider.areasArrayLeftPos.length; i++) {
				var diff = Math.abs(nextX - multiSlider.areasArrayLeftPos[i]);
				if(diff < closeDiff) {
					closeDiff = diff;
					closeLeftStep = i;
				}
			}
			if(multiSlider.dragObject == multiSlider.sliderLeft){
				nextStep = closeLeftStep;
			}else if(multiSlider.dragObject == multiSlider.sliderRight){
				nextStep = closeLeftStep-1;
			}
		}
		
		nextStep = Math.min(nextStep, maxStep);
		nextStep = Math.max(nextStep, minStep);
		
		if(multiSlider.dragObject == multiSlider.sliderLeft){
			multiSlider.setLeftStep(nextStep);
		}else if(multiSlider.dragObject == multiSlider.sliderRight){
			multiSlider.setRightStep(nextStep);
		}

		multiSlider.updateDataClasses();
	}
	return false;
};
MultiSlider.mouseUp = function(ev){
	ev = ev || window.event;
	for (key in MultiSlider.all) {
		if (MultiSlider.all.hasOwnProperty(key)) {
			var dragObject = MultiSlider.all[key].dragObject;
			if(dragObject){
				var multiSlider = dragObject.parent;
				multiSlider.dragObject = null;
				var updated = multiSlider.updateHidden();
				if(updated){
					multiSlider.callback();
				}
			}
		}
	}
	return false;
};
