/* (C) 2009 Musikhaus Thomann. Do not even think about copying, stealing or changing the code. MER dunnit. */

function CAJAX(Pcb,PgetXML,PrequestURL) {
	var callBack = Pcb;
	var startCallBack = undefined;
	var readyCallBack = undefined;
	
	var getXML = PgetXML;
	var requestURL = PrequestURL;
	var requestObj = undefined;
	
	var _const = function () {
		if (window.XMLHttpRequest) {
			requestObj = new XMLHttpRequest();
		} else if (window.ActiveXObject) {
			requestObj = new ActiveXObject('Microsoft.XMLHTTP');
		}
	}
	var localCallback = function() {
		if (requestObj.readyState == 4) {
			if (requestObj.status == 200) {
				if (getXML) {
					callBack(requestObj.responseXML);
				} else {
					callBack(requestObj.responseText);
				}
				if (readyCallBack) readyCallBack();
			}
		}
	}
	this.send = function () {
		if (requestObj != undefined) {
			if (startCallBack) startCallBack();
			
			requestObj.open('GET',requestURL,true);
			requestObj.setRequestHeader("Pragma", "no-cache");
			requestObj.setRequestHeader("Cache-Control", "must-revalidate");
			requestObj.setRequestHeader("If-Modified-Since", document.lastModified); 
			requestObj.onreadystatechange=localCallback;
			requestObj.send(null);
		}
	}
	this.setStartCallBack = function(Pscb) {
		startCallBack = Pscb;
	}
	this.setReadyCallBack = function(Prcb) {
		readyCallBack = Prcb;
	}
	_const();
}

////////////////////////////////////////////////////////////////////////////////////// CTicker ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

function CTicker(PparentId) {
	var parentId = PparentId;
	var parentBox = undefined;
	
	var outerBox = undefined;
	var scrollBox = undefined;
	
	var width = 250;
	var height = 20;
	var tickerNamePrefix = undefined;
	var currTickerId = undefined;

	var tickerTexts = new Array();
	var intervalHandle = undefined;
	
	var __self = this;
	
	var __const = function () {
		if (!addEvent) return;
		parentBox = document.getElementById(parentId);
		
		tickerNamePrefix = 'class_ticker_event';
		
		outerBox = document.createElement('div');
		outerBox.style.overflow = 'hidden';
		outerBox.style.width = width;
		outerBox.style.height = height;
		
		scrollBox = document.createElement('div');
		scrollBox.style.width = 2000;
		scrollBox.style.position = 'relative';
		scrollBox.style.left = width + 'px';
		
		outerBox.appendChild(scrollBox);
		parentBox.appendChild(outerBox);
	}
	this.addText = function (param,tickerText) {
		var bindObject;
		if (typeof param == 'string') {
			bindObject = document.getElementById(param);
		} else if (typeof param == 'object') {
			bindObject = param;
		}
		if (!bindObject) return;
		
		var nuId = tickerTexts.length;
		bindObject.tickerId = nuId;
		tickerTexts[nuId] = new Object();
		tickerTexts[nuId]['bindObject'] = bindObject;
		tickerTexts[nuId]['tickerText'] = tickerText;
		bindObject.onmouseover = startAnimation;
		bindObject.onmouseout = stopAnimation;
	}
	var startAnimation = function (event) {
		if (!event) event = window.event;

		var id = -1;
		if (event.target) {
			id = event.target.tickerId;
		} else if (event.srcElement) {
			id = event.srcElement.tickerId;
		}
		if (id >= 0) {
			scrollBox.innerHTML = tickerTexts[id]['tickerText'];
			currTickerId = id;
			intervalHandle = window.setInterval(anim,12);
		}
	}
	var stopAnimation = function (event) {
		if (currTickerId < 0) return;
		window.clearInterval(intervalHandle);
		currTickerId = -1;
		scrollBox.innerHTML = '';
		scrollBox.style.left = width + 'px';
	}
	var anim = function (event) {
		if (currTickerId >= 0) scrollBox.style.left = (parseInt(scrollBox.style.left.replace(/px/,'')) - 1) + 'px';
	}
	__const();
}

////////////////////////////////////////////////////////////////////////////////////// CDropdown ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

function CDropdown() {
	var callback = undefined;
	var parentBox = undefined;
	var selectorBox = undefined;
	var chosenBox = undefined;
	
	var objectId = undefined;
	var parentId = undefined;
	var classSelector = undefined;
	var classChosen = undefined;
	var chosenIndex = undefined;
	var meClicked = false;
	
	var stdBG1 = undefined;
	var stdBG2 = undefined;
	var highBG = undefined;
	var highBGPrev = undefined;
	var currBG = undefined;
	var stdBox = 'standardwert';
	var localNotifier = undefined;
	var desc = undefined;

	var rendered = false;
	var arrItems = new Array();
	var self = this;
	
	this.renderMe = function() {
		if (!addEvent) return;
		
		objectId = parseInt(Math.random() * 100000000);
		parentBox = document.getElementById(parentId);
		if (rendered) {
			if (chosenBox) parentBox.removeChild(chosenBox);
			if (selectorBox) parentBox.removeChild(selectorBox);
		}
		if (parentBox && objectId != undefined) {
			var box = document.createElement('div');
			box.innerHTML = stdBox;
			try { box.style.cursor = 'pointer'; } catch(e) {}
			chosenBox = box;
			box = document.createElement('div');
			box.innerHTML = stdBox;
			selectorBox = box;

			if (classSelector != undefined) {
				chosenBox.className = classChosen;
				selectorBox.className = classSelector;
			}
			chosenBox.onclick = boxClickHandler;
			selectorBox.style.display = 'none';
			selectorBox.style.position = 'absolute';
			
			addEvent(document,'click',documentClickHandler);
			
			if (arrItems.length > 0) {
				selectorBox.innerHTML = '';
				for (var i = 0; i < arrItems.length; i++) {
					var nunode = document.createElement("div");
					nunode.innerHTML = arrItems[i]['code'];
					nunode.id = objectId + '_' + i;
					if (i == 0) nunode.className = 'first';
					if (stdBG1 && stdBG2) {
						if (currBG == stdBG2) {
							nunode.style.backgroundColor = stdBG1;
							currBG = stdBG1;
						} else {
							nunode.style.backgroundColor = stdBG2;
							currBG = stdBG2;
						}
					}
					try { nunode.style.cursor = 'pointer'; } catch (e) {}
					if (arrItems[i]['isResetItem']) {
						//addEvent(nunode,'click',createSelectorClickHandler(i));
						addEvent(nunode,'click',createResetPriv());
					} else {
						addEvent(nunode,'click',createSelectorClickHandler(i));
					}
					selectorBox.appendChild(nunode);
				}
			}
			parentBox.appendChild(chosenBox);
			parentBox.appendChild(selectorBox);
			
			if (localNotifier && desc) {
				localNotifier.addText(chosenBox,desc);
			}
			rendered = true;
		}
	}
	this.addItem = function (value,code,presentation,sendBack,isResetItem) {
		if (!isResetItem) isResetItem = false; else isResetItem = true;
		var no = arrItems.length;
		arrItems[no] = new Object();
		arrItems[no]['value'] = value;
		arrItems[no]['code'] = code;
		arrItems[no]['presentation'] = presentation;
		arrItems[no]['sendBack'] = sendBack;
		arrItems[no]['isResetItem'] = isResetItem;
	}
	this.reset = function (triggerCB) {
		if (triggerCB) resetPriv(true); else resetPriv(false);
	}
	var createResetPriv = function() {
		return function() {
			resetPriv(true);
		}
	}
	var resetPriv = function (triggerCB) {
		if (rendered) {
			if (chosenIndex >= 0) {
				if (highBGPrev) document.getElementById(objectId + '_' + chosenIndex).style.backgroundColor = highBGPrev;
				chosenIndex = undefined;
			}
			chosenBox.innerHTML = stdBox;
			
			if (triggerCB) callback(self);
		}
	}
	this.clear = function () {
		if (rendered) {
			arrItems.length = 0;
			chosenBox.innerHTML = stdBox;
			chosenIndex = undefined;
			selectorBox.innerHTML = '';
		}
	}

	////// HANDLER  ///////////////////////////////////////////////////////////////////////////////////////////
	var boxClickHandler = function (event) {
		if (!event) event = window.event;
		
		if (selectorBox.style.display == 'block') {
			selectorBox.style.display = 'none';
		} else if (selectorBox.style.display == 'none' || selectorBox.style.display == '') {
			selectorBox.style.display = 'block';
		}
		meClicked = true;
		//event.cancelBubble = true; 
	}
	var createSelectorClickHandler = function (param) {
		return function (ev) {
			selectorClickHandler(ev,param);
		}
	}
	var selectorClickHandler = function (event,id) {
		selectorBox.style.display = 'none';
		if (id >= 0) {
			if (highBG) {
				if (chosenIndex >= 0 && highBGPrev) document.getElementById(objectId + '_' + chosenIndex).style.backgroundColor = highBGPrev;
				var chosen = document.getElementById(objectId + '_' + id);
				if (chosen) {
					highBGPrev = chosen.style.backgroundColor;
					chosen.style.backgroundColor = highBG;
				}
			}
			chosenIndex = id;
			chosenBox.innerHTML = arrItems[chosenIndex]['presentation'];
			callback(self);
		}
		event.cancelBubble = true;
	}
	var documentClickHandler = function (e) {
		if (!meClicked) selectorBox.style.display = 'none'; else meClicked = false;
	}

	////// SETTER /////////////////////////////////////////////////////////////////////////////////////////////
	this.setVisibility = function (val) {
		if (val) {
			selectorBox.style.display = 'none';
			chosenBox.style.display = 'block';
		} else {
			selectorBox.style.display = 'none';
			chosenBox.style.display = 'none';
		}
	}
	this.setParentId = function (val) {
		parentId = val;
	}
	this.setStyleClasses = function (valSelector,valChosen) {
		classSelector = valSelector;
		classChosen = valChosen;
	}
	this.setCallback = function (value) {
		callback = value;
	}
	this.setBGs = function (bg1,bg2,high) {
		stdBG1 = bg1;
		stdBG2 = bg2;
		highBG = high;
	}
	this.setStd = function(value) {
		stdBox = value;
	}
	this.setNotifier = function(PNotifier,Pdesc) {
		localNotifier = PNotifier;
		desc = Pdesc;
	}
	this.setActive = function(value) {
		if (!chosenBox || !selectorBox) return;
		var id;
		if (document.getElementById(objectId + '_' + chosenIndex)) document.getElementById(objectId + '_' + chosenIndex).style.backgroundColor = highBGPrev;
		for (var i = 0; i < arrItems.length; i++) { //get id by value
			if (arrItems[i]['value'] == value) {
				id = i;
			}
		}
		if (id >= 0) {
			chosenIndex = id;
			highBGPrev = document.getElementById(objectId + '_' + id).style.backgroundColor;
			document.getElementById(objectId + '_' + id).style.backgroundColor = highBG;
			chosenBox.innerHTML = arrItems[chosenIndex]['presentation'];
		} else {
			chosenBox.innerHTML = stdBox;
			chosenIndex = undefined;
		}
	}

	////// GETTER /////////////////////////////////////////////////////////////////////////////////////////////
	this.getValue = function () {
		if (chosenIndex <= arrItems.length) return arrItems[chosenIndex]['value']; else return '';
	}
	this.getSendBack = function () {
		if (chosenIndex <= arrItems.length) return arrItems[chosenIndex]['sendBack'];
	}
	this.isRendered = function () {
		return rendered;
	}
}

////////////////////////////////////////////////////////////////////////////////////// CCheckbox ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

function CCheckbox(Pparent,Pcallback,Pdesc,PNotifier) {
	var parentId = Pparent;
	var callBack = Pcallback;
	var parentBox = undefined;
	var currentState = undefined; //active, inactive
	var currentClickState = undefined; //clicked, unclicked
	var currentBox = undefined;
	
	var BGinactive = '';
	var BGstd = '';
	var BGclicked = '';
	var Width = 20;
	var Height = 20;
	var desc = Pdesc;
	var localNotifier = PNotifier;
	var errorSet = false;
	var errorId = 'cCheckboxErrorMssg' + parseInt(Math.random()*1000);
	
	var __self = this;
	
	var __const = function () {
		parentBox = document.getElementById(parentId);
		if (parentBox) {
			currentState = 'active';
			currentClickState = 'unclicked';
			currentBox = createBox();
			parentBox.appendChild(currentBox);
			setBG();
		}
	}
	var createBox = function () {
		var box = document.createElement('div');
		box.style.width = Width;
		box.style.height = Height;
		//box.style.border = '1px solid red';
		try { box.style.cursor = 'pointer'; } catch (e) {}
		box.onmousedown = clickHandler;
		if (localNotifier && desc) { //see if we got the global notifier object
			localNotifier.addText(box,desc);
		}
		return box;
	}
	var setBG = function () {
		if (!BGinactive || !BGclicked || !BGstd) showErrorMssg('notice that there is no BG set!');
		if (currentState == 'inactive') {
			currentBox.style.background = 'url(' + BGinactive + ')';
		} else {
			if (currentClickState == 'clicked') {
				currentBox.style.background = 'url(' + BGclicked + ')';
			} else {
				currentBox.style.background = 'url(' + BGstd + ')';
			}
		}
		currentBox.style.backgroundRepeat = 'no-repeat';
		currentBox.style.backgroundPosition = 'center center';
	}
	var setDim = function () {
		currentBox.style.width = Width;
		currentBox.style.height = Height;
	}
	var showErrorMssg = function (msg) {
		if (errorSet) return;
		if (!parentBox) return;
		var b = document.createElement('span');
		b.id = errorId;
		b.innerHTML = msg;
		parentBox.appendChild(b);
		errorSet = true;
	}
	var removeErrorMssg = function () {
		if (!errorSet) return;
		if (!parentBox) return;
		if (!document.getElementById(errorId)) return;
		parentBox.removeChild(document.getElementById(errorId));
	}

	////// SETTER ////////////////////////////////////////////////////////////////////////////////////////////
	this.setBoxes = function (inactive,std,clicked) {
		if (inactive) BGinactive = inactive;
		if (std) BGstd = std;
		if (clicked) BGclicked = clicked;
		removeErrorMssg();
		setBG();
	}
	this.setValue = function (value,triggerCallback) {
		if (value) {
			currentClickState = 'clicked';
			setBG();
		} else {
			currentClickState = 'unclicked';
			setBG();
		}
		if (callBack && triggerCallback) callBack();
	}
	this.setDimensions = function (Pwidth,Pheight) {
		Width = Pwidth;
		Height = Pheight;
		setDim();
	}
	this.setVisibility = function (value) {
		if (value) currentBox.style.display = 'block'; else currentBox.style.display = 'none';
	}
	this.setActive = function (active) {
		if (active) currentState = 'active';  else currentState = 'inactive';
		setBG();
	}
	
	////// GETTER ////////////////////////////////////////////////////////////////////////////////////////////
	this.getValue = function() {
		if (currentClickState == 'clicked') {
			return true;
		} else if (currentClickState == 'unclicked') {
			return false;
		}
	}
	
	////// HANDLER ///////////////////////////////////////////////////////////////////////////////////////////
	var clickHandler = function (event) {
		if (currentState == 'active') {
			if (currentClickState == 'unclicked') {
				currentClickState = 'clicked';
			} else if (currentClickState == 'clicked') {
				currentClickState = 'unclicked';
			}
			setBG();
			if (callBack) callBack(__self);
		}
	}
	
	__const();
}

////////////////////////////////////////////////////////////////////////////////////// CSlider //////////////////////////////////////////////////////////////////////////////////////

 function CSlider(PparentId,ParrValues) {
	var objectId = parseInt(Math.random() * 100000);
	var parentId = PparentId;
	var mouseLockCallback = undefined;
	var mouseUpCallback = undefined;
	var mouseCurrentCallback = undefined;
	var slidewayWidth = 250;
	var scrollerWidth = 25;
	var slidewayHeight = 20;
	var scrollerHeight = 20;
	var slideDirection = 'HOR';
	var refSizeSW = 0;
	var refSizeSC = 0;
	var desc = undefined;
	var arrValues = ParrValues;
	var arrValuesCalc = undefined;
	var stepLocking = true;
	
	var scrollerBGinactive = undefined;
	var slidewayBG = undefined;
	var scrollerBG = undefined;
	
	var scroller = undefined;
	var slideway = undefined;
	var parentBox = undefined;
	var localNotifier = undefined;
	var __self = this;

	var chosenIndex = undefined;
	var startPos = undefined;
	var mouseOffset = undefined;
	var currentDragObj = undefined;
	var stepPadding = 1;
	var scrollerStart = undefined;
	
	var overflowMode = false;
	
	var __const = function () {
		if (parentId != '' && arrValues && arrValues.length > 0 && document.getElementById(parentId) && addEvent) {
			parentBox = document.getElementById(parentId);
			if (!parentBox) return;
			
			if (arrValues.length <= 1) {
				showErrorMssg('at least i need one element to feel comfortable!'); return;
			}
			renderElements();
			
			addEvent(document,'mousemove',documentMouseMoveHandler);
			addEvent(document,'mouseup',createDocumentMouseUpHandler(objectId));

			calcReferenceValues();
			calcNuArray();
			calcStepPadding();
			calcStartPos();
		}
	}
	var renderElements = function () {
		if (!parentBox) return;
	
		scroller = document.createElement('div');
		slideway = document.createElement('div');
		
		slideway.appendChild(scroller);
		parentBox.appendChild(slideway);
		
		scroller.style.width = scrollerWidth;
		slideway.style.width = slidewayWidth;
		scroller.style.height = scrollerHeight;
		slideway.style.height = scrollerHeight;
		slideway.style.overflow = 'hidden';
		scroller.style.position = 'relative';

		scroller.style.backgroundColor = '#ff0000';
		slideway.style.backgroundColor = '#aaaaaa';
		processBG();
		
		//addEvent(scroller,'mousedown',scrollerMouseDownHandler);
		scroller.onmousedown = scrollerMouseDownHandler;
		//addEvent(scroller,'mousedown',scrollerMouseDownHandler);
		addEvent(slideway,'mousedown',slidewayMouseDownHandler);
	}
	var calcStartPos = function () {
		if (slideDirection == 'HOR')
			startPos = returnAbsoluteLeft(slideway);
		else if (slideDirection == 'VERT')
			startPos = returnAbsoluteTop(slideway);
	}
	var calcReferenceValues = function () {
		if (slideDirection == 'HOR') {
			refSizeSW = slidewayWidth; 
			refSizeSC = (overflowMode ? scrollerHeight : scrollerWidth);
		} else if (slideDirection == 'VERT') { 
			refSizeSW = slidewayHeight;
			refSizeSC = (overflowMode ? scrollerWidth : scrollerHeight);
		}
	}
	var calcNuArray = function () {
		var nuArr = Array();
		if (arrValues.length > 0) {
			nuArr[0] = new Object();
			nuArr[0]['value'] = 0;
			nuArr[0]['pos'] = 0;
			for (var i = 0; i < arrValues.length; i++) {
				nuArr[i+1] = new Object();
				nuArr[i+1]['value'] = arrValues[i];
				if (i == arrValues.length-1) {
					nuArr[i+1]['pos'] = (refSizeSW - refSizeSC);
				} else {
					nuArr[i+1]['pos'] = parseInt(((refSizeSW - refSizeSC) / arrValues.length))*(i+1);
				}
			}
			arrValuesCalc = nuArr;
		} else return undefined;
	}
	var calcStepPadding = function () {
		stepPadding = parseInt((1/3) * ((refSizeSW-refSizeSC) / arrValuesCalc.length));
	}
	var calcDimensions = function () {
		if (slideway) {
			slideway.style.width = slidewayWidth;
			slideway.style.height = slidewayHeight;
		}
		if (scroller) {
			scroller.style.width = scrollerWidth;
			scroller.style.height = scrollerHeight;
		}
	}
	var returnIndexByValue = function (val) {
		for (var i = 0; i < arrValuesCalc.length; i++) {
			if (arrValuesCalc[i]['value'] == val) {
				return i;
			}
		}
		return false;
	}
	var returnIndexByPos = function (val) {
		for (var i = 0; i < arrValuesCalc.length; i++) {
			if (arrValuesCalc[i]['pos'] == val) {
				return i;
			}
		}
		return false;
	}
	var returnAbsoluteLeft = function (obj) {
		var gesamtL = 0;
		if (obj) {
			gesamtL = obj.offsetLeft;
			if (obj.offsetParent) {
				var e = obj.offsetParent;
				while (e) {
					gesamtL = gesamtL + e.offsetLeft;
					e = e.offsetParent;
				}
			}
		}
		return gesamtL;
	}
	var returnAbsoluteTop = function (obj) {
		var gesamtL = 0;
		if (obj) {
			gesamtL = obj.offsetTop;
			if (obj.offsetParent) {
				var e = obj.offsetParent;
				while (e) {
					gesamtL = gesamtL + e.offsetTop;
					e = e.offsetParent;
				}
			}
		}
		return gesamtL;
	}
	var control = function (clientPos) {
		var currentPos = clientPos - mouseOffset - startPos;
		if (currentPos <= 0) return 0;
		if (currentPos >= (refSizeSW-refSizeSC)) return (refSizeSW-refSizeSC);
		for (var i = 0; i < arrValuesCalc.length; i++) {
			if (currentPos >= (arrValuesCalc[i]['pos']-stepPadding) && currentPos <= (arrValuesCalc[i]['pos']+stepPadding)) {
				return arrValuesCalc[i]['pos'];
			}
		}
		return -1;
	}
	var processBG = function () {
		if (!slideway) return;
		if (slidewayBG) slideway.style.background = 'url(' + slidewayBG + ')';
		slideway.style.backgroundPosition = 'center center';
		slideway.style.backgroundRepeat = 'no-repeat';
		
		if (!scroller) return;
		if (scrollerBG) {
			scroller.style.background = 'url(' + scrollerBG + ')';
			if (!chosenIndex && scrollerBGinactive) scroller.style.background = 'url(' + scrollerBGinactive + ')';
		} else if (scrollerBGinactive) {
			scroller.style.background = 'url(' + scrollerBGinactive + ')';
		}
		scroller.style.backgroundPosition = 'center center';
		scroller.style.backgroundRepeat = 'no-repeat';
	}
	var calcX = function () {
		if (!stepLocking) return;
		if (chosenIndex) scroller.style.left = arrValuesCalc[chosenIndex]['pos']; else scroller.style.left = 0;
	}
	var calcY = function () {
		if (!stepLocking) return;
		if (chosenIndex) scroller.style.top = arrValuesCalc[chosenIndex]['pos']; else scroller.style.top = 0;
	}
	var showErrorMssg = function (msg) {
		if (!parentBox) return;
		while (parentBox.childNodes[0]) {
			parentBox.removeChild(parentBox.childNodes[0]);
		}
		parentBox.innerHTML = msg;
	}
	var slideInPos = function (endSlide) {
		endSlide = parseInt(endSlide);
		var slideT = 1;
		var step;
		var startSlide = 0;
		if (slideDirection == 'HOR') {
			startSlide = returnAbsoluteLeft(scroller) - startPos;
		} else if (slideDirection == 'VERT') {
			startSlide = returnAbsoluteTop(scroller) - startPos;
		}
		step = 4;
		var currPos = startSlide;
		var handle = window.setInterval(
							function () {
								if (endSlide > startSlide) {
									if ((currPos + step) > endSlide) {
										currPos = endSlide;
									} else {
										currPos = currPos + step;
									}
								} else {
									if ((currPos - step) < endSlide) {
										currPos = endSlide;
									} else {
										currPos = currPos - step;
									}
								}
								
								if (slideDirection == 'HOR') scroller.style.left = currPos; else scroller.style.top = currPos;
								if (mouseCurrentCallback) mouseCurrentCallback(__self);
								if (Math.abs(endSlide-currPos) <= 1) window.clearInterval(handle);
							},
							slideT);
	}
	var returnCurrentScrollAmount = function() {
		var y = (typeof(document.body.scrollTop)=='number') ? document.body.scrollTop : window.pageYOffset;
		var x = (typeof(document.body.scrollLeft)=='number') ? document.body.scrollLeft : window.pageXOffset;
		return [x,y];
	}
	////// SETTER  ////////////////////////////////////////////////////////////////////////////////////////////
	this.setOverflowMode = function (Pvalue) {
		overflowMode = Pvalue;
	}
	this.setSlidewayBG = function (Pvalue) {
		slidewayBG = Pvalue;
		processBG();
	}
	this.setScrollerBGinactive = function(Pvalue) {
		scrollerBGinactive = Pvalue;
		processBG();
	}
	this.setScrollerBG = function(Pvalue) {
		scrollerBG = Pvalue;
		processBG();
	}
	this.setValues = function (ParrValues) {
		arrValues = ParrValues;
		calcNuArray();
	}
	this.setSlidewayWidth = function (Pvalue) {
		slidewayWidth = Pvalue;
		calcDimensions();
		calcNuArray();
		calcStepPadding();
	}
	this.setSlidewayHeight = function (Pvalue) {
		slidewayHeight = Pvalue;
		calcDimensions();
		calcNuArray();
		calcStepPadding();
	}
	this.setScrollerWidth = function (Pvalue) {
		scrollerWidth = Pvalue;
		calcDimensions();
		calcStepPadding();
	}
	this.setScrollerHeight = function (Pvalue) {
		scrollerHeight = Pvalue;
		calcDimensions();
		calcStepPadding();
	}
	this.setActive = function (Pvalue,PslideInPos) {
		if (!PslideInPos) PslideInPos = false;
		var id = returnIndexByValue(Pvalue);
		if (id)  chosenIndex = id; else  chosenIndex = undefined;
		if (!PslideInPos) {
			if (slideDirection == 'HOR') calcX(); else if (slideDirection == 'VERT') calcY();
		} else {
			slideInPos(arrValuesCalc[chosenIndex]['pos']);
		}
		if (mouseCurrentCallback) mouseCurrentCallback(__self);
	}
	this.setActivePercent = function (Pvalue,PslideInPos) { //only makes sense when steplocking ist disabled!
		if (stepLocking) return;
		if (!PslideInPos) PslideInPos = false;
		if (Pvalue >= 0 && Pvalue <= 1) {
			var pos = (1-Pvalue) * (refSizeSW-refSizeSC);
			if (!PslideInPos) {
				if (slideDirection == 'HOR') {
					scroller.style.left = pos;
				} else if (slideDirection = 'VERT') {
					scroller.style.top = pos;
				}
			} else {
				slideInPos(pos);
			}
		}
		if (mouseCurrentCallback) mouseCurrentCallback(__self);
	}
	this.setMouseUpCallback = function (Pvalue) {
		mouseUpCallback = Pvalue;
	}
	this.setMouseLockCallback = function (Pvalue) {
		mouseLockCallback = Pvalue;
	}
	this.setMouseCurrentCallback = function (Pvalue) { //fired with every move of the slider! think about that....
		mouseCurrentCallback = Pvalue;
	}
	this.setNotifier = function (PNotifier,Pdesc) {
		localNotifier = PNotifier;
		desc = Pdesc;
		localNotifier.addText(scroller,desc);
	}
	this.setSlideDirection = function (dir) {
		if (dir == 'HOR' || dir == 'VERT') {
			slideDirection = dir;
			calcReferenceValues();
			calcStartPos();
			calcNuArray();
			calcStepPadding();
		}
	}
	this.setStepLocking = function (val) {
		//no more locking to steps. BTW it wouldnt make sense to check slider.getValue() when steplocking is false. use slider.getValuePercent() instead!
		//besides that, no more steplocking events are fired!
		if (val) stepLocking = true; else stepLocking = false;
	}
	////// GETTER  ////////////////////////////////////////////////////////////////////////////////////////////
	this.getValue = function() {
		if (chosenIndex) return arrValuesCalc[chosenIndex]['value']; else return 0;
	}
	this.getValuePercent = function() {
		var retVal;
		if (chosenIndex) {
			retVal = Math.round((arrValuesCalc[chosenIndex]['pos'] / (refSizeSW-refSizeSC))*100)/100;
		} else {
			var pos = 0;
			if (slideDirection == 'HOR') {
				pos = returnAbsoluteLeft(scroller) - startPos;
			} else if (slideDirection == 'VERT') {
				pos = returnAbsoluteTop(scroller) - startPos;
			}
			retVal = pos / (refSizeSW-refSizeSC);
		}
		return Math.round(((1-retVal)*100))/100;
	}
	this.getObjectId = function () {
		return objectId;
	}
	
	////// HANDLER  ///////////////////////////////////////////////////////////////////////////////////////////
	var scrollerMouseDownHandler = function (ev) {
		ev = (ev ? ev : window.event);
		if (ev.stopPropagation) ev.stopPropagation(); else ev.cancelBubble = true;
		
		calcStartPos();
		
		var tmp = 0;
		if (slideDirection == 'HOR') {
			tmp = returnAbsoluteLeft(scroller);
			mouseOffset = ev.clientX - tmp;
		} else if (slideDirection == 'VERT') {
			tmp = returnAbsoluteTop(scroller);
			mouseOffset = ev.clientY - tmp;
		}
		currentDragObj = scroller;
		return false;
	}
	var slidewayMouseDownHandler = function (ev) {
		if (stepLocking) return;
		
		calcStartPos();
		var refPos = 0;
		if (slideDirection == 'HOR') { refPos = ev.clientX; } else { refPos = ev.clientY; }
		
		var scrollAmount = returnCurrentScrollAmount();
		
		var pos = refPos - startPos - refSizeSC / 2;
		if (slideDirection == 'HOR') {
			pos = pos + scrollAmount[0];
		} else {
			pos = pos + scrollAmount[1];
		}
		
		if (pos < 0) pos = 0;
		if (pos > (refSizeSW - refSizeSC)) pos = refSizeSW - refSizeSC;
		if (slideDirection == 'HOR') {
			scroller.style.left = pos + 'px';
		} else {
			scroller.style.top = pos + 'px';
		}
		if (mouseCurrentCallback) mouseCurrentCallback(__self);
		if (mouseUpCallback) mouseUpCallback(__self);
	}
	var documentMouseMoveHandler = function (ev) {
		if (currentDragObj) {
			if (!ev) ev = window.event;
			var setValue = 0;
			var relevantPos = 0;
			if (slideDirection == 'HOR') {
				relevantPos = ev.clientX;
			} else if (slideDirection == 'VERT') {
				relevantPos = ev.clientY;
			}
			if (stepLocking) {
				var currentPos = control(relevantPos);
				if (currentPos == -1) {
					setValue = relevantPos - mouseOffset - startPos;
				} else if (currentPos >= 0) {
					chosenIndex = returnIndexByPos(currentPos);
					if (mouseLockCallback) mouseLockCallback(__self);
					setValue = currentPos;
					processBG();
				}
			} else {
				var realPos = relevantPos - mouseOffset - startPos;
				if ((realPos) <= 0)
					setValue = 0;
				else if (realPos >= refSizeSW-refSizeSC) 
					setValue = refSizeSW-refSizeSC;
				else
					setValue = relevantPos - mouseOffset - startPos;
			}
			if (slideDirection == 'HOR') {
				currentDragObj.style.left = setValue;
			} else if (slideDirection == 'VERT') {
				currentDragObj.style.top = setValue;
			}
			if (mouseCurrentCallback) mouseCurrentCallback(__self);
		}
	}
	var createDocumentMouseUpHandler = function (id) {
		return function(ev) {
			documentMouseUpHandler(ev,id);
		}
	}
	var documentMouseUpHandler = function (ev,id) {
		if (currentDragObj) {
			currentDragObj = undefined;
			if (slideDirection == 'HOR') calcX(); else if (slideDirection == 'VERT') calcY();
			if (mouseUpCallback) mouseUpCallback(__self);
		}
	}

	__const();
 }
  
////////////////////////////////////////////////////////////////////////////////////// CTooltip //////////////////////////////////////////////////////////////////////////////////////

 function CTooltip() {
	var box = undefined;
	var texts = new Array();
	var inside = false;
	var initialOffset = 20;
	var timeOutHandler = undefined;
	var cssClass = undefined;
	
	var lastX = 0;
	var lastY = 0;
	
	var switched = false;
	
	var __self = this;
	
	var __const = function() {
		if (!addEvent) return;
	
		box = document.createElement('div');
		box.style.position = 'absolute';
		box.style.display = 'none';
		box.innerHTML = '1';
		document.getElementsByTagName('body')[0].appendChild(box);
		
		addEvent(document,'mousemove',documentMouseMoveHandler);
	}
	
	this.addText = function(param,desc,click,hand) {
		var bindObject = document.getElementById(param);
		bindObject = (typeof param == 'string' ? document.getElementById(param) : (typeof param == 'object' ? param : '') );
		if (!bindObject) return;
		
		var nuId = texts.length;
		bindObject.toolTipId = nuId;
		try { if (hand) bindObject.style.cursor = 'pointer'; } catch (e) {}
		texts[nuId] = new Object();
		texts[nuId]['bindObject'] = bindObject;
		texts[nuId]['text'] = desc;
		
		addEvent(bindObject,'mouseover',createHandlerOver(nuId));
		addEvent(bindObject,'mouseout',handlerOut);
		if (click)
			addEvent(bindObject,'click',createHandlerClick(nuId));
		else 
			addEvent(bindObject,'click',handlerOut);
	}
	var showTT = function(id) {
		switched = false;
		box.style.width = '';
		if (id >= 0) box.innerHTML = texts[id]['text'];
		inside = true;
		var vp = returnViewport();
		var scr = returnCurrentScrollAmount();
		box.style.display = 'block';
		if (box.offsetWidth > 250) box.style.width = '250px';
		box.style.left = lastX + scr[0] + initialOffset;
		box.style.top = lastY + scr[1] + initialOffset;
		if ((lastY + box.offsetHeight) > vp[1]) {
			box.style.top = lastY + scr[1] - box.offsetHeight;
			switched = true;
		}
	}
	var returnCurrentScrollAmount = function() {
		var y = (typeof(document.body.scrollTop)=='number') ? document.body.scrollTop : window.pageYOffset;
		var x = (typeof(document.body.scrollLeft)=='number') ? document.body.scrollLeft : window.pageXOffset;
		return [x,y];
	}
	var returnViewport = function() {
		var vpW = 0;
		var vpH = 0;
		if (window.innerWidth) {
			vpW = window.innerWidth;
			vpH = window.innerHeight;
		} else if (typeof document.documentElement != 'undefined' && typeof document.documentElement.clientWidth != 'undefined' && document.documentElement.clientWidth != 0) {
			vpW = document.documentElement.clientWidth;
			vpH = document.documentElement.clientHeight;
		} else {
			vpW = document.getElementsByTagName('body')[0].clientWidth;
			vpH = document.getElementsByTagName('body')[0].clientHeight;
		}
		return [vpW,vpH];
	}
	////// HANDLER ////////////////////////////////////////////////////////////////////////////////////////////
	var documentMouseMoveHandler = function(ev) {
		if (inside) {
			if (!ev) ev = window.event;
			var scr = returnCurrentScrollAmount();
			box.style.left = ev.clientX + scr[0] + initialOffset;
			if (!switched) box.style.top = ev.clientY + scr[1] + initialOffset; else box.style.top = ev.clientY + scr[1] - box.offsetHeight;
		}
		lastX = ev.clientX;
		lastY = ev.clientY;
	}
	var handlerOut = function() {
		window.clearTimeout(timeOutHandler);
		inside = false;
		box.style.display = 'none';
	}
	var createHandlerClick = function(param) {
		return function(ev) {
			handlerClick(ev,param);
		}
	}
	var handlerClick = function(ev,id) {
		window.clearTimeout(timeOutHandler);
		if (id >= 0) showTT(id);
	}
	var createHandlerOver = function(param) {
		return function(ev) {
			handlerOver(ev,param);
		};
	}
	var handlerOver = function(ev,id) {
		if (id >= 0) timeOutHandler = window.setTimeout(function() {showTT(id); },200);
	}
	////// SETTER  ////////////////////////////////////////////////////////////////////////////////////////////
	this.setCSSClass = function (val) {
		if (!val || !box) return;
		cssClass = val;
		box.className = cssClass;
	}
	this.setOffset = function(val) {
		if (val <= 0) return;
		initialOffset = val;
	}
	this.hideTT = function() {
		handlerOut();
	}
	
	__const();
 }
 
 ////////////////////////////////////////////////////////////////////////////////////// CButton //////////////////////////////////////////////////////////////////////////////////////

 function CButton(PparentID,Phand) {
	var box = undefined;
	var parentBox = undefined;
	var parentID = PparentID
	var callback = undefined;
	var xDim = undefined;
	var yDim = undefined;
	var bgStd = undefined;
	var bgClicked = undefined;
	var status = 'std';
	var hand = Phand;
	var localNotifier;
	var desc;
	
	var __const = function() {
		parentBox = document.getElementById(parentID);
		if (!parentBox && !addEvent) return;
	
		box = document.createElement('div');
		box.backgroundColor = '#ff0000';
		
		addEvent(box,'mousedown',handlerMouseDown);
		addEvent(box,'mouseup',handlerMouseUp);
		addEvent(box,'mouseout',handlerMouseOut);
		
		try { if (hand) box.style.cursor = 'pointer'; } catch (e) {}
		parentBox.appendChild(box);
	}
	var handlerMouseDown = function(ev) {
		status = 'clicked';
		calcBG();
	}
	var handlerMouseUp = function(ev) {
		status = 'std'
		calcBG();
		if (callback) callback(this);
	}
	var handlerMouseOut = function(ev) {
		if (status == 'clicked') status = 'std';
		calcBG();
	}
	var calcBG = function() {
		if (status == 'std') box.style.backgroundImage = 'url(' + bgStd + ')'; else box.style.backgroundImage = 'url(' + bgClicked + ')';
	}
	var calcDim = function() {
		box.style.width = xDim;
		box.style.height = yDim;
	}

	////// SETTER  ////////////////////////////////////////////////////////////////////////////////////////////
	this.setCallback = function(Pcb) {
		callback = Pcb;
	}
	this.setDimensions = function(Px,Py) {
		xDim = Px;
		yDim = Py;
		calcDim();
	}
	this.setBG = function(Pstd,Pclicked) {
		bgStd = Pstd;
		bgClicked = Pclicked;
		calcBG();
	}
	this.setNotifier = function(PNotifier,Pdesc) {
		localNotifier = PNotifier;
		desc = Pdesc;
		localNotifier.addText(box,desc);
	}
	__const();
 }

////////////////////////////////////////////////////////////////////////////////////// CHover //////////////////////////////////////////////////////////////////////////////////////
 
 function CHover() {
	var pictures = Array();
	var callbacks = Array();

	var __const = function () { }
 
	this.addImg = function(id,stdPic,hoverPic) {
		if (!addEvent) return;
		var nuId = pictures.length;
		var bindObject = document.getElementById(id);
		bindObject = (typeof id == 'string' ? document.getElementById(id) : (typeof id == 'object' ? id : '') );
		if (!bindObject) return;
		
		pictures[nuId] = new Object();
		pictures[nuId]['obj'] = bindObject;
		pictures[nuId]['std'] = stdPic;
		pictures[nuId]['hover'] = hoverPic;
		
		addEvent(bindObject,'mouseover',createOverHandler(nuId,'IMG'));
		addEvent(bindObject,'mouseout',createOutHandler(nuId,'IMG'));
	}
	
	this.addCB = function(id,Pvalue,PcallbackOver,PcallbackOut) {
		if (!addEvent) return;
		var nuId = callbacks.length;
		var bindObject = document.getElementById(id);
		bindObject = (typeof id == 'string' ? document.getElementById(id) : (typeof id == 'object' ? id : '') );
		if (!bindObject) return;
		
		callbacks[nuId] = new Object();
		callbacks[nuId]['obj'] = bindObject;
		callbacks[nuId]['cbOver'] = PcallbackOver;
		callbacks[nuId]['cbOut'] = PcallbackOut;
		callbacks[nuId]['value'] = Pvalue;
		
		addEvent(bindObject,'mouseover',createOverHandler(nuId,'CB'));
		addEvent(bindObject,'mouseout',createOutHandler(nuId,'CB'));
		addEvent(bindObject,'click',createOutHandler(nuId,'CB'));
	}
 
	////// HANDLER  ////////////////////////////////////////////////////////////////////////////////////////////
	var createOverHandler = function(param,kind) {
		return function () {
			overHandler(param,kind);
		}
	}
	var overHandler = function(id,kind) {
		if (id < 0) return;
		if (kind == 'IMG') pictures[id]['obj'].src = pictures[id]['hover'];
		if (kind == 'CB' && callbacks[id]['cbOver']) callbacks[id]['cbOver'](callbacks[id]['value']);
	}
	var createOutHandler = function(param,kind) {
		return function () {
			outHandler(param,kind);
		}
	}
	var outHandler = function(id,kind) {
		if (id < 0) return;
		if (kind == 'IMG')	pictures[id]['obj'].src = pictures[id]['std'];
		if (kind == 'CB' && callbacks[id]['cbOut']) callbacks[id]['cbOut'](callbacks[id]['value']);
	}
	__const();
 }
 
 ////////////////////////////////////////////////////////////////////////////////////// CContext //////////////////////////////////////////////////////////////////////////////////////
 
 function CContext(PCssClass) {
	var box = undefined;
	var texts = new Array();
	var inside = false;
	var initialOffset = 20;
	var cssClass = PCssClass;
	
	var opened = false;
	var aktOpen;
	
	var __self = this;
	
	var __const = function() {
		if (!addEvent) return;
	
		box = document.createElement('div');
		box.style.position = 'absolute';
		box.style.display = 'none';
		box.innerHTML = '1';
		if (cssClass) box.className = cssClass;
		document.getElementsByTagName('body')[0].appendChild(box);
		
		addEvent(document,'click',handlerDocumentClick);
	}
	
	this.addText = function(param,desc) {
		var bindObject = document.getElementById(param);
		bindObject = (typeof param == 'string' ? document.getElementById(param) : (typeof param == 'object' ? param : '') );
		if (!bindObject) return;
		
		var nuId = texts.length;
		texts[nuId] = new Object();
		texts[nuId]['bindObject'] = bindObject;
		texts[nuId]['text'] = desc;
		
		try { bindObject.style.cursor = 'pointer'; } catch(e) {}

		addEvent(bindObject,'click',createHandlerClick(nuId));
	}
	var showContext = function(id) {
		aktOpen = id;
		box.innerHTML = texts[id]['text'];
		box.style.display = 'block';
		opened = true;
		
		var pos = FindXYWH(texts[id]['bindObject']);
		var pos2 = FindXYWH(box);
		var scr = returnCurrentScrollAmount();
		var vp = returnViewport();
		
		if (pos.y + pos.h + pos2.h > vp[1]) {
			box.style.top = pos.y - pos2.h + scr[1];
		} else {
			box.style.top = pos.y + scr[1] + pos.h;
		}
		box.style.left = pos.x + scr[0];
	}
	var closeContext = function() {
		opened = false;
		aktOpen = null;
		box.style.display = 'none';
	}
	var returnCurrentScrollAmount = function() {
		var y = (typeof(document.body.scrollTop)=='number') ? document.body.scrollTop : window.pageYOffset;
		var x = (typeof(document.body.scrollLeft)=='number') ? document.body.scrollLeft : window.pageXOffset;
		return [x,y];
	}
	var returnViewport = function() {
		var vpW = 0;
		var vpH = 0;
		if (window.innerWidth) {
			vpW = window.innerWidth;
			vpH = window.innerHeight;
		} else if (typeof document.documentElement != 'undefined' && typeof document.documentElement.clientWidth != 'undefined' && document.documentElement.clientWidth != 0) {
			vpW = document.documentElement.clientWidth;
			vpH = document.documentElement.clientHeight;
		} else {
			vpW = document.getElementsByTagName('body')[0].clientWidth;
			vpH = document.getElementsByTagName('body')[0].clientHeight;
		}
		return [vpW,vpH];
	}

	////// HANDLER ////////////////////////////////////////////////////////////////////////////////////////////
	var createHandlerClick = function(param) {
		return function(ev) { handlerClick(ev,param); }
	}
	var handlerClick = function(ev,id) {
		if (id == aktOpen) {
			closeContext();
		} else {
			ev.cancelBubble = true;
			if (id >= 0) showContext(id);
		}
	}
	var handlerDocumentClick = function() { closeContext(); }
	
	////// SETTER  ////////////////////////////////////////////////////////////////////////////////////////////
	this.setCSSClass = function (val) {
		if (!val || !box) return;
		cssClass = val;
		box.className = cssClass;
	}
	this.setOffset = function(val) {
		if (val <= 0) return;
		initialOffset = val;
	}
	
	__const();
 }