/*
// addrow: cellen noch leeren



*/
function renderTable(P) {
	if (!P.rootID) 		alert("renderTable: no rootID, can't go on")
	else 				this.rootID = P.rootID
	this.table = document.getElementById(this.rootID)
	// alert("renderTable: " + this.rootID);
}

// R O W S
renderTable.prototype.addRow = function(pos) {
	// alert("add");return;
	r 			= this.table.rows[pos]
	// alert(pos)
	// alert(r.innerHTML)
	clonedRow 	= r.cloneNode(true)
	for(var i=0;i<clonedRow.cells.length;i++) {clonedRow.cells[i].firstChild.value='';} // leeen
	var nS 		= this.table.rows[pos].nextSibling
	if (nS) 	r.parentNode.insertBefore(clonedRow,nS)
	else 		r.parentNode.appendChild(clonedRow)
	this.resetNumbers();
}

renderTable.prototype.deleteRow = function(pos) {
	if (!this.table.rows[2]) {alert('Sorry, can\'t delete the last row'); return;}
	r 		= this.table.rows[pos]
	pN 		= r.parentNode
	pN.removeChild(r)
	this.resetNumbers();
}

renderTable.prototype.moveRowUp = function(pos) {
	r 		= this.table.rows[pos]
	if (pos-1<0) {alert('Can\'t move up. It\'s the first row.'); return}
	newposNode =  this.table.rows[pos-1]
	r.parentNode.insertBefore(r,newposNode)
	this.resetNumbers();
}

renderTable.prototype.moveRowDown = function(pos) {
	r 		= this.table.rows[pos]
	var numRows = this.table.rows.length
	if (pos+2 == numRows) {alert('Can\'t move down. It\'s the last row.'); return}
	newposNode =  this.table.rows[pos+2]
	r.parentNode.insertBefore(r,newposNode)
	this.resetNumbers();
}



// C O L S 
renderTable.prototype.addCol = function(pos) {
	// alert("addcol " + pos)
	var numRows = this.table.rows.length
	var numCols = this.table.rows[0].cells.length
	for (var i=0; i<numRows; i++) {
		var cell 	= this.table.rows[i].cells[pos]
		clonedCell 	= cell.cloneNode(true)
		clonedCell.firstChild.value='' // leeen
		var nS 		= cell.nextSibling
		if (nS) 	cell.parentNode.insertBefore(clonedCell,nS)
		else 		cell.parentNode.appendChild(clonedCell)
	}
	this.resetNumbers();
}

renderTable.prototype.deleteCol = function(pos) {
	var numRows = this.table.rows.length
	var numCols = this.table.rows[0].cells.length
	if (numCols==2) {alert('Sorry, can\'t delete the last col'); return;} // 2 wegen der 1. Spalte fuer die Buttons
	for (var i=0; i<numRows; i++) {
		var cell 	= this.table.rows[i].cells[pos]
		cell.parentNode.removeChild(cell)
	}
	this.resetNumbers();
}

renderTable.prototype.moveColRight = function(pos) {
	// alert("moveColRight pos " +pos)
	var numRows = this.table.rows.length
	var numCols = this.table.rows[0].cells.length
	// alert("moveColRight pos+1 " +(pos) + " numCols: "+numCols)
	if (pos+1==numCols) {alert('Can\'t move right. It\'s the right col.'); return}
	for (var i=0; i<numRows; i++) {
		var cell 	= this.table.rows[i].cells[pos]
		newposNode 	= cell.nextSibling.nextSibling
		if (newposNode) cell.parentNode.insertBefore(cell,newposNode)
		else  			cell.parentNode.appendChild(cell)
	}
	this.resetNumbers();
}

renderTable.prototype.moveColLeft = function(pos) {
	// alert("moveColLeft pos: " + pos)
	var numRows = this.table.rows.length
	var numCols = this.table.rows[0].cells.length
	if (pos<2) {alert('Can\'t move left. It\'s the left col.'); return}
	for (var i=0; i<numRows; i++) {
		var cell 	= this.table.rows[i].cells[pos]
		newposNode 	= cell.previousSibling
		if (newposNode) cell.parentNode.insertBefore(cell,newposNode)
	}
	this.resetNumbers();
}

renderTable.prototype.resetNumbers = function() {
	var numRows = this.table.rows.length
	var numCols = this.table.rows[0].cells.length
	for(var i=0; i<numRows; i++) {
		var _i = i
		for (var ii=1; ii<numCols;ii++) {
			//report("i: " + _i + " ii: " + ii + "\n")
			try {
				var td = this.table.rows[_i].cells[ii];
				if (td) {
					var textarea = td.firstChild
					var textareaName = textarea.getAttribute('name')
					//report("textareaName: " + textareaName + "\n")
					textareaNameArr = textareaName.split('######')
					newName = ('a' + i +'######c'+ ii + '######'+textareaNameArr[2])
					// report("newName: " + newName + "\n")
					textarea.setAttribute('name',newName)
				}
			} catch (err_MSXML2) {}
		}
	}
}






























function resizerObj(P) {
/* I N F O 
	BorderWidth:		muss mit der im CSS definierten borderWidth uebereinstimmen
	

*/
	if (!window.resizerObjCounter) window.resizerObjCounter = 0;
	this.i = ++window.resizerObjCounter
	
	// alert("i " + i)
	P.top				? 	this.top 		 = 'top:'		+P.top 			+'px;'	: 	this.top 			= '';
	P.left				? 	this.left 		 = 'top:'		+P.top 			+'px;'	: 	this.left 			= '';
	P.width				? 	this.width 		 = 'width:'		+P.width 		+'px;'	: 	this.width 			= '';
	P.height			? 	this.height	 	 = 'height:'	+P.height 		+'px;'	: 	this.height 		= '';
	P.borderWidth		? 	this.borderWidth = 'height:'	+P.borderWidth 	+'px;'	: 	this.borderWidth 	= '1'; // Default: 1px border
	P.frameclass		? 	this.frameclass  = P.frameclass 	: 	this.frameclass 	= 'resize_frame';
	P.handleclass		? 	this.handleclass = P.handleclass 	: 	this.handleclass 	= 'resize_handle';
	P.display			? 	this.display = P.display 			: 	this.display 		= 'block';
	sideHandleDisplayStyle = 'display:block;';
	
	// Holder element (enthaelt frame + handles
	this.resizerElHolder 				= document.createElement('div')
	this.resizerElHolder.style.cssText 	= 'position:absolute; left:0; top:0; width:100px; height:100px;'
	// frame
	html = 			'<div class="'+this.frameclass+'" unselectable="on" id="resizeframe'+this.i+'"></div>'
	// handles
	html += 		'<div class="'+this.handleclass+'" unselectable="on" id="handle'+this.i+'_topLeft"		style="cursor:nw-resize;  	left:0; 		top:0;"		></div>'
	html += 		'<div class="'+this.handleclass+'" unselectable="on" id="handle'+this.i+'_topCenter" 	style="cursor:n-resize;  	left:50px; 		top:0; 		'+sideHandleDisplayStyle+';"></div>'
	html += 		'<div class="'+this.handleclass+'" unselectable="on" id="handle'+this.i+'_topRight"		style="cursor:ne-resize; 	left:100px; 	top:0; 		"></div>'
	html += 		'<div class="'+this.handleclass+'" unselectable="on" id="handle'+this.i+'_middleLeft" 	style="cursor:w-resize;  	left:0; 		top:50px; 	'+sideHandleDisplayStyle+'"></div>'
	html += 		'<div class="'+this.handleclass+'" unselectable="on" id="handle'+this.i+'_middleRight" 	style="cursor:w-resize;  	left:100px; 	top:50px; 	'+sideHandleDisplayStyle+'"></div>'
	html += 		'<div class="'+this.handleclass+'" unselectable="on" id="handle'+this.i+'_bottomLeft"  	style="cursor:ne-resize; 	left:0; 		top:100px; 	"></div>'
	html += 		'<div class="'+this.handleclass+'" unselectable="on" id="handle'+this.i+'_bottomCenter"  style="cursor:n-resize; 	left:50px; 		top:100px; 	'+sideHandleDisplayStyle+'"></div>'
	html += 		'<div class="'+this.handleclass+'" unselectable="on" id="handle'+this.i+'_bottomRight" 	style="cursor:nw-resize; 	left:100px; 	top:100px;	"></div>'
	this.resizerElHolder.innerHTML = html;
	document.body.appendChild(this.resizerElHolder)
	// alert(this.resizerEl.innerHTML)
	
	this.h_topLeft 			= document.getElementById('handle'+this.i+'_topLeft');				// 8 Griffe
	this.h_topCenter		= document.getElementById('handle'+this.i+'_topCenter');
	this.h_topRight			= document.getElementById('handle'+this.i+'_topRight');
	this.h_middleLeft 		= document.getElementById('handle'+this.i+'_middleLeft');
	this.h_middleRight		= document.getElementById('handle'+this.i+'_middleRight');
	this.h_bottomLeft		= document.getElementById('handle'+this.i+'_bottomLeft');
	this.h_bottomCenter		= document.getElementById('handle'+this.i+'_bottomCenter');
	this.h_bottomRight		= document.getElementById('handle'+this.i+'_bottomRight');
	this.resizerEl 			= document.getElementById('resizeframe'+this.i);					// der Frame
	// this.resizerEl
	this.handleW 			= this.h_topLeft.offsetWidth
	// alert(getCSSStyle(this.resizerEl,'border')) //geht nicht...
	this.setFrame(200,200,200,200)
	
	//alert(this.handleWidth)
	// this.positionHandles(this)
	
	var obj = this // Fuer call
	// 8 Griffe, und der resizeframe
	this.d_topLeft 		= new dragObj({dragEl:'handle'+this.i+'_topLeft',		constrainH:0, constrainV:0, call_drag:	function(){obj.positionHandles(this)}	})
	this.d_topCenter 	= new dragObj({dragEl:'handle'+this.i+'_topCenter', 	constrainH:0, constrainV:1, call_drag:	function(){obj.positionHandles(this)}	})
	this.d_topRight 	= new dragObj({dragEl:'handle'+this.i+'_topRight', 		constrainH:0, constrainV:0, call_drag:	function(){obj.positionHandles(this)}	})
	this.d_middleLeft 	= new dragObj({dragEl:'handle'+this.i+'_middleLeft', 	constrainH:1, constrainV:0, call_drag:	function(){obj.positionHandles(this)}	})
	this.d_middleRight 	= new dragObj({dragEl:'handle'+this.i+'_middleRight', 	constrainH:1, constrainV:0, call_drag:	function(){obj.positionHandles(this)}	})
	this.d_bottomLeft 	= new dragObj({dragEl:'handle'+this.i+'_bottomLeft', 	constrainH:0, constrainV:0, call_drag:	function(){obj.positionHandles(this)}	})
	this.d_bottomCenter = new dragObj({dragEl:'handle'+this.i+'_bottomCenter', 	constrainH:0, constrainV:1, call_drag:	function(){obj.positionHandles(this)}	})
	this.d_bottomRight 	= new dragObj({dragEl:'handle'+this.i+'_bottomRight', 	constrainH:0, constrainV:0, call_drag:	function(){obj.positionHandles(this)}	})
	// frame
	this.d_frame 		= new dragObj({dragEl:'resizeframe'+this.i, 			constrainH:0, constrainV:0, call_drag:	function(){obj.positionHandles(this)}	})
	// report(document.body.innerHTML)
}
resizerObj.prototype.setFrame = function(L,T,W,H) {

		if (L) this.resizerEl.style.left 	= L + 'px'
		if (T) this.resizerEl.style.top 	= T + 'px'
		if (W) this.resizerEl.style.width 	= W + 'px'
		if (H) this.resizerEl.style.height 	= H + 'px'
		PL 	= absLeft(this.resizerEl)							// left
		PT 	= absTop(this.resizerEl)							// top
		PR  = absLeft(this.resizerEl) + this.resizerEl.offsetWidth	- this.handleW		// right
		PB  = absTop(this.resizerEl)  + this.resizerEl.offsetHeight	- this.handleW		// bottom
		PC	= PL + ((PR - PL)/2)			// center
		PM  = PT + ((PB - PT)/2)			// middle
		this.h_topLeft.style.left 		= PL + 'px'
		this.h_topLeft.style.top  		= PT + 'px'
		this.h_topCenter.style.left 	= PC + 'px'
		this.h_topCenter.style.top  	= PT + 'px'
		this.h_topRight.style.left 		= PR + 'px'
		this.h_topRight.style.top  		= PT + 'px'
		
		this.h_middleLeft.style.left 	= PL + 'px'
		this.h_middleLeft.style.top  	= PM + 'px'
		this.h_middleRight.style.left 	= PR + 'px'
		this.h_middleRight.style.top  	= PM + 'px'
		
		this.h_bottomLeft.style.left 	= PL + 'px'
		this.h_bottomLeft.style.top  	= PB + 'px'
		this.h_bottomCenter.style.left 	= PC + 'px'
		this.h_bottomCenter.style.top  	= PB + 'px'
		this.h_bottomRight.style.left 	= PR + 'px'
		this.h_bottomRight.style.top  	= PB + 'px'
		
}

resizerObj.prototype.positionHandles = function(obj) {
		// obj ist das Object, das den caller sendet, z. B. das dragObj
		// aktuelle Masse erfassen
		PL 	= absLeft(this.h_topLeft)						// left
		PT 	= absTop(this.h_topLeft)						// top
		PR  = absLeft(this.h_bottomRight)	+ this.handleW // right
		PB  = absTop(this.h_bottomRight)	+ this.handleW // bottom
		var resizeFrameFlag = 0
		// report("\PL: "+ PL + " PT: " + PT + " PR: " + PR + " PB: " + PB, '','400px')
		switch(obj.dragEl) {
			case this.resizerEl:
				this.setFrame();
				resizeFrameFlag = 1
				break
			case this.h_topLeft:
				nL = absLeft(obj.dragEl)
				nT = absTop(obj.dragEl)
				nR = PR
				nB = PB
				break;
			case this.h_topCenter:
				nL = PL
				nT = absTop(obj.dragEl)
				nR = PR
				nB = PB
				break;
			case this.h_topRight:
				nL = PL
				nT = absTop(obj.dragEl)
				nR = absLeft(obj.dragEl) + this.handleW
				nB = PB
				break;
			case this.h_middleLeft:
				nL = absLeft(obj.dragEl)
				nT = PT
				nR = PR
				nB = PB
				break;
			case this.h_middleRight:
				nL = PL
				nT = PT
				nR = absLeft(obj.dragEl) + this.handleW
				nB = PB
				break;
			case this.h_bottomLeft:
				nL = absLeft(obj.dragEl)
				nT = PT
				nR = PR
				nB = absTop(obj.dragEl) + this.handleW
				break;
			case this.h_bottomCenter:
				nL = PL
				nT = PT
				nR = PR
				nB = absTop(obj.dragEl) + this.handleW
				break;
			case this.h_bottomRight:
				nL = PL
				nT = PT
				nR = absLeft(obj.dragEl) + this.handleW
				nB = absTop(obj.dragEl)  + this.handleW
				break;
			
		
		}
		// report("\nL: "+ nL + " nT: " + nT + " nR: " + nR + " nB: " + nB, '','400px') 
		// report("\n nB: " + nB, '','400px') 
		nW = nR - nL
		nH = nB - nT
		
		// report("\nL: "+ nL + " nT: " + nT + " nW: " + nW + " nH: " + nH, '','400px') 
		// obj.dragEl.style.left = 0;
		// obj.dragEl.style.top  = 0;
		
		if (!resizeFrameFlag) {
			this.resizerEl.style.left 	= nL + 'px'
			this.resizerEl.style.top 	= nT + 'px'
			this.resizerEl.style.width 	= (nW - this.borderWidth*2) + 'px'
			this.resizerEl.style.height = (nH - this.borderWidth*2) + 'px'
		}
		this.setFrame()
		/*
		left	= 0
		top 	= 0
		right 	= this.resizerEl.offsetWidth  	- this.handleW
		bottom 	= this.resizerEl.offsetHeight 	- this.handleW
		center  = this.resizerEl.offsetWidth/2  - this.handleW/2
		middle  = this.resizerEl.offsetHeight/2 - this.handleW/2
		*/
		/*alert(
			"left:" 	+ left 		+ "\n" + 
			"top:" 		+ top 		+ "\n" + 
			"right:" 	+ right 	+ "\n" + 
			"bottom:" 	+ bottom 	+ "\n" + 
			"center:" 	+ center 	+ "\n" + 
			"middle:" 	+ middle 	+ "\n" + 
			""
		)*/
		/*
		this.h_topLeft.style.left 		= left
		this.h_topLeft.style.top  		= top
		this.h_topMiddle.style.left 	= center
		this.h_topMiddle.style.top  	= top
		this.h_topRight.style.left 		= right
		this.h_topRight.style.top  		= top
		
		this.h_centerLeft.style.left 	= left
		this.h_centerLeft.style.top  	= middle
		this.h_centerRight.style.left 	= right
		this.h_centerRight.style.top  	= middle
		
		this.h_bottomLeft.style.left 	= left
		this.h_bottomLeft.style.top  	= bottom
		this.h_bottomMiddle.style.left 	= center
		this.h_bottomMiddle.style.top  	= bottom
		this.h_bottomRight.style.left 	= right
		this.h_bottomRight.style.top  	= bottom
		*/
		
		/*
		alert(
				"rootID " 							+ this.rootID	+ "\n" + 
				"absTop(this.rootEl) " 				+ absTop(this.rootEl)	+ "\n" + 
				"obj.posV " 						+ obj.posV 	+ "\n" + 
				"maxHeight " 						+ this.rootEl.offsetHeight 	+ "\n" + 
				"maxWidth " 						+ this.rootEl.offsetWidth 	+ "\n" + 
				"_areaframe.offsetHeight"			+ document.getElementById(this.rootID +'_areaframe').offsetHeight 	+ "\n" + 
				"_height " 							+ _height 					+ "\n" + 
				"_width " 							+ _width 					+ "\n" + 
				"defaultsize " 						+ defaultsize 				+ "\n" + 
				"this.defaultfactor " 				+ this.defaultfactor 			+ "\n" + 
				"this.slidersize " 					+ this.slidersize 			+ "\n" + 
				"this.area1.style.top " 			+ this.area1.style.top 		+ "\n" + 
				"this.area1.style.height " 			+ this.area1.style.height 	+ "\n" + 
				"this.slider.style.top " 			+ this.slider.style.top 	+ "\n" + 
				"this.slider.style.height " 		+ this.slider.style.height 	+ "\n" +
				"this.area2.style.top " 			+ this.area2.style.top 	+ "\n" +  
				"this.area2.style.height" 			+ this.area2.style.height 	+ "\n" + 
				"")
			*/
	
}














function pickerObj(P) {
/* I N F O 
	Es koennen unterschiedliche Style-Eigneschaften gepickt werden:
		Default:		(cssProperty,cssPropertyJS) background-color, backgroundColor

	Wenn der Picker geschlossen wird, ohne set(), dann wird der Ausgangswert wiederhergestellt. (this.startvalue)
	

*/
	if (!window.queryStr) window.queryStr = getQueryStr()
	if (!P.rootID) alert("pickerObj: no rootID, can't go on")
	else this.rootID = P.rootID
	this.saveMode = P['saveMode']
	
	// alert(this.rootID)
	// registerEventListenersObj(document, "mouseup",  this, false, 'refreshArea');
	this.picker 			= document.getElementById(this.rootID)
	this.parentForm 		= findParentElementByNodeName(document.getElementById(this.rootID),'form')
	this.inputField 		= document.getElementById(this.rootID + '_pVal');
	this.cssPropertyJS 		= P.cssPropertyJS
	// alert(this.cssPropertyJS)
	this.pickerLayer 		= document.getElementById(this.rootID + '_pickerlayer')
	this.pickerInnerLayer 	= document.getElementById(this.rootID + '_pickerinnerlayer')
	// Updaten eines anderen Elements, z. B. einem Anzeigefeld
	this.targetFieldID 	= P.targetFieldID
	this.targetField   	= document.getElementById(this.targetFieldID);				// optional
	this.startvalue 	= P.activeValue
}

pickerObj.prototype.hide = function(e,el) {
	e = e ? e : event;
	if (!el.contains(e.relatedTarget || e.toElement)) {
		el.style.display = "none"
	}
	this.picker.style[this.cssPropertyJS] 		= this.startvalue
}
pickerObj.prototype.view = function(val,el) {
	// alert('val ' + val)
	this.picker.style[this.cssPropertyJS] = val
	this.inputField.value 				= val
	if (this.targetField) this.targetField.value= val
	// el.style.border = '1px solid red';
}
pickerObj.prototype.set = function(val) {
	this.pickerLayer.style.display 				= 'none'
	this.picker.style[this.cssPropertyJS] 		= val
	this.inputField.value 						= val
	this.startvalue								= val
	if (this.targetField) this.targetField.value= val
	window.queryStr = modifyQueryString(window.queryStr,0,this.rootID + '_pVal', escape(val))
}

















function tabsObj(P) {
	if (!window.queryStr) window.queryStr = getQueryStr()
	/* I N F O 
	*/
	if (!P.rootID) alert("tabsObj: no rootID, can't go on")
	else this.rootID = P.rootID
	// alert(this.rootID)
	// registerEventListenersObj(document, "mouseup",  this, false, 'refreshArea');
	this.rootEl 		= document.getElementById(this.rootID)
	this.parentForm 	= findParentElementByNodeName(document.getElementById(this.rootID),'form')
	this.inputField 	= document.getElementById(this.rootID + '_activetab');
	this.inputField2 	= document.getElementById(this.rootID + '_activetabname');
	// alle Reiter erfassen
	this.tabcount = P['tabcount']
	this.tabnamesArr = P['tabnames'].split(';#;')
	this.saveMode = P['saveMode']
	this.tabs = {};
	for(i=0;i<this.tabcount; i++) {
		tab = document.getElementById(this.rootID + '_tab' + i);
		this.tabs['tab'+i] = tab
		registerEventListenersObj(tab, "mousedown",	this, false, 'activatetab',i);
	}
	imgPreloader(new Array('tabs_active1n.gif','tabs_active1r.gif','tabs_active2n.gif','tabs_active2r.gif','tabs_inactive1n.gif','tabs_inactive1r.gif','tabs_inactive2n.gif','tabs_inactive2r.gif'));
	// alert(showObject(this.tabs))
}

tabsObj.prototype.activatetab = function(e,el,tabNum) {
	activetab = document.getElementById(this.rootID + '_tab' + tabNum);
	//alert("activetab " + activetab.id)
	//alert(showObject(this.tabs))
	var i = 0;
	for (tab in this.tabs) {
		//alert(this.tabs[tab].id)
		this.tabs[tab].className = this.tabs[tab].className.replace('li_active','li_inactive');
		//alert(this.tabs[tab].className)
		// alert(this.rootID + '_layer' + i)
		if (document.getElementById(this.rootID + '_layer' + i)) {
			//alert(this.rootID + '_layer' + i)
			document.getElementById(this.rootID + '_layer' + i).style.display = 'none'
		}
		i++
	}
	activetab.className = activetab.className.replace('li_inactive','li_active');
	if (document.getElementById(this.rootID + '_layer' + tabNum)) {
			document.getElementById(this.rootID + '_layer' + tabNum).style.display = ''
	}
	// alert("this.id " + this.id + " pars " + pars)
	this.inputField.value = tabNum
	this.inputField2.value = this.tabnamesArr[tabNum]
	window.queryStr = modifyQueryString(window.queryStr,0,this.rootID + '_activetab', this.inputField.value)
	// alert("window.queryStr " + window.queryStr)
	// alert(this.saveMode + "this.parentForm " + this.parentForm.name)
	if (this.saveMode == 'POST') {
		this.parentForm.submit();
	}
	if (this.saveMode == 'GET')  {
		newUrl =  modifyQueryString('',1,'',window.queryStr)							// normal: 			varname, varvalue	
		// alert("newUrl: " + newUrl)
		document.location.href = newUrl
	}
}




function clapObj(P) {
	if (!window.queryStr) window.queryStr = getQueryStr()
	/* I N F O 
	Erwartet ein Parameterobject {}
	*/
	if (!P.rootID) alert("clapObj: no rootID, can't go on")
	else this.rootID = P.rootID
	
	// registerEventListenersObj(document, "mouseup",  this, false, 'refreshArea');
	this.rootEl = document.getElementById(this.rootID)
	// Bereiche
	this.openerID  		= this.rootID + '_opener';			this.opener 	= document.getElementById(this.openerID);   		if (!this.opener) 	alert("clapObj: no opener, can't go on")
	this.claptargetID  	= P['claptargetID'];				this.claptarget = document.getElementById(this.claptargetID);   	if (!this.claptarget) 	alert("clapObj: no claptarget, can't go on")
	this.parentForm 	= findParentElementByNodeName(document.getElementById(this.rootID),'form')
	this.inputField 	= document.getElementById(this.rootID + '_clapstate');	
	this.clapstate 		= P['clapstate']
	this.saveMode 		= P['saveMode']
	this.resizewindow 	= P['resizewindow']
	this.autoClapTarget = P['autoClapTarget']
	registerEventListenersObj(this.opener, "click",	this, false, 'clap'); // IE hat ein Problem beim window.resize die richtige Hoehe zu berechnen, etwas spater geht es.
	// alert("claptargetID: " + this.claptargetID)
	// alert("this.clapstate: "+this.clapstate)
	// !autoClapTarget heisst, dass das Claptarget ausserhalb liegt, also ein beliebiges Element sein kann, dessen display nicht mir PHP geschrieben werden kann.
	// Es muss also ueber Javascript geoeffnet werden.
	// alert(this.clapstate)
	if (!this.autoClapTarget && this.clapstate=='opened') this.clap('opened')
}


clapObj.prototype.clap = function(state) {
// Fensterhoehe bestimmen IE mit Leisten?
	if (document.all) 	{
		this.windowWidth  = document.body.clientWidth + 8 // fuer Border
		this.windowHeight = document.body.clientHeight + 29
	} else {
		this.windowWidth  = window.outerWidth
		this.windowHeight = window.outerHeight
	}
	// alert("this.windowWidth " + this.windowWidth + " this.windowHeight " + this.windowHeight)
	// alert("this.clapstate " + this.clapstate)
	
	// O E F F N E N
	if (this.clapstate == 'closed' || state == 'opened') {
		this.opener.className = this.opener.className.replace('clap_closed','clap_opened');
		// alert(this.claptarget.className)
		if (hasClassName(this.claptarget,"claptarget_closed"))  this.claptarget.className = this.claptarget.className.replace('claptarget_closed','claptarget_opened');
		else 													this.claptarget.className += ' claptarget_opened';
		this.clapstate 				= 'opened'
		this.inputField.value 		= 'opened'
		this.claptarget.style.display = ''	// sicherheitshalber deise Eigenschaft entfernenm soll vom ClassName ueberschreiben werden
		window.queryStr 			= modifyQueryString(window.queryStr,0,this.rootID + '_clapstate', this.inputField.value)
		if (this.resizewindow) {
			clapTargetHeight = this.claptarget.offsetHeight
			//alert("clapTargetHeight " + clapTargetHeight)
			//alert(window.outerHeight + clapTargetHeight + 'px')
			//if (document.all) 	{window.resizeTo(this.windowWidth, this.windowHeight + clapTargetHeight)}
			//else 				{window.outerHeight = window.outerHeight + clapTargetHeight + 'px'}
			if (document.all) 	{window.resizeBy(0, clapTargetHeight)}
			else 				{window.outerHeight = '800px'}
		}
	// S C H L I E S S E N	
	} else {					
		if (this.resizewindow) {
			clapTargetHeight = this.claptarget.offsetHeight
			//alert("clapTargetHeight " + clapTargetHeight)
			if (document.all) 	{window.resizeBy(0, -clapTargetHeight)}
			else 				{window.outerHeight = window.outerHeight - clapTargetHeight + 'px'}
		}
		// alert(this.claptarget.className)
		if (hasClassName(this.claptarget,"claptarget_opened"))  this.claptarget.className = this.claptarget.className.replace('claptarget_opened','claptarget_closed');
		else 													this.claptarget.className += ' claptarget_closed';
		this.claptarget.style.display 				= ''
		this.opener.className = this.opener.className.replace('clap_opened','clap_closed');
		this.clapstate 				= 'closed'
		this.inputField.value 		= 'closed'
		window.queryStr 			= modifyQueryString(window.queryStr,0,this.rootID + '_clapstate', this.inputField.value)
	}
	// alert(this.saveMode)
	// alert(this.parentForm.name)
	if (this.saveMode =='POST') document[this.parentForm.name].submit();
	/*
	alert(		"this.clapstate " 			+ this.clapstate 				+ "\n" + 
				"claptarget.id: " 			+ this.claptarget.id			+ "\n" + 
				"claptarget.className: " 	+ this.claptarget.className		+ "\n" + 
				
	"")
	*/
	
}

	
	
	
function areaObj(P) {
	
	if (!window.queryStr) window.queryStr = getQueryStr()
	/* I N F O 
	Erwartet ein Parameterobject {constrain_h:'20px', ...}
	*/
	if (!P.rootID) alert("areaObj: no rootID, can't go on")
	else this.rootID = P.rootID
	P.direction  ?  this.direction = P.direction  : this.direction  = 'h'
	// registerEventListenersObj(document, "mouseup",  this, false, 'refreshArea');
	this.rootEl = document.getElementById(this.rootID)
	// Bereiche
	this.area1ID  		= this.rootID + '_1';				this.area1 		= document.getElementById(this.area1ID);   			if (!this.area1) 	alert("areaObj: no area1, can't go on")
	this.area2ID  		= this.rootID + '_2';				this.area2 		= document.getElementById(this.area2ID);   			if (!this.area2) 	alert("areaObj: no area2, can't go on")
	this.sliderID 		= this.rootID + '_slider';			this.slider 	= document.getElementById(this.sliderID);			if (!this.slider) 	alert("areaObj: no areaSlider, can't go on")
	this.inputField 	= document.getElementById(this.rootID + '_a1f');														if (!this.inputField) 	alert("areaObj: no inputField '" +this.rootID + "_a1f,' can't go on") 
	this.framesize     	= P.framesize
	this.slidersize     = parseInt(P.slidersize)
	this.defaultfactor  = P.defaultfactor
	this.slideroverlay  = P.slideroverlay
	this.parentForm		= findParentElementByNodeName(this.rootEl,'form')
	this.parentStartWidth  = this.rootEl.offsetWidth
	this.parentStartHeight = this.rootEl.offsetHeight
	// alert(this.rootID + " this.defaultfactor " + this.defaultfactor)
	// dragObj
	var obj = this // Fuer call
	if (document.all) 	registerEventListenersObj(window, "resize",	this, false, 'resizeAreaLater'); // IE hat ein Problem beim window.resize die richtige Hoehe zu berechnen, etwas spater geht es.
	else 				registerEventListenersObj(window, "resize",	this, false, 'resizeArea');
	// registerEventListenersObj(window, "resize",	this, false, 'resizeArea');
	
	// window.setInterval(function() {obj.checkForSizeChanges('')}, 100)
	// Slideroverlay einstellen
	if (this.slideroverlay == true) 	{
		if (this.direction == 'v') {
			document.getElementById(this.rootID + '_overlay1v').style.left 		= -this.framesize  + 'px'
			document.getElementById(this.rootID + '_overlay1v').style.width 	=  this.framesize  + 'px'
			document.getElementById(this.rootID + '_overlay1v').style.height 	=  this.slidersize + 'px'
			document.getElementById(this.rootID + '_overlay2v').style.width 	=  this.framesize  + 'px'
			document.getElementById(this.rootID + '_overlay2v').style.height 	=  this.slidersize + 'px'
		} else {
			document.getElementById(this.rootID + '_overlay1h').style.top 		= -this.framesize + 'px'
			document.getElementById(this.rootID + '_overlay1h').style.height 	=  this.framesize + 'px'
			document.getElementById(this.rootID + '_overlay2h').style.height 	=  this.framesize + 'px'
		}
	}

	// Startwerte
	this.resizeArea('')
	
	// alert(showObject(this))
	if (this.direction=='h') new dragObj({
					dragEl: 			this.rootID + '_slider', 
					constrainH:			1, 
					maxLeft: 			this.rootEl, 
					maxRight:			this.rootEl,  
					call_startdrag:		function(){obj.resetSlider(this,'absolute')}, 
					call_stopdrag:		function(){obj.resetSlider(this,'relative')}, 
					call_drag:			function(){obj.resizeArea(this)}   
					})
	if (this.direction=='v') new dragObj({
					dragEl: this.rootID + '_slider', 
					constrainV:			1, 
					maxTop: 			this.rootEl,  
					maxBottom:			this.rootEl,
					call_startdrag:		function(){obj.resetSlider(this,'absolute')}, 
					call_stopdrag:		function(){obj.resetSlider(this,'relative')}, 
					call_drag:			function(){obj.resizeArea(this)}   
					})
					
}

areaObj.prototype.resizeAreaLater = function() {
	var obj = this
	//report("resizeAreaLater " + this.rootID)
	// report("resizeAreaLater " + obj.rootID)
	window.setTimeout(function() {obj.resizeArea('')}, 100)
}


areaObj.prototype.checkForSizeChanges = function() {
	if (this.rootEl.offsetWidth != this.parentStartWidth) {
		this.parentStartWidth = this.rootEl.offsetWidth
		this.resizeArea('');
	}
	if (this.rootEl.offsetHeight != this.parentStartHeight) {
		this.parentStartHeight = this.rootEl.parentStartHeight
		this.resizeArea('');
	}
}
areaObj.prototype.resizeArea = function(obj) {
// obj ist das Object, das den caller sendet, z. B. das dragObj

		// alert("resizeArea " + this.rootID)
		// if (this.direction == 'h') this.area1.width  = obj.posH - absLeft(this.area1) + 'px'
		if (this.inputField.value) 	this.defaultfactor = this.inputField.value
		_height = 0;
		_width  = 0;
		
		if (this.direction == 'v') {
			if (this.defaultfactor) 	defaultsize = parseInt((this.rootEl.offsetHeight - this.slidersize) * this.defaultfactor)
			else 						defaultsize = parseInt((this.rootEl.offsetHeight - this.slidersize) * 0.5)
			if (!obj.posV) 				_height = defaultsize
			else 						_height = obj.posV - absTop(this.rootEl)
			this.area1.style.top 		= 0
			this.area1.style.height 	= _height 			+ 'px'
			this.slider.style.top 		= _height 			+ 'px'
			this.slider.style.height 	= this.slidersize 	+ 'px'						// slider
			this.area2.style.height 	= this.rootEl.offsetHeight - _height - this.slidersize + 'px'
			this.area2.style.top 		= (_height 			+ this.slidersize) + 'px'
		}
		if (this.direction == 'h') {
			if (this.defaultfactor) 	defaultsize = parseInt((this.rootEl.offsetWidth - this.slidersize) * this.defaultfactor)
			else 						defaultsize = parseInt((this.rootEl.offsetWidth - this.slidersize) * 0.5)
			if (!obj.posH) 				_width = defaultsize
			else 						_width = obj.posH - absLeft(this.rootEl)
			//this.area1.style.height 	= '100%'
			//this.area2.style.height 	= '100%'
			//this.slider.style.height 	= '100%'
			
			this.area1.style.left 		= 0
			this.area1.style.width 		= _width 			+ 'px'
			this.slider.style.left 		= _width 			+ 'px'
			this.slider.style.width 	= this.slidersize 	+ 'px'						// slider
			this.area2.style.width 		= this.rootEl.offsetWidth - _width - this.slidersize + 'px'
			this.area2.style.left 		= (_width 			+ this.slidersize) + 'px'
		}
		/*
		alert(
				"rootID " 							+ this.rootID	+ "\n" + 
				"absTop(this.rootEl) " 				+ absTop(this.rootEl)	+ "\n" + 
				"obj.posV " 						+ obj.posV 	+ "\n" + 
				"maxHeight " 						+ this.rootEl.offsetHeight 	+ "\n" + 
				"maxWidth " 						+ this.rootEl.offsetWidth 	+ "\n" + 
				"_areaframe.offsetHeight"			+ document.getElementById(this.rootID +'_areaframe').offsetHeight 	+ "\n" + 
				"_height " 							+ _height 					+ "\n" + 
				"_width " 							+ _width 					+ "\n" + 
				"defaultsize " 						+ defaultsize 				+ "\n" + 
				"this.defaultfactor " 				+ this.defaultfactor 			+ "\n" + 
				"this.slidersize " 					+ this.slidersize 			+ "\n" + 
				"this.area1.style.top " 			+ this.area1.style.top 		+ "\n" + 
				"this.area1.style.height " 			+ this.area1.style.height 	+ "\n" + 
				"this.slider.style.top " 			+ this.slider.style.top 	+ "\n" + 
				"this.slider.style.height " 		+ this.slider.style.height 	+ "\n" +
				"this.area2.style.top " 			+ this.area2.style.top 	+ "\n" +  
				"this.area2.style.height" 			+ this.area2.style.height 	+ "\n" + 
				"")
			*/
	
}
areaObj.prototype.resetSlider = function(obj, mode) {
	if (this.direction == 'h') 	this.inputField.value = (this.area1.offsetWidth/parseFloat(this.rootEl.offsetWidth   - this.slidersize))
	else 						this.inputField.value = (this.area1.offsetHeight/parseFloat(this.rootEl.offsetHeight - this.slidersize))
	window.queryStr = modifyQueryString(window.queryStr,0,this.rootID + '_a1f', this.inputField.value)
}
areaObj.prototype.refreshArea = function(e) {
	e  = (e) ? e : event;
	el = (e.target) ? e.target : e.srcElement;
	if (el == this.areaSlider) {
		// alert("refreshArea")
	}
}



// ________________________________________________________________________________________________________________________________
// D R A G 
function dragObj(P) {
	/* I N F O 
	Erwartet ein Parameterobject {dragEl:dragEl...constrain_h:'20px', ...}
	-	dragEl
		das zu draggende ELement, wird erst nach Klick activert (this.activated)
	
	*/
	//alert(type(P.dragEl))
	// window.EvLisObj = {} // nach jedem Refresh wieder leeren
	if(typeof P.dragEl == 'object') 	this.dragEl = P.dragEl									// kann ein HTML object sein
	else 								this.dragEl = document.getElementById(P.dragEl)			// oder eine ID
	// alert("P.dragEl " + P.dragEl)
	// this.sq = 1
	if (!this.dragEl) alert("dragObj: no dragEl ("+P.dragEl+"). Can't go on")
	// alert("this.dragEl " + this.dragEl)
	/*
	this.position = 'relative'
	if (this.dragEl.style.position == 'relative' || this.position == 'relative') {
		this.parentEl = this.dragEl.parentNode	// wenn relative, dann mussen die Distancen in Bezug auf den Parent berechnet werden
		this.parentLeft = absLeft(this.parentEl)
		this.parentTop  = absTop(this.parentEl)
		// report(this.parentEl.nodeName + " parentEl coords:  " + this.parentLeft	+ ' ' + this.parentTop)
	}*/
	if(P.controlEl)	this.controlEl  = document.getElementById(P.controlEl) // ein anderes Element, dass als Ausloeser dient
	else 			this.controlEl  = this.dragEl
	// alert(this.controlEl.id)
	// alert(this.controlEl.nodeName)
	this.dummy 				= P.dummy // Es wird nicht das Original-Element bewegt, sondern ein Dummy (Rahmen oder so)
	// +++ Achtung: Wichtig: wenn da Element 
	//P.positionToParent    ?  this.positionToParent = P.positionToParent : this.positionToParent = this.positionToParent //function(){report('mouseup on droptarget')}
	
	P.constrainH 			?  this.constrainH  = P.constrainH  	: this.constrainH  	= 0		// Bewegung beschränken horizontal
	P.constrainV 			?  this.constrainV  = P.constrainV  	: this.constrainV  	= 0		// Bewegung beschränken vertikal
	P.maxLeft 				?  this.maxLeft 	= P.maxLeft  		: this.maxLeft 		= 0 	// Abstand zum Umfassenden Container left			Werte: %, px
	P.maxTop 			 	?  this.maxTop 		= P.maxTop  		: this.maxTop 		= 0		// Abstand top
	P.maxRight 				?  this.maxRight 	= P.maxRight  		: this.maxRight 	= 0		// Abstand right
	P.maxBottom 			?  this.maxBottom  	= P.maxBottom  		: this.maxBottom 	= 0		// Abstand bottom
	P.dropTargetClass 		?  this.dropTargetClass    = P.dropTargetClass    : this.dropTargetClass 	= 'droptarget'		// Abstand bottom
	P.dropTargetFunction    ?  this.dropTargetfunction = P.dropTargetFunction : this.dropTargetfunction = this.mouseTargetFunction //function(){report('mouseup on droptarget')}
	// +++ Das geht nicht:     this.dropTargetfunction = function(){...)}, fuehrt zu n-fach Ausfuehrung, wenn der Listener mehrfach an eine Element gehaengt wird.
	
	// Bsp: Griffe in eime Div, das verschoben wird. Hier sollen die absoluten Positionen nur in Bezug auf das parent-Div berechnet werden,
	// damit die griffe auch automatisch mit dem Parentelement verscoben werden koennen.
	// Wenn das Parentelement absolut positioniert ist, liegt der Nullpunkt der Griffe in der linke oberen Ecke des Parents. 
	this.posRelativeToParent = 0
	if (this.dragEl.parentNode.style && this.dragEl.parentNode.style.position == 'absolute') this.posRelativeToParent = 1
	
	// alert(this.dropTargetClass)
	// alert(this.dropTargetfunction)
	// Funktionen, die gerufen wird bei drag, dragstart, dragstop, z. B. vom areaObj
	P.call_startdrag 		?  this.call_startdrag  = P.call_startdrag  	: this.call_startdrag 	= ''
	P.call_drag 			?  this.call_drag  		= P.call_drag  			: this.call_drag 		= ''
	P.call_stopdrag			?  this.call_stopdrag  = P.call_stopdrag  		: this.call_stopdrag 	= ''
	this.activated = null;
	this.width = this.dragEl.offsetWidth
	registerEventListenersObj(document, 	'mousedown',	this, false, 'startdrag');
	registerEventListenersObj(document, 	'mousemove',	this, false, 'drag');
	registerEventListenersObj(document, 	'mouseup',		this, false, 'stopdrag');											// alert(is_ie)
	obj = this
	// Ich erzeuge alle potentiellen Droptargets fuer dieses Dragobjet.
	// Das ist evtl. etwas ressourcenverschwenderisch, bei jedem Klick, aber ich habe für jedes Drag-Elenet die Moeglichkeit, individuelle Droptaregts zu definieren
	// es werden ebenfalls fuer alle dropTargets Listener erzeugt.
	if (this.dropTargetClass) {
		elArr = getElementsByClassNameM(document,'div',this.dropTargetClass)
		L = elArr.length
		// Das Problem hier: Wenn ich eine literale Funktion oder eine Methode(wird auch als literale Funktion umgesetzt) für ein Element mehrfach registriere,
		// sammeln sich die Listener an und werden mehrfasch ausgefuehrt, ich bekomme sei auch mit removeEventListener nicht weg.
		// Das passeirt bei einfachen Functionen icht, da kann ich aber weder Paramer mitgeben, noch auf Eigenschaftem des Objektes zugreifen
		// Dilemma...
		// if (!window.EvLisObj) window.EvLisObj = {} // speichert fuer bereits mit einem Listener fuer "startdroptarget" versehenen Elemente, um Doppelbesetzung zu vermeiden
		
		for (i=0; i<L; i++) {
			// +++ Achtung: Geht nicht mit einer literalen Funktion... dann vervielfacht sich der Listener
			//elArr[i].removeEventListener('mouseup',	this['startdroptarget'], false) 
			// function registerEventListenersObj(element,eventtype,listener,captures,f,pars)
			// report(window.EvLisObj['e'+i]+"<br>")
			elArr[i].onmouseup = function(e){obj.startdroptarget(e)} // e ist hier das eventObjekt
			// document.removeEventListener('mouseup',false,startdroptarget)
			// registerEventListenersObj(elArr[i], 	'mouseup',	this, false, 'startdroptarget');
		}
		// report(showObject(window.EvLisObj))
	}
}

dragObj.prototype.startdrag = function(e,dummy) {
	// alert("startdrag")
	e  = (e) ? e : event;
	el = (e.target) ? e.target : e.srcElement;
	// report(this.controlEl.id + " " + this.dragEl.id)
	if (this.controlEl == el || this.controlEl == dummy) {
		el = this.dragEl
		X = e.clientX
		Y = e.clientY
		// report("clientX " 		+ e.clientX + "\n" + "clientY " 		+ e.clientY )
		if (this.call_startdrag) this.call_startdrag()
		this.activated = 1
		if (this.sq) report(el.id + "was activated<br>")
		
		if (this.dragEl.style.position == 'relative' || this.posRelativeToParent) {
			this.parentEl = this.dragEl.parentNode	// wenn relative, dann mussen die Distancen in Bezug auf den Parent berechnet werden
			this.parentLeft = absLeft(this.parentEl)
			this.parentTop  = absTop(this.parentEl)
			// report(this.parentEl.nodeName + " parentEl coords:  " + this.parentLeft	+ ' ' + this.parentTop)
		}
		// alert(this.dragEl.id)
		// report("this.dragEl " + this.dragEl.nodeName)
		// this.OffsetLeft 	= parseInt(this.dragEl.offsetLeft) // wird in ie bis zum Rand, in Moz bis rum naechsten Blocllevel gerehcnet
		// this.OffsetTop 	 	= parseInt(this.dragEl.offsetTop) 
		this.OffsetLeft 	= parseInt(absLeft(this.dragEl))
		this.OffsetTop 	 	= parseInt(absTop(this.dragEl)) 
		this.dragdistLeft 	= X - this.OffsetLeft								// report(this.dragEl.offsetLeft + "  " + absLeft(this.dragEl))
		this.dragdistTop  	= Y - this.OffsetTop
		
		/*
		alert(	"startdrag " 	+ "\n" + 
				"clientX " 		+ e.clientX + "\n" + 
				"clientY " 		+ e.clientY + "\n" + 
				"OffsetLeft " 	+ this.OffsetLeft + "\n" + 
				"OffsetTop " 	+ this.OffsetTop + "\n" + 
				"dragdistLeft " + this.dragdistLeft + "\n" + 
				"dragdistTop "  + this.dragdistTop
		)
		*/
		if (!document.all) 	{e.preventDefault()} // wichtig fuer Moz, nicht den Griff anklicken!
		else 				{e.cancelBubble = true; e.returnValue = false}
		window.dragActive = 1; // globale, die einen gerade laufenden Dragvorgang anzeigt
	}
}
dragObj.prototype.drag = function(e) {
	e = (e) ? e : event;
	if (this.dragEl && this.activated){
		this.posH  = e.clientX - this.dragdistLeft
		this.posV  = e.clientY - this.dragdistTop
		// e.preventDefault();
		// e.cancelBubble = true
		
		// e.stopPropagation();
		
		if (this.dragEl.style.position == 'relative' || this.posRelativeToParent) {
			// report("dragEl " + this.posH + " " + this.posV + " parentEl " + this.parentEl.offsetLeft	 + ' ' +this.parentEl.offsetTop + "<br/>")
			this.posH = this.posH - this.parentLeft 		// relative Positionierung
			this.posV = this.posV - this.parentTop 
		}
		// report("this.posH " + this.posH)
		//report("this.maxLeft " + this.maxLeft.nodeName)
		
		// C O N S T R A I N S
		// Als Constrain koenne Werte oder Elemente dienen
		if (this.maxLeft) {
			if (this.maxLeft.nodeName) 	_maxLeft = absLeft(this.maxLeft)
			else  						_maxLeft = this.maxLeft
			if (this.posH < _maxLeft) this.posH = _maxLeft
		}
		if (this.maxRight) {
			if (this.maxRight.nodeName) _maxRight = absLeft(this.maxLeft) + this.maxRight.offsetWidth - this.dragEl.offsetWidth
			else  						_maxRight = this.maxLeft
			if (this.posH > _maxRight) this.posH = _maxRight
		}
		if (this.maxTop) {
			if (this.maxTop.nodeName) 	_maxTop = absTop(this.maxTop)
			else  						_maxTop = this.maxTop
			if (this.posV < _maxTop) this.posV = _maxTop
			
		}
		if (this.maxBottom) {
			if (this.maxBottom.nodeName) _maxBottom = absTop(this.maxBottom) + this.maxBottom.offsetHeight - this.dragEl.offsetHeight
			else  						_maxBottom = this.maxBottom
			if (this.posV > _maxBottom) this.posV = _maxBottom
		}
		if (this.sq) report(" posH " + this.posH)
		if (!this.constrainV) this.dragEl.style.left = this.posH + 'px'
		if (!this.constrainH) this.dragEl.style.top  = this.posV + 'px'
		if (this.call_drag) this.call_drag()
		// events
		if (!document.all) 	{e.preventDefault()} // wichtig fuer Moz, nicht den Griff anklicken!
		else 				{e.cancelBubble = true; e.returnValue = false}
	}
}

dragObj.prototype.stopdrag = function(e) {
	if (this.dragEl && this.activated){
		this.activated = 0
		if (this.call_stopdrag) this.call_stopdrag()
		if (this.dummy) this.dragEl.parentNode.removeChild(this.dragEl)
		window.dragActive = 0; // globale, die einen gerade laufenden Dragvorgang anzeigt
	}
}
dragObj.prototype.startdroptarget = function(e) {
	// alert("dropTargetfunction ")
	// el = (e.target) ? e.target : e.srcElement;
	// report("startdroptarget: " + el.id + "<br>")
	// alert(showObject(e))
	// report("startdroptarget: "+ this.dragEl.id+"<br>")
	this.dropTargetfunction(e,this.dragEl)
}
//  
function activateDrag(e, el, dropTargetClass, dropTargetFunction) { // erstellt beim klick auf ein zu draggendes Element das DragObject on the fly
		// alert(typeof el)
		// if(el) alert("das ding gibt es")
		tr  	= findParentElementByNodeName(el,'tr')
		div 	= document.createElement("div")
		div.style.cssText = 'position:absolute; background:transparent; left:'+(absLeft(tr)+50)+'px; top:'+absTop(tr)+'px; border:1px solid red; width:'+(tr.offsetWidth-50)+'px; height:'+tr.offsetHeight+'px;'
		div.id  = 'dummy'+el.id // darf nur 1 '_' enthalten, z.B. dummydragEl_2
		document.body.appendChild(div)
		// es wird ein dragObject erzeugt, mit eime IDfilter...
		obj = new dragObj({
			dragEl: 			div, 
			dummy: 				1, 
			constrainV:			1, 
			dropTargetClass :	dropTargetClass,
			dropTargetFunction:	dropTargetFunction
			//call_startdrag:		function(){obj.resetSlider(this,'absolute')}, 
			//call_stopdrag:		function(){obj.resetSlider(this,'relative')}, 
			//call_drag:			function(){obj.resizeArea(this)}   
		})
		obj.startdrag(e,div)
		// report(div.id+"<br>")
		return obj
}















// ________________________________________________________________________________________________________________________________
// T R E E
function treeObj(rootID,saveMode,sq) {
	if (!window.queryStr) window.queryStr = getQueryStr()   // global
	// alert(window.queryStr)
/* I N F O 
-	SaveMode POST ist noch nicht fertigentwickelt

-	Um mehrere Bäume parallel betreiben zu koenne, muss der IDstr als globale definiert sein und von aalen Bäumen modizizeirt werden koennen.
	Das Problem ist, dass jeder einzelne Baum die Werte des anderen mitberuecksichtigen muss.
	Es muss also bei jedem Klick uf eine Link des Baumes die Url+qierystring ausgelesen werden und die entsprechenden Werte fuer  d i e s e n   Baum eingesetzt werden.
	Dabei mussen die Werte anderer Bäume erhlten bleiben.
		
	Bei Klick wird dei url des Links um ein paar query-Parameter erweitert: Die Zustandsvariablen des Baumes: IDstr + activeID
		
- 	window.treeIDstr:
		ist ein global Variable, die von allen Trees verwendet wird.
		Der window.treeIDstr wird bei jedem Klick auf eine open-Element aktualisiert

-	getTreeTargetUrl()
	wird direkt vom Link des Baumes aufgerufen
			
*/
	this.sq = sq // debug
	// this.sq = 1 // debug
	if (!rootID) alert('treeObj: Can\'t start, no rootID');
	this.rootID 		= rootID // tree_meinbaum, ist wichtig, um bei mehreren Bäumen die GET Varaiblen auseinanderhalten zu koennen
	this.startIDStr 	= '';
	this.saveMode		= saveMode
	// alert("this.saveMode " + this.saveMode)
	if (this.saveMode =='GET') {
		queryVarObj = parseQueryStr();			// querystring auslesen, um aktive ID zu erkennen
		// alert(queryVarObj.querystring + "\n" + queryVarObj[this.rootID + '_IDstr'])
		this.activeID 	= (queryVarObj[this.rootID + '_activeID'] ? queryVarObj[this.rootID + '_activeID'] : '')
		this.IDstr 	    = (queryVarObj[this.rootID + '_IDstr']    ? queryVarObj[this.rootID + '_IDstr'] : '')
		// +++ Achtung: globale Variable, um mehrere Strings von verschiedenen Trees zu speichern
		//if (!window.treeIDstr) window.treeIDstr = this.rootID + '_IDstr' + '=' + this.IDstr
		// if (!window.treeIDstr) window.treeIDstr = this.rootID + '_IDstr' + '=' + this.IDstr
		
		// alert("this.IDstr " + this.IDstr)
		//alert("queryVarObj.tree2_IDstr " + queryVarObj.tree2_IDstr)
	}
	this.parentForm = findParentElementByNodeName(document.getElementById(this.rootID),'form')
	
	if (this.saveMode =='POST') {
		// alert(this.parentForm.name)
		if (this.parentForm) {
			if (this.parentForm[this.rootID + '_IDstr'].value) 	  this.IDstr    = this.parentForm[this.rootID + '_IDstr'].value
			if (this.parentForm[this.rootID + '_activeID'].value) this.activeID = this.parentForm[this.rootID + '_activeID'].value;
			// if (document[this.parentForm.name][this.rootID + '_IDstr'].value) 	 this.IDstr    = document[this.parentForm.name][this.rootID + '_IDstr'].value
			//if (document[this.parentForm.name][this.rootID + '_activeID'].value) this.activeID = document[this.parentForm.name][this.rootID + '_activeID'].value;
			/*alert(	"POST "   	+ "\n" + 
					"IDstr "    + this.IDstr    + "\n" + 
					"activeID " + this.activeID + "\n")
			*/
		}
	}
	this.buildtree()
}



// this function apply the CSS style and the event
treeObj.prototype.buildtree = function() {
	this.tree = document.getElementById(this.rootID); 		// the root element
	this.lis = this.tree.getElementsByTagName('li'); 		// alle li in lis
	/*
	// alert(startIDstr)
	if (CatMode != 'folder') {
		ebene = 0
		checkforParentNodes(document.getElementById('lix'+activeID))
		if (IDstr.indexOf(startIDstr)==-1) IDstr += startIDstr // wnn es kein Ordner ist, muss die aktive Seite sichtbar werden, dann wird der IDstr um den Pfad der aktiven Seite erweitert
	}
	*/
	/*
	alert(	
			"rootID "    	  	+ this.rootID      	+ "\n" + 
			"IDstr "      		+ this.IDstr      	+ "\n" + 
			"startIDstr " 		+ this.startIDstr 	+ "\n" + 
			"activeID " 		+ this.activeID 	+ "\n"
	)
	*/
	// alert(activeID)
	// actives Elelement markieren
	// alert(this.activeID)
	if (this.activeID && document.getElementById(this.activeID)) document.getElementById(this.activeID).firstChild.className += ' activeelement'			// actives Element kennzeichnen
	this.IDstrObj = {}
	
	if (this.IDstr) {						// globale
		IDstrArr = this.IDstr.split("_")
		// alert(this.rootID + " this.IDstr " + this.IDstr)
		for(i=0;i<IDstrArr.length;i++) {
			// alert("IDstrArr[i] " + IDstrArr[i])
			if (IDstrArr[i]) {
				this.IDstrObj[IDstrArr[i]] = "open"; // es reicht, wenn die objecteigenschaften vorhanden sind
				// alert(IDstrObj[IDstrArr[i]])
			}
		}
	}
	for (var i=0; i<this.lis.length; i++) {
		ebene = 0
		this.checkforParentNodes(this.lis.item(i),0) 														// ebene ermitteln
		li_ebene = ebene/2; 																	// alert(ebene)
		if (this.lis[i].getElementsByTagName('ul').length > 0) { 
			registerEventListenersObj(this.lis[i], "mousedown", this, false, 'show');
			this.lis[i].getElementsByTagName('ul')[0].style.display = "none"; 
			// alert(this.lis[i].id)
			if (this.IDstrObj[this.lis[i].id] == "open") {													// ist es ein zu oeffnenedes li?						
				//alert("oeffne: " + IDstrObj["li"+i] + " " + lis[i].id)		
				this.lis[i].getElementsByTagName('ul')[0].style.display = "block"; 					// sichtbar machen
				this.lis[i].firstChild.style.backgroundImage = 'url(/cms/images/tree_icon_dirminus.gif)'
			}
		}
	}
	// adjustEditFormAction(this.rootID,this.IDstr)
}



treeObj.prototype.getOpenElements = function() {
	var lis     = this.tree.getElementsByTagName('li'); // all the li
	this.IDstr  = '';
	for (var i=0; i<lis.length; i++) {
		if (lis[i].getElementsByTagName('ul').length > 0) { 											//alert("lis[i].getElementsByTagName('ul')[0].style.display " + lis[i].getElementsByTagName('ul')[0].style.display)    
			if (lis[i].getElementsByTagName('ul')[0].style.display != "none") {
				// this.IDstr += ("_"+lis[i].id)
				this.IDstr += ("_"+lis[i].id)
			}
		}
	}
	// alert("getOpenElements " +this.IDstr)
	if (this.sq) {
	alert(			"this.IDstr " + this.IDstr  + "\n" + 
					"this.rootID " + this.rootID)
	}
	if (this.sq) alert("vorher " + "\n" + window.queryStr)
	// window.treeIDstr = modifyQueryString(window.treeIDstr,0,this.rootID + '_IDstr', this.IDstr)
	window.queryStr = modifyQueryString(window.queryStr,0,this.rootID + '_IDstr', this.IDstr)
	if (this.sq) alert(	"nachher" + "\n" + window.queryStr)
	// alert(this.parentForm.name)
	if (this.parentForm) {
		if (this.IDstr)    this.parentForm[this.rootID + '_IDstr'].value    = this.IDstr
		if (this.activeID) this.parentForm[this.rootID + '_activeID'].value = this.activeID;
		// adjustEditFormAction(this.rootID,this.IDstr)
	}
}


 


// show the first ul element found under this element
treeObj.prototype.show = function(e,handlerOwnerElement) {
	e = (e) ? e : event;
	// handlerOwnerElement ist das Element,m das den lsitener traegt.
	// Notloesung, da IE die Eigenschft "e.currentTarget "nicht unterstuetzt
	if (document.all) 	el = e.srcElement
	else  				el = e.target								//alert(handlerOwnerElement.nodeName)
	if (document.all) 	actuelLi = handlerOwnerElement
	else 				actuelLi = e.currentTarget
	if (hasClassName(el,"switch")) {
		actuelDisplay = actuelLi.getElementsByTagName('ul')[0].style.display
		if (actuelDisplay=="block") 	{
			actuelLi.getElementsByTagName('ul')[0].style.display = 'none';
			el.style.backgroundImage = 'url(/cms/images/tree_icon_dirplus.gif)'
		}
		if (actuelDisplay != "block") {
			actuelLi.getElementsByTagName('ul')[0].style.display = 'block';
			el.style.backgroundImage = 'url(/cms/images/tree_icon_dirminus.gif)'
		}
		if(!document.all) 	e.stopPropagation()
		else 				window.event.cancelBubble=true;
	}
	this.getOpenElements()
}

treeObj.prototype.checkforParentNodes = function(el,rootID) {
	if (el.parentNode.id == rootID) return;
	ebene++;
	if (el.id.indexOf("li") != -1) {this.startIDstr += "_"+el.id} 				// ermittelt auch noch die uebergeordneten li, um den ganzen Baum auszuklappen
	this.checkforParentNodes(el.parentNode)
}


function getTreeTargetUrl(activeID, rootID, url) {
	// Diese Funktion wird beim Klick auf den Link eines li Elements aufgrufen
	obj = window[rootID + '_tree'];	// +++ Achtung: hier mit obj arbeiten, statt this!
	// alert("obj.saveMode " + obj.saveMode)
	// alert("getTreeTargetUrl url " + url)
	newUrl = modifyQueryString(url, 1, '', window.queryStr + ('&'+rootID + '_activeID='+activeID))	//alert("adjustLinkTarget newTargerurl "+newTargerurl)
	//alert(newUrl)
	if (!newUrl) newUrl = '?'													// Problem: wenn newUrl = '', der Baum also eingeklappt ist und keine anderen GET unterwegs sind, dann
	// Submit
	if (obj.saveMode == 'POST') {
		//alert("submit via POST")
		if (obj.parentForm) {
			if (activeID) obj.parentForm[obj.rootID + '_activeID'].value = activeID;
			obj.parentForm.submit();
		}
	} else {	
		// alert("via GET")			
		document.location.href = newUrl
	}
}


// H E L P E R    F U N C T I O N S
// hide the ul elements under the element identified by id
function hideUlUnder(id) {   
    document.getElementById(id).getElementsByTagName('ul')[0].style.display = 'none';
}

function hideAllOthersUls(currentLi) {													// hide all ul on the same level of  this list item
    var ul = currentLi.parentNode; 														// alert(lis.childNodes.length);
    for (var i=0; i<ul.childNodes.length; i++) {
        if (ul.childNodes[i].id && ul.childNodes[i].id != currentLi.id) {
            hideUlUnderLi(ul.childNodes[i] );
        }
    }
}
function adjustEditFormAction(rootID, IDstr) {
	// alert("adjustEditFormAction " + rootID + " " + IDstr)
	parentForm = findParentElementByNodeName(document.getElementById(rootID),'form')
	// alert("parentForm.name " + parentForm.name)
	if (parentForm) {
		// changeQueryPars: es werden Variablenname + Wert uebergebn und in die Url eingesetzt
		parentForm.action = modifyQueryString(parentForm.action, 0,rootID +'_IDstr', IDstr)		//
		// alert("parentForm.action " + parentForm.action)
	}
}

function hideUlUnderLi(li) {																	// hide all the ul wich are in the li element
    var uls = li.getElementsByTagName('ul');
    for (var i=0; i<uls.length; i++) {
        uls.item(i).style.display = 'none';
    }
} 

