/*
	Slider

	Last modification 16.06.2011 by JeDu

	Tested in FF4, IE6, IE7, IE8, OP11, SF5, CH8


	***                ***	outerRange
	   +++          +++	innerRange
	      X--------X	valueRange
*/

function mdxSlider(config) {
	this.config = config;

	function confError(variable) { return 'Die Konfiguration ist unvollständig.<br>' + variable + ' nicht gesetzt.'; }

	if (typeof(config.element) != 'object') { config.element = document.getElementById(typeof config.element === 'string' ? config.element : 'slider' ); }
	if (typeof(config.type) != 'string') {
		config.type = 'range';
	} else {
		config.type = config.type.toLowerCase();
		if (config.type != 'range' && config.type === 'from' && config.type === 'to') { config.type = 'range'; }
	}

	if (typeof config.width != 'number') { config.element.innerHTML = confError('width'); return; }
	if (typeof config.height != 'number') { config.element.innerHTML = confError('height'); return; }

	if (typeof(config.outerRange) != 'object') {
		config.outerRange = { min:0, max:config.width, background:'none' };
	} else {
		if (typeof config.outerRange.min != 'number') { config.element.innerHTML = confError('outerRange.min'); return; }
		if (typeof config.outerRange.max != 'number') { config.element.innerHTML = confError('outerRange.max'); return; }
		if (typeof config.outerRange.background != 'string') { config.outerRange.background = 'none'; }
	}

	if (typeof(config.innerRange) != 'object') {
		config.innerRange = { min:0, max:config.width, background:'none' };
	} else {
		if (typeof config.innerRange.min != 'number') { config.innerRange.min = config.outerRange.min; }
		if (typeof config.innerRange.max != 'number') { config.innerRange.max = config.outerRange.max; }
		if (typeof config.innerRange.background != 'string') { config.innerRange.background = 'none'; }
	}

	if (typeof(config.valueRange) != 'object') { config.element.innerHTML = confError('valueRange'); return; }
	if (typeof config.valueRange.background != 'string') { config.element.innerHTML = confError('valueRange.background'); return; }

	if (typeof(config.disabled) != 'boolean') { config.disabled = false; }

	switch (config.type) {
		case 'range':
			if (typeof(config.leftTrack) != 'object') { config.element.innerHTML = confError('leftTrack'); return; }
			if (typeof(config.leftTrack.value) != 'number') { config.element.innerHTML = confError('leftTrack.value'); return; }
			if (typeof(config.leftTrack.width) != 'number') { config.element.innerHTML = confError('leftTrack.width'); return; }
			if (typeof(config.leftTrack.height) != 'number') { config.element.innerHTML = confError('leftTrack.height'); return; }
			if (typeof(config.leftTrack.offset) != 'number') { config.element.innerHTML = confError('leftTrack.offset'); return; }
			if (typeof(config.leftTrack.background) != 'string') { config.element.innerHTML = confError('leftTrack.background'); return; }

			if (typeof(config.rightTrack) != 'object') {
				config.rightTrack.value = config.leftTrack.value;
				config.rightTrack.width = config.leftTrack.width;
				config.rightTrack.height = config.leftTrack.height;
				config.rightTrack.offset = config.leftTrack.offset;
				config.rightTrack.background = config.leftTrack.background;
			} else {
				if (typeof(config.rightTrack.value) != 'number') { config.element.innerHTML = confError('rightTrack.value'); return; }
				if ((typeof(config.rightTrack.width) == 'undefined') && (typeof(config.rightTrack.height) == 'undefined') && (typeof(config.rightTrack.offset) == 'undefined') && (typeof(config.rightTrack.background) == 'undefined')) {
					config.rightTrack.width = config.leftTrack.width;
					config.rightTrack.height = config.leftTrack.height;
					config.rightTrack.offset = config.leftTrack.offset;
					config.rightTrack.background = config.leftTrack.background;
				} else {
					if (typeof(config.rightTrack.width) != 'number') { config.element.innerHTML = confError('rightTrack.width'); return; }
					if (typeof(config.rightTrack.height) != 'number') { config.element.innerHTML = confError('rightTrack.height'); return; }
					if (typeof(config.rightTrack.offset) != 'number') { config.element.innerHTML = confError('rightTrack.offset'); return; }
					if (typeof(config.rightTrack.background) != 'string') { config.element.innerHTML = confError('rightTrack.background'); return; }
				}
			}
			break;

		case 'from':
			if (typeof(config.leftTrack) != 'object') { config.element.innerHTML = confError('leftTrack'); return; }
			if (typeof(config.leftTrack.value) != 'number') { config.element.innerHTML = confError('leftTrack.value'); return; }
			if (typeof(config.leftTrack.width) != 'number') { config.element.innerHTML = confError('leftTrack.width'); return; }
			if (typeof(config.leftTrack.height) != 'number') { config.element.innerHTML = confError('leftTrack.height'); return; }
			if (typeof(config.leftTrack.offset) != 'number') { config.element.innerHTML = confError('leftTrack.offset'); return; }
			if (typeof(config.leftTrack.background) != 'string') { config.element.innerHTML = confError('leftTrack.background'); return; }

			config.rightTrack = {};
			break;

		case 'to':
			if (typeof(config.rightTrack) != 'object') { config.element.innerHTML = confError('rightTrack'); return; }
			if (typeof(config.rightTrack.value) != 'number') { config.element.innerHTML = confError('rightTrack.value'); return; }
			if (typeof(config.rightTrack.width) != 'number') { config.element.innerHTML = confError('rightTrack.width'); return; }
			if (typeof(config.rightTrack.height) != 'number') { config.element.innerHTML = confError('rightTrack.height'); return; }
			if (typeof(config.rightTrack.offset) != 'number') { config.element.innerHTML = confError('rightTrack.offset'); return; }
			if (typeof(config.rightTrack.background) != 'string') { config.element.innerHTML = confError('rightTrack.background'); return; }

			config.leftTrack = {};
			break;
	}

	var _this = this, mouse = { x:0, target:null };

	config.element.style.position = 'relative';
	config.element.style.width = config.width + 'px';
	config.element.style.height = config.height + 'px';
	config.element.style.background = config.outerRange.background;
	setUnselectable(config.element);

	config.innerRange.element = document.createElement('div');
	config.innerRange.element.style.position = 'absolute';
	config.innerRange.element.style.left = '0';
	config.innerRange.element.style.top = '0';
	config.innerRange.element.style.width = config.width + 'px';
	config.innerRange.element.style.height = config.height + 'px';
	config.innerRange.element.style.background = config.innerRange.background;
	config.innerRange.element.style.clip = 'rect(0px ' + config.width + 'px ' + config.height + 'px 0px)';
	config.innerRange.element = config.element.appendChild(config.innerRange.element);
	setUnselectable(config.innerRange.element);

	config.valueRange.element = document.createElement('div');
	config.valueRange.element.style.position = 'absolute';
	config.valueRange.element.style.left = '0';
	config.valueRange.element.style.top = '0';
	config.valueRange.element.style.width = config.width + 'px';
	config.valueRange.element.style.height = config.height + 'px';
	config.valueRange.element.style.background = config.valueRange.background;
	config.valueRange.element.style.clip = 'rect(0px ' + config.width + 'px ' + config.height + 'px 0px)';
	config.valueRange.element = config.innerRange.element.appendChild(config.valueRange.element);
	setUnselectable(config.valueRange.element);

	if (config.type == 'range' || config.type == 'from') {
		config.leftTrack.element = document.createElement('div');
		config.leftTrack.element.style.position = 'absolute';
		config.leftTrack.element.style.left = '0';
		config.leftTrack.element.style.top = '0';
		config.leftTrack.element.style.width = config.leftTrack.width + 'px';
		config.leftTrack.element.style.height =  config.leftTrack.height + 'px';
		config.leftTrack.element.style.background =  config.leftTrack.background;
		config.leftTrack.element.style.cursor = 'pointer';
		config.leftTrack.element = config.element.appendChild(config.leftTrack.element);
		setUnselectable(config.leftTrack.element);
	}

	if (config.type == 'range' || config.type == 'to') {
		config.rightTrack.element = document.createElement('div');
		config.rightTrack.element.style.position = 'absolute';
		config.rightTrack.element.style.left = '0';
		config.rightTrack.element.style.top = '0';
		config.rightTrack.element.style.width = config.rightTrack.width + 'px';
		config.rightTrack.element.style.height =  config.rightTrack.height + 'px';
		config.rightTrack.element.style.background =  config.rightTrack.background;
		config.rightTrack.element.style.cursor = 'pointer';
		config.rightTrack.element = config.element.appendChild(config.rightTrack.element);
		setUnselectable(config.rightTrack.element);
	}

	var mdxFunctions = {
		mdxStripText:function (text, len, attach) {
			attach = attach || '';
			var retText = text.substr(0, len);
			return retText + (text != retText ? attach : '');
		},
		mdxFormatNumber:function (num) {
			if (typeof num == 'string') { num = parseFloat(num); }
				
			if (num < 0) {
				var sign = '-';
				num = -num;
			} else {
				var sign = '';
			}

			num = num.toString();

			var decPoint = num.indexOf('.');
			if (decPoint != -1) {
				var intPlaces = num.substr(0, decPoint);
				var decPlaces = num.substr(decPoint + 1);
			} else {
				var intPlaces = num;
				var decPlaces = '';
			}

			if (intPlaces.length > 3) {		
				var intPlacesOut = intPlaces.substr(intPlaces.length - 3);
			} else {
				var intPlacesOut = intPlaces;
			}
			for (var i = intPlaces.length - 6; i >= -2; i -= 3) {
				if (i >= 0) {
					intPlacesOut = intPlaces.substr(i, 3) + '.' + intPlacesOut;
				} else {
					intPlacesOut = intPlaces.substr(0, 3 + i) + '.' + intPlacesOut;
					break;
				}
			}
			return sign + intPlacesOut + (decPoint != -1 ? ',' + decPlaces : '');
		}
	};
	mdxStripText = mdxFunctions.mdxStripText;
	mdxFormatNumber = mdxFunctions.mdxFormatNumber;

	this.disable = function (state) {
		if (typeof(state) == 'undefined') {
			return config.disabled;
		} else if (state == config.disabled) {
			return config.disabled;
		} else if (state === true) {
			config.disabled = true;
			if (config.leftTrack.element) { config.leftTrack.element.style.cursor = 'default'; }
			if (config.rightTrack.element) { config.rightTrack.element.style.cursor = 'default'; }
			if (typeof(config.onDisable) === 'function') {
				config.onDisable.call(config);
			}
		} else {
			config.disabled = false;
			if (config.leftTrack.element) { config.leftTrack.element.style.cursor = 'pointer'; }
			if (config.rightTrack.element) { config.rightTrack.element.style.cursor = 'pointer'; }
			if (typeof(config.onEnable) === 'function') {
				config.onEnable.call(config);
			}
		}
		return config.disabled;
	};
	this.setInnerRange = function (min, max) {
		if (typeof(min) != 'undefined' && min != config.innerRange.min) {
			config.innerRange.min = min;
		}
		if (typeof(max) != 'undefined' && max != config.innerRange.max) {
			config.innerRange.max = max;
		}

		var tmp;
		if (max < min) {
			tmp = min;
			min = max;
			max = tmp;
		}
		if (config.rightTrack.value < config.leftTrack.value) {
			tmp = config.leftTrack.value;
			config.leftTrack.value = config.rightTrack.value;
			config.rightTrack.value = tmp;
		}

		if (config.innerRange.min < config.outerRange.min) { config.innerRange.min = config.outerRange.min; }
		if (config.innerRange.max > config.outerRange.max) { config.innerRange.max = config.outerRange.max; }
		config.innerRange.element.style.clip = 'rect(0px ' + config.innerRange.max + 'px ' + config.height + 'px ' + config.innerRange.min + 'px)';

		if (config.type == 'to') { config.leftTrack.value = config.innerRange.min; }
		if (config.type == 'from') { config.rightTrack.value = config.innerRange.max; }

		if (config.rightTrack.element) {
			mouse.target = config.rightTrack.element;
			mouse.x = config.rightTrack.value;
			checkChange('load');
		}
		if (config.leftTrack.element) {
			mouse.target = config.leftTrack.element;
			mouse.x = config.leftTrack.value;
			checkChange('load');
		}
		mouse.target = null;
		mouse.x = 0;

		return { min:config.innerRange.min, max:config.innerRange.max };
	}

	addEvent(document, 'mousedown', mouseDownEvent);
	addEvent(document, 'mouseup',  mouseUpEvent);

	function mouseDownEvent(e) {
		var target;
		if (e.target) {
			target = e.target;
		} else if (e.srcElement) {
			target = e.srcElement;
		}
		if (target.nodeType == 3) {
			// defeat Safari bug
			target = target.parentNode;
		}

		if (!config.disabled && (target == config.leftTrack.element || target == config.rightTrack.element)) {
			mouse.target = target;

			if (navigator.userAgent.match(/(Android|iPhone|iPad|iPod)/i)) {
				if(e.touches.length == 1) {
					mouse.x = e.touches[0].pageX;
				}
			} else if (window.event) {
				mouse.x = window.event.clientX;
			} else {
				mouse.x = e.pageX;
			}
			checkChange('start');

			if (e.stopPropagation) { e.stopPropagation(); }
			if (e.preventDefault) { e.preventDefault(); }
			return false;
		}
	}

	function mouseUpEvent(e, keepPos) {
		if (!config.disabled && mouse.target != null) {
			if (!keepPos) {
				if (navigator.userAgent.match(/(Android|iPhone|iPad|iPod)/i)) {
					if(e.touches.length == 1) {
						mouse.x = e.touches[0].pageX;
					}
				} else if (window.event) {
					mouse.x = window.event.clientX;
				} else {
					mouse.x = e.pageX;
				}
			}
			checkChange('end');

			mouse.target = null;
			mouse.x = 0;

			if (e.stopPropagation) { e.stopPropagation(); }
			if (e.preventDefault) { e.preventDefault(); }
			return false;
		}
	}

	addEvent(document, 'mousemove', mouseMoveEvent);

	function mouseMoveEvent(e) {
		if (!config.disabled && mouse.target != null) {
/*
			if (window.event && window.event.button == 0) {
				return mouseUpEvent(e, true);
			}
*/

			if (navigator.userAgent.match(/(Android|iPhone|iPad|iPod)/i)) {
				if(e.touches.length == 1) {
					mouse.x = e.touches[0].pageX;
				}
			} else if (window.event) {
				mouse.x = window.event.clientX;
			} else {
				mouse.x = e.pageX;
			}
			checkChange('move');

			if (e.stopPropagation) { e.stopPropagation(); }
			if (e.preventDefault) { e.preventDefault(); }
			return false;
		}
	}

	if (navigator.userAgent.match(/(Android|iPhone|iPad|iPod)/i)) {
		document.addEventListener("touchstart", mouseDownEvent, false);
		document.addEventListener("touchmove", mouseMoveEvent, false);
		document.addEventListener("touchcancel", mouseUpEvent, false);
		document.addEventListener("touchend", mouseUpEvent, false);
	}

	this.setInnerRange(config.innerRange.min, config.innerRange.max);

	function checkChange(eventName) {
		var xNew = mouse.x - (eventName != 'load' ? getAbsPos(config.element).x : 0);
		if (xNew < config.innerRange.min) {
			xNew = config.innerRange.min;
		} else if (xNew > config.innerRange.max) {
			xNew = config.innerRange.max;
		}

		if (typeof(config.onBeforeChange) === 'function') {
			var xNewTmp = config.onBeforeChange.call(config, xNew);
			if (typeof(xNewTmp) === 'number') { xNew = xNewTmp; }
		}

		if (xNew < config.innerRange.min) {
			xNew = config.innerRange.min;
		} else if (xNew > config.innerRange.max) {
			xNew = config.innerRange.max;
		}

		mouse.target.style.left = (xNew + (mouse.target == config.leftTrack.element ? config.leftTrack.offset : config.rightTrack.offset)) + 'px';
		if (eventName != 'load') {
			if (config.leftTrack.element) { config.leftTrack.value = (parseInt(config.leftTrack.element.style.left) - config.leftTrack.offset); }
			if (config.rightTrack.element) { config.rightTrack.value = (parseInt(config.rightTrack.element.style.left) - config.rightTrack.offset); }

			if (config.type == 'range' && config.rightTrack.value < config.leftTrack.value) {
				var tmp = config.leftTrack.value;
				config.leftTrack.value = config.rightTrack.value;
				config.rightTrack.value = tmp;

				var tmp = config.leftTrack.element.style.left;
				config.leftTrack.element.style.left = config.rightTrack.element.style.left;
				config.rightTrack.element.style.left = tmp;

				mouse.target = (mouse.target == config.leftTrack.element ? config.rightTrack.element : config.leftTrack.element);
			}
		} else if (mouse.target == config.leftTrack.element) {
			config.leftTrack.value = (parseInt(config.leftTrack.element.style.left) - config.leftTrack.offset);
		} else {
			config.rightTrack.value = (parseInt(config.rightTrack.element.style.left) - config.rightTrack.offset);
		}
		config.valueRange.element.style.clip = 'rect(0px ' + config.rightTrack.value + 'px ' + config.height + 'px ' + config.leftTrack.value + 'px)';

		if (config.leftTrack.element && config.rightTrack.element) {
			if (mouse.target === config.leftTrack.element) {
				config.leftTrack.element.style.zIndex = 2;
				config.rightTrack.element.style.zIndex = 1;
			} else {
				config.leftTrack.element.style.zIndex = 1;
				config.rightTrack.element.style.zIndex = 2;
			}
		}

		if (typeof(config.onChange) === 'function') {
			config.onChange.call(config, eventName);
		}
	}

	function addEvent(obj, type, fn) {
		if (obj.attachEvent) {
			var rnd = parseInt(Math.random() * 0xffffffff, 16).toString() + parseInt(Math.random() * 0xffffffff, 16).toString() + parseInt(Math.random() * 0xffffffff, 16).toString() + parseInt(Math.random() * 0xffffffff, 16).toString();
			obj['e' + type + fn + rnd] = fn;
			obj[type + fn + rnd] = function() { obj['e' + type + fn + rnd](window.event); }
			obj.attachEvent('on' + type, obj[type + fn + rnd]);
		} else {
			obj.addEventListener(type, fn, false);
		}
	}

	function getAbsPos(elem) {
		var x = 0, y = 0;
		while (elem != null) {
			x += elem.offsetLeft;
			y += elem.offsetTop;
			elem = elem.offsetParent;
		}

		return { "x":x, "y":y };
	}

	function setUnselectable(elem) {
		if (elem == undefined) { return; }
		addEvent(elem, 'selectstart', function () { return false; });
		elem.style.MozUserSelect = 'none';
		elem.style.WebkitUserSelect = 'none';
		elem.style.KhtmlUserSelect = 'none';
		elem.style.userSelect = "none";
		elem.unselectable = 'on';
	}
}
