/**
 * AJAX api
 *
 * $URL: svn://localhost/RBL-dev/tags/2010-06-05_rbl_hfr/jkcms/js/ajax_container.js $
 * $Rev: 1279 $
 * $Author: jk $
 * $Date: 2010-05-28 20:37:38 +0200 (Fr, 28 Mai 2010) $
 * 
 */

var ajax_event;
// Browser Erkennung
var BROWSER = new cBrowser();

/**
 * Ajax-Basisobjekt ajax_obj
 * @super Object
 * @type constructor
 * @memberOf ajax_obj
 * @param objid variablename
 */
ajax_obj.prototype = new Object();
function ajax_obj(objid) {
	
	this.id        = objid;
	this.container = null;				// DIV-Container
	this.titel     = null;				// Überschrift H4
	this.content   = null;				// Inhalt im Container-Fenster
	this.target    = null;				// Inhalt im Document-Element <target>
	this.target_mode = 'replaceContent';// replaceContent = Inhalt von target ersetzen
										// addContent = an Inhalt von Target anhängen
										// replaceNode = target ersetzen
										// insertBefore = vor target einfügen
	/**
	 * XMLHttpRequest Objekt
	 * @property ajax
	 * @type XMLHttpRequest
	 */
	this.ajax      = null;				// XMLHttpRequest-Objekt
	this.abstandX  =   10;				// horizontaler und ...
	this.abstandY  =   10;				// vertikaler Abstand vom Mauszeiger
	this.width     =  300;				// Breite und ...
	this.height    =    0;				// Höhe des Containers
	this.minheight =  150;				// Höhe des Containers
	this.pos_x     =    0;				// Position des
	this.pos_y     =    0;				// Containers
	this.xmlresult =   '';				// Rückgabewert xml: <value>resulttext</value>
	this.onLoad    = null;				// callback funktion wenn daten geladen
	this.onClose   = null;				// callback funktion wenn Fenster geschlossen wird
	this.onNoAjax  = ajax_not_avail;	// callback funktion wenn Ajax nicht verfügbar
	this.movable   = true;				// kann man den Container verschieben
	this.pendingImg= null;				// "Sanduhr"
	//this.create_container = create_container;
	/**
	 * erzeugt Div-Container (Fenster)
	 * @method create_container  
	 * @param {Int} X x-Koordinate
	 * @param {Int} Y y-Koordinate
	 */
	this.create_container = function (X, Y) {
		if (this.container) this.close();

		this.container = document.createElement("div");
		if (this.id) {
			this.container.id = this.id;
		}
		this.container.className = "ajax";
		this.container.style.width  = this.width + "px";
		if (this.height) {
			this.container.style.height = this.height + "px";
		}
		if ((X >= 0) && (Y >= 0)) {
			// Positionieren, abhängig von Mauszeiger und Browserfenster
			// Der Kasten soll rechts vom Mauszeiger erscheinen, wenn dort
			// noch Platz ist oder links kein Platz ist
			var scroll = new ajax_get_scrollpos();
			this.pos_x = ((X + this.abstandX + this.width + 30 < window.innerWidth) || (this.width + this.abstandX > X)) ?
					X + this.abstandX : // rechts von Mauszeiger
					X - (this.width + this.abstandX); // links
			// Der Kasten soll über dem Mauszeiger erschein, wenn Platz ist
			if (this.height > 0) {
				this.pos_y = (this.height + this.abstandY < Y - scroll.Y) ?
						Y - this.height - this.abstandY :  // unter Mauszeiger
						Y + this.abstandY; // darüber
			} else {
				this.pos_y = (Y - this.minheight + this.abstandY < scroll.Y) ?
						scroll.Y + this.abstandY :          // am oberen Rand
						Y - this.minheight - this.abstandY; // über Mauszeiger
			}
			//alert('roll: '+scroll.X + ' ' + scroll.Y);// + "\npos: "+ pos_x + ' ' + pos_y + "\nmaus: "+ FN.mausX + ' ' + FN.mausY);
		}
		this.container.style.left = this.pos_x + "px";
		this.container.style.top  = this.pos_y + "px";
		// Überschrift
		this.titel = document.createElement("h4");
		this.titel.icon = document.createElement('img');
		this.titel.icon.src = '/pic/pix.gif';
		this.titel.icon.className = 'icon';
		this.titel.appendChild(this.titel.icon);
		this.titel.txt = document.createTextNode('Titel');
		this.titel.appendChild(this.titel.txt);
		// Link zum Schließen
		var sp_link = document.createElement("a");
		sp_link.ajaxobj = this;
		sp_link.onclick = function () {
			this.ajaxobj.close();
		};
		sp_link.setAttribute("title", "schließen");
		sp_link_txt = document.createTextNode(' ');
		sp_link.appendChild(sp_link_txt);

		if (this.movable) {
			this.titel.onmousedown = ajax_obj_drag_start;
			this.titel.style.cursor = "move";
		}

		// zusammensetzen
		this.titel.appendChild(sp_link);
		this.container.appendChild(this.titel);

		this.content = document.createElement("div");
		this.content.className = "ajax_content";
		if (this.height) {
			this.content.style.height = this.height - 20 + "px";
		}
		
		this.pendingImg = document.createElement('img');
		this.pendingImg.src = '/pic/wait.gif';
		this.pendingImg.className = 'pending';
		this.content.appendChild(this.pendingImg);
		
		this.container.appendChild(this.content);

		document.getElementsByTagName("body")[0].appendChild(this.container);
	};
	this.close     = function() {
		// schließt und löscht den Container
		if (this.container) {
			
			if (this.onClose) {
				this.onClose();
			}
			
			document.getElementsByTagName('body')[0].removeChild(this.container);
			this.container = null;
		}
	};
	
	this.load = function (url) {
		
		var self = this;
		
		// evtl eine PHP Sessionid anhängen
		if (SESSID) {
			if (url.indexOf(SESSID) == -1) {
				if (url.search(/\?/) >= 0) {
					url = url.concat('&'+SESSID);
				} else {
					url = url.concat('?'+SESSID);
				}
			}
		}

		// Pending Image einschalten
		if (this.pendingImg) {
			this.pendingImg.style.display = 'block';
		}

		// Ajax-Verbindung herstellen
		try {           
			// W3C-Standard
			this.ajax = createXMLHttp();
		} catch(err) {
			this.ajax = new noXMLHttpRequest(this);
			if (url.search(/\?/) >= 0) {
				url = url.concat('&noxmode=iframe');
			} else {
				url = url.concat('?noxmode=iframe');
			}
		}

		if (url.length < 2000) {
			// Datei mit GET anfordern (asynchron)
			this.ajax.open('GET', url, true);//encodeURI(url)
			this.ajax.setRequestHeader('Content-Type', 'text/xml');
			// umgeht Internet Explorers Caching von GET-Anfragen
			this.ajax.setRequestHeader('If-Modified-Since', 'Sat, 1 Jan 2000 00:00:00 GMT');

			this.ajax.send(null);
		} else {
			var p = url.indexOf('?');
			var param = url.substr(p+1);
			url = url.slice(0,p);
			this.ajax.open("POST", url, true);

			this.ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
			this.ajax.setRequestHeader("Content-length", param.length);
			this.ajax.setRequestHeader("Connection", "close");

			// make the server request
			this.ajax.send(param);
		}
		// nach Status-Änderungen der Verbindung
		// werden die empfangenen Inhalte geparst

		this.ajax.onreadystatechange = function() {	
			// wenn Datei komplett empfangen ist ...
			if (self.ajax.readyState == 4) {
				// Dokument nicht gefunden (Code 0 für lokale Tests):
				if (self.ajax.status != 200 && self.ajax.status != 0) {
					alert('XML-Fehler: Datei konnte nicht gefunden werden!'+self.ajax.status);
					var er_text = document.createTextNode("XML-Datei konnte nicht gefunden werden!");
					var absatz = document.createElement("p");
					absatz.appendChild(er_text);
					self.container.appendChild(absatz);
					document.body.style.cursor = 'auto';
					return false;
				}

				if (!self.ajax.responseXML) {
					alert('XML-Fehler: \n'+self.ajax.responseText.replace(/<[^>]*>/g, ''));
					document.body.style.cursor = 'auto';
					return false;
				}

				//alert('onreadystatechange:' + self.id);

				// schreibe titel in fns
				if (self.titel) {
					var fns = self.ajax.responseXML.getElementsByTagName("titel");
					if ((fns.length > 0) && (fns[0].firstChild)) {
						self.titel.txt.nodeValue = fns[0].firstChild.nodeValue;
						//alert(fns[0].firstChild.nodeValue);
					}
					// schreibe icon in fns
					var fns = self.ajax.responseXML.getElementsByTagName("icon");
					if (fns.length > 0) {
						self.titel.icon.src = fns[0].firstChild.nodeValue;
						//alert(fns[0].firstChild.nodeValue);
					}
				}

				// schreibe content in fns
				if (self.content) {
					var fns = self.ajax.responseXML.getElementsByTagName("content");
					if (fns.length > 0) {
						klonen(fns[0].cloneNode(true), self.content);
					}
				}

				var fns = self.ajax.responseXML.getElementsByTagName("targets");
				if (fns.length > 0) {
					// neue Variante: ajaxHandler bestimmt Targets und Modes 
					var targets = fns[0].getElementsByTagName("target");
					if (targets.length > 0) {
						for (var i = 0; i < targets.length; i++) {
							var target = targets[i];
							var target_id = target.getAttribute('id');
							if (target_id) {
								var old_target = document.getElementById(target_id);
								var target_mode = target.getAttribute('mode');
							} else {
								var old_target = self.target;
								var target_mode = self.target_mode;
							}
							if (old_target) {
								if ((target_mode == 'replaceNode') || (target_mode == 'insertBefore')) {

									// Parent als DocumentFragment erstellen
									var new_target = document.createDocumentFragment();
									klonen(target.cloneNode(true), new_target);

									old_target.parentNode.insertBefore(new_target, old_target);

									if (target_mode == 'replaceNode') {
										// Target löschen
										old_target.parentNode.removeChild(old_target);
									}

								} else {
									if (target_mode == 'replaceContent') {
										while(child = old_target.firstChild) {
											old_target.removeChild(child);
										}
									}
									// target_mode = 'addContent'
									klonen(target.cloneNode(true), old_target);
								}
							}
						}
					}
				} else if (self.target) {
					// schreibe target in fns
					var fns = self.ajax.responseXML.getElementsByTagName("target");
					if (fns.length > 0) {
						if ((self.target_mode == 'replaceNode') || (self.target_mode == 'insertBefore')) {

							// Parent als DocumentFragment erstellen
							var new_target = document.createDocumentFragment();
							klonen(fns[0].cloneNode(true), new_target);

							self.target.parentNode.insertBefore(new_target, self.target);

							if (self.target_mode == 'replaceNode') {
								// Target löschen
								self.target.parentNode.removeChild(self.target);
							}

						} else {
							if (self.target_mode == 'replaceContent') {
								while(child = self.target.firstChild) {
									self.target.removeChild(child);
								}
							}
							// self.target_mode = 'addContent'
							klonen(fns[0].cloneNode(true), self.target);
						}
					}
				}

				// schreibe value in fns
				var fns = self.ajax.responseXML.getElementsByTagName("value");
				if ((fns.length > 0) && (fns[0].firstChild)) {
					//alert("nodeType = " + fns[0].firstChild.nodeType);
					if (fns[0].firstChild.nodeType == 3) {
						// textknoten
						self.xmlresult = fns[0].firstChild.nodeValue;
					} else {
						self.xmlresult = new Object;
						var vnode = fns[0].firstChild;
						while (vnode != null) {
							if (vnode.firstChild) {
								self.xmlresult[vnode.nodeName] = vnode.firstChild.nodeValue;
//								alert(vnode.nodeName + " = " + vnode.firstChild.nodeValue);
//								else
//								self.xmlresult[vnode.nodeName] = '';
//								alert(vnode.nodeName + " = #");
							}
							vnode = vnode.nextSibling;
						}
					}
				} else {
					self.xmlresult = '';
				}

				// Pending Image ausschalten
				if (self.pendingImg) {
					self.pendingImg.style.display = 'none';
				}
				//alert(self.onLoad);
				if (self.onLoad) {
					self.onLoad();
				}
				document.body.style.cursor = 'auto';
				return true;
			}
		}; // onreadystatechange

	};
	
	/**
	 * setzt den Textknoten eines DOM-Nodes
	 * @param parent
	 * @param {string} text
	 */
	this.setTextNode = function (parent, text) {
		//alert(BROWSER.OP);
		if (parent) {
			//alert('['+parent.firstChild.nodeValue+']');
			if (typeof text == 'undefined') text = '';
			if (parent.firstChild) {
				if (BROWSER.OP) {
					parent.replaceChild(document.createTextNode(text), parent.firstChild);
				} else {
					parent.firstChild.nodeValue = text;
				}
			} else if (text) {
				parent.appendChild(document.createTextNode(text));
			}
		}
	};

	/**
	 * setzt den Textknoten eines Element durch seine ID
	 * @param {string} id
	 * @param {string} text
	 * @return (node) 
	 */
	this.setTextNodeById = function (id, text) {
		var el = document.getElementById(id);
		if (el) this.setTextNode(el, text);
		return el;
	};

	/**
	 * setzt den Wert eines Formular-Elements ermittelt durch seine ID
	 * @param {string} id
	 * @param {string} value
	 * @return (node) 
	 */
	this.setNodeValueById = function (id, value) {
		var el = document.getElementById(id);
		if (el) el.value = value;
		return el;
	};

	/**
	 * fügt die Werte des Rückgabe-Arrays in das Dokument ein
	 * die Zielknoten für die einzelnen Werte müssen das
	 * ID-Attribut in der Form "[name]_[id]_[feldname]" haben
	 * 
	 * {Boolean} Function( {String} name ); 
	 */
	this.setXmlResult = function(name) {
		if ((typeof(this.xmlresult) == 'object') && (this.xmlresult['id'])) {
			var id = this.xmlresult['id'];
			for (var key in this.xmlresult) {
				// Ziel suchen
				var node = document.getElementById(name + '_' + id + '_' + key);
				this.setTextNode(node, this.xmlresult[key]);
			}
			return true;
		}
		return false;
	};
}

function noXMLHttpRequest(parent_obj) {
	this.parent_obj = parent_obj;
	window._ifr_buf_count |= 0;
	this.iframe = null;
	this.iframeID = 'iframebuffer' + window._ifr_buf_count++;
	this.url = '';
	this.open = noXMLHttpRequest_open;
	this.setRequestHeader = noXMLHttpRequest_setRequestHeader;
	this.send = noXMLHttpRequest_send;
	this.onreadystatechange = null;
	this.onready = noXMLHttpRequest_onready;
	this.readyState = 1;
	this.status = 1;
	this.responseXML;
	this.win;
}

function noXMLHttpRequest_open(method, url, dummy) {
	this.url = url;
}

function noXMLHttpRequest_setRequestHeader(key, value) {
	// IE5.0 doesn't like createElement'd frames (won't script them) and IE4 just plain
	// doesn't support it. Luckily, this will fix them both:
	document.body.insertAdjacentHTML('beforeEnd', '<iframe name="' + this.iframeID +
			'" id="' + this.iframeID + '" style="display: none;"></iframe>');// style="position: absolute;"

	// This helps most IE versions regardless of the creation method:
	if (window.frames && window.frames[this.iframeID]) this.iframe = window.frames[this.iframeID];
}

function noXMLHttpRequest_send(dummy) {
	this.iframe.document.location.replace(this.url);
}

function noXMLHttpRequest_onready() {
	var responseXML;

	if (this.iframe.contentDocument) {
		// For NS6
		responseXML = this.iframe.contentDocument;
	} else if (this.iframe.contentWindow) {
		// For IE5.5 and IE6
		responseXML = this.iframe.contentWindow.document;
	} else if (this.iframe.document) {
		// For IE5
		responseXML = this.iframe.document;
	}

	if (responseXML) {
		// schreibe titel
		if (this.parent_obj.titel) {
			var fns = responseXML.getElementById("xmlrsp_titel");
			if ((fns) && (fns.firstChild)) {
				this.parent_obj.titel.txt.nodeValue = fns.firstChild.nodeValue;
				//alert(fns.firstChild.nodeValue);
			}
		}

		// schreibe content in fns
		if (this.parent_obj.content) {
			var fns = responseXML.all.xmlrsp_content;
			if (fns) { 
				this.parent_obj.content.insertAdjacentHTML("AfterBegin",fns.innerHTML);
			}
		}

		// schreibe target in fns
		if (this.parent_obj.target) {
			var fns = responseXML.all.xmlrsp_target;
			if (fns) {
				// @todo (jk) replace/add
				while(child = this.parent_obj.target.firstChild) {
					this.parent_obj.target.removeChild(child);
				}
				this.parent_obj.target.insertAdjacentHTML("AfterBegin",fns.innerHTML);
			}
		}

		if (this.iframe.getvalue) {
			this.parent_obj.xmlresult = this.iframe.getvalue();
		}

		// Pending Image ausschalten
		if (this.pendingImg) {
			this.pendingImg.style.display = 'none';
		}
		if (this.parent_obj.onLoad) {
			this.parent_obj.onLoad();
		}
		document.body.style.cursor = 'auto';
		return true;
	}
	return false;
}

function ajax_obj_drag_start() {
	// this ist hier das H4 Element => der container ist this.parentNode

	return drag_start(this.parentNode);
}

function ajax_not_avail() {
	alert("Ihr Browser kann leider keine Ajax-Inhalte anzeigen.");
}

function createXMLHttp() {

	if (typeof XMLHttpRequest != "undefined") {
		//alert('XMLHttpRequest' + (typeof XMLHttpRequest));
		return new XMLHttpRequest();
	} else if (window.ActiveXObject) {
		var aVersions = [ "MSXML2.XMLHttp.5.0",
		                  "MSXML2.XMLHttp.4.0","MSXML2.XMLHttp.3.0",
		                  "MSXML2.XMLHttp","Microsoft.XMLHttp"
		                  ];

		for (var i = 0; i < aVersions.length; i++) {
			try {
				var oXmlHttp = new ActiveXObject(aVersions[i]);
				//alert(aVersions[i]);
				return oXmlHttp;
			} catch (oError) {
				//Do nothing
			}
		}
	}
	//alert('no XMLHttp');
	throw new Error("XMLHttp object could be created.");
}

function klonen(quelle, ziel) {
	// Hilfsfunktion für Darstellung im DOM
	// Einfaches cloneNode() funktioniert nicht bei komplexen
	// Gebilden; eine Schleife baut den Teilbaum nach.
	for(var i = 0; i < quelle.childNodes.length; i++) {
		var knoten = quelle.childNodes[i];
		switch (knoten.nodeType) {
		case 1:   // Elementknoten
//				alert('Quelle: Nodename = '+knoten.nodeName);
			if (BROWSER.IE && (BROWSER.Version < 8)) {
				// IE fix
				var attribs = '';
				if ((knoten.outerHTML) && (knoten.nodeName.toLowerCase() == 'img')) {
					newNode = document.createElement(knoten.outerHTML);
				} else {
					var newNode = document.createElement(knoten.nodeName);
					for (var j = 0; j < knoten.attributes.length; j++) {
						switch (knoten.attributes[j].nodeName.toLowerCase()) {
						case "class":
							newNode.className = knoten.attributes[j].nodeValue;
							break;
						case "cellpadding":
							newNode.cellPadding = knoten.attributes[j].nodeValue;
							break;
						case "cellspacing":
							newNode.cellSpacing = knoten.attributes[j].nodeValue;
							break;
						case "width":
							if (knoten.attributes[j].nodeValue)
								newNode.width = knoten.attributes[j].nodeValue;
							break;
						case "height":
							if (knoten.nodeName.toLowerCase() != 'input')
//								alert('height:'+knoten.attributes[j].nodeValue);
								if (knoten.attributes[j].nodeValue)
									newNode.height = knoten.attributes[j].nodeValue;
							break;
						case "align":
							newNode.align = knoten.attributes[j].nodeValue;
							break;
						case "bgcolor":
							newNode.bgColor = knoten.attributes[j].nodeValue;
							break;
						case "id":
							newNode.id = knoten.attributes[j].nodeValue;
							break;
						case "size":
							newNode.size = knoten.attributes[j].nodeValue;
							break;
						case "maxlength":
							newNode.maxLength = knoten.attributes[j].nodeValue;
							break;
						case "type":
							// ausser <button type="button" ...>
							if ((knoten.nodeName.toLowerCase() != 'button') || (knoten.attributes[j].nodeValue.toLowerCase() != 'button'))
								newNode.type = knoten.attributes[j].nodeValue;
							break;
						case "value":
							newNode.value = knoten.attributes[j].nodeValue;
							break;
						case "href":
							newNode.href = knoten.attributes[j].nodeValue;
							break;
						case "name":
							newNode.name = knoten.attributes[j].nodeValue;
							break;
						case "colspan":
							newNode.colSpan = knoten.attributes[j].nodeValue;
							break;
						case "rowspan":
							newNode.rowSpan = knoten.attributes[j].nodeValue;
							break;
						case "onclick":
						case "ondblclick":
						case "onkeyup":
						case "onchange":
						case "onsubmit":
						case "onmouseover":
						case "onmouseout":
							newNode[knoten.attributes[j].nodeName.toLowerCase()] = new Function(knoten.attributes[j].nodeValue);
							break;
						case "style":
							var styles = knoten.attributes[j].firstChild.nodeValue.split(';');
							if (styles.length > 1) {
								for (var i = 0; i < styles.length - 1; i++) {
									try {
										var style = styles[i].split(':');
										newNode.style[style[0]] = style[1];
									} catch(err) {
										// do nothing
									}
								}
							} else {
								alert(knoten.attributes[j].firstChild.nodeValue);
							}
							break;
							// geprüfte Attribute, die mit setattribute funktionieren
						case "checked":
						case "selected":
						case "method":
						case "action":
						case "title":
						case "alt":
						case "src":
							newNode.setAttribute(knoten.attributes[j].nodeName, knoten.attributes[j].nodeValue);
							break;
						default: // noch nicht geprüfte Attribute
						newNode.setAttribute(knoten.attributes[j].nodeName, knoten.attributes[j].nodeValue);
						//alert('Attribut: '+knoten.attributes[j].nodeName+' = "'+knoten.attributes[j].nodeValue+'"');
						}
						attribs += ' ' + knoten.attributes[j].nodeName.toLowerCase() + '="' + knoten.attributes[j].nodeValue + '"';
					}
				}
			} else {
				// correct DOM (firefox/opera)
				var newNode = document.createElement(knoten.nodeName);
				for (var j = 0; j < knoten.attributes.length; j++) {
					newNode.setAttribute(knoten.attributes[j].nodeName, knoten.attributes[j].nodeValue);
				}
			}

			// IE input width bugfix
			if ((BROWSER.IE) && (BROWSER.Version < 8) && (knoten.nodeName.toLowerCase() == 'input') && (newNode.width == 0)) {
				newNode.removeAttribute("width");
//				alert(newNode.type);
			}

			if ((BROWSER.IE) && (BROWSER.Version < 8) && (knoten.nodeName.toLowerCase() == 'input') && (newNode.type == 'radio')) {
				// IE radio button bugfix
				//alert(knoten.outerHTML);
				if (knoten.outerHTML) {
					newNode = document.createElement(knoten.outerHTML);
				} else {
					var add = '';
					if (newNode.checked)   add += ' checked';
					if (newNode.className) add += ' class="'+newNode.className+'IE"';
					newNode = document.createElement('<input type="radio" name="'+newNode.name+'" value="'+newNode.value+'"'+add+'>');
				}
			} else if ((BROWSER.IE) && (BROWSER.Version < 8) && (knoten.nodeName.toLowerCase() == 'input') && (newNode.type == 'checkbox')) {
				// IE checkbox bugfix
				//alert(knoten.outerHTML);
				if (knoten.outerHTML) {
					newNode = document.createElement(knoten.outerHTML);
				} else {
					newNode = document.createElement('<input' + attribs + '>');
				}
			} else {
				// rekursion
				klonen(knoten, newNode);
			}

			var neu = ziel.appendChild(newNode);
			break;
		case 3:   // Textknoten
			subknoten = document.createTextNode(knoten.nodeValue);
			ziel.appendChild(subknoten);

			// andere Knotentypen sind nicht relevant
		}
	}
}

function ajax_get_event(e) {
	ajax_event = new ajax_set_event(e);

	// drag and drop
	if (drag_object) {
		drag_move();
	} else if (jkMouseMoveCallback) {
		jkMouseMoveCallback();
	}
}

function ajax_set_event(e) {
	if (!e) {
		this.type = window.event.type;
		this.target=window.event.srcElement;
		this.clientX = window.event.clientX;
		this.clientY = window.event.clientY;
		if (document.documentElement && document.documentElement.scrollTop) { 
			// Explorer 6 Strict
			this.pageX = window.event.clientX + document.documentElement.scrollLeft;
			this.pageY = window.event.clientY + document.documentElement.scrollTop;
		} else if (document.body) {
			// all other Explorers
			this.pageX = window.event.clientX + document.body.scrollLeft;
			this.pageY = window.event.clientY + document.body.scrollTop;
		}
	} else {
		this.type = e.type;
		this.target = e.currentTarget;
		this.clientX = e.clientX;
		this.clientY = e.clientY;
		this.pageX = e.clientX + window.pageXOffset;
		this.pageY = e.clientY + window.pageYOffset;
	}

	return false;
}

/**
 * Enthält die horizontale oder vertikale Scroll-Verschiebung
 * @constructor
 */
function ajax_get_scrollpos() {
	if (isFinite(self.pageYOffset)) {
		// DOM
		this.X = self.pageXOffset;
		this.Y = self.pageYOffset;
		//alert('pageYOffset = ' + this.Y);
	} else if (document.documentElement && document.documentElement.scrollTop) {
		this.X = document.documentElement.scrollLeft;
		this.Y = document.documentElement.scrollTop;
		//alert('documentElement.scrollTop = ' + this.Y);
	} else if (document.body) {
		// all other Explorers
		this.X = document.body.scrollLeft;
		this.Y = document.body.scrollTop;
		//alert('body.scrollTop = ' + this.Y);
	}
}

/**
 * liefert das Rechteck (x,y,w,h) eines Elements mit absoluten Koordinaten
 * 
 * @param {Object} o HTML-Element
 * @return rect {x,y,w,h}
 */
function jkAbsoluteRect(o) {

    var r = { x:0, y:0, w:0, h:0 };

    if(!o) {
    	return r;
    } else if(typeof o == 'string' ) {
    	o = document.getElementById(o);
    } 

    if( typeof o != 'object' ) return r;

    if(typeof o.offsetTop != 'undefined') {

         r.h = o.offsetHeight;
         r.w = o.offsetWidth;
         r.x = r.y = 0;

         while (o && o.tagName != 'BODY')         {

              r.y += parseInt( o.offsetTop );
              r.x += parseInt( o.offsetLeft );
              o = o.offsetParent;

         }
    }

    return r;
}


// drag and drop

var jkMouseMoveCallback = null;

jkDragDropObject.prototype = new Object();
function jkDragDropObject() {
	/**
	 * div-Element (mit Klasse "__drag"), das eine Kopie der drag-Quelle enthält
	 * @private
	 */
	this.container = null;
	
	/**
	 * drag-Quelle
	 * @private
	 */
	this.source = null;
	
	/**
	 * drop-Ziel
	 * @private
	 */
	this.target = null;
	
	/**
	 * registrierte drop-Ziele
	 * @private
	 */
	this.drop_targets = new Array();
	
	/**
	 * callback: fn(source,target) wird aufgerufen, wenn das drag-Objekt
	 * auf einem drop-target losgelassen wird
	 */
	this.onDragDrop = null;
	
	/**
	 * eingefügte Oberfläche, um Mouse-Events abzufangen
	 */
	this.drag_canvas = null;
	
	/**
	 * Startet die Drag-Aktion mit drag_source als zu ziehenes Objekt
	 * (auslösen mit onmousedown)
	 * 
	 * @param drag_source HTML-Element
	 */
	this.start = function(drag_source) {
		
		this.source = drag_source;
		
		this.drag_canvas = document.createElement('div');
		
		var rb = jkAbsoluteRect(document.getElementsByTagName("body")[0]);
		this.drag_canvas.id = 'drag_canvas';
		this.drag_canvas.style.position = 'absolute';
		this.drag_canvas.style.left = "0px";
		this.drag_canvas.style.top  = "0px";
		this.drag_canvas.style.width  = "100%";
		this.drag_canvas.style.height  = rb.h + "px";
		this.drag_canvas.style.backgroundColor  = "transparent";
		this.drag_canvas.style.backgroundImage = 'url("/pic/pix.gif")';
		this.drag_canvas.overflow = 'hidden';
		this.drag_canvas.style.zIndex  = 99;

		var self = this;
		this.drag_canvas.onmousemove = function (e) {
			
			// markieren verhindern
			if(window.getSelection) {
			    var sel = window.getSelection();
			    sel.removeAllRanges();
			}		
			
			var ev = new ajax_set_event(e);
			
			var mx = ev.pageX;
			var my = ev.pageY;
			var can_drop;
			
			if (self.container) {
				self.container.style.left  = ev.pageX + self.drag_x_rel + "px";
				self.container.style.top   = ev.pageY + self.drag_y_rel + "px";
			}
			
			self.target = null;

			for (var i = 0; i < self.drop_targets.length; ++i) {

				var dt = self.drop_targets[i];
				if (dt != self.source) {
					var r = jkAbsoluteRect(dt);

					if ((mx > r.x) && (mx < r.x + r.w) && (my > r.y) && (my < r.y + r.h)) {
						if ((self.target) && (self.target.onDragOut)) {
							self.target.onDragOut();
						}
						if (dt.onDragOver) {
							can_drop = dt.onDragOver(self.source, mx - r.x, my - r.y);
						} else {
							can_drop = true;
						}

						if (can_drop) {
							self.target = dt;
						}
					} else {
						if (dt.onDragOut) dt.onDragOut();
					}
				}
			}

		};

		/**
		 * behandelt den onmouseup-Event, um die Drag-Aktion zu beenden
		 * 
		 * @private
		 */
		this.drag_canvas.onmouseup = function() {
			if (self.target) {
				if (self.target.onDragOut) self.target.onDragOut();
				
				if (self.onDragDrop) self.onDragDrop(self.source, self.target);
			}
			
			if (self.drag_canvas) {
				document.getElementsByTagName("body")[0].removeChild(self.drag_canvas);
			}

			self.drag_canvas = null
			self.container = null;
			self.target = null;

		};

		document.getElementsByTagName("body")[0].appendChild(this.drag_canvas);
				
		// Container erstellen
		if (this.onDragStart) this.onDragStart(drag_source);
		
	};
	
	/**
	 * Standard DragStart-Aktion mit drag_source als zu ziehenes Objekt
	 * 
	 * @param drag_source HTML-Element
	 */
	this.defaultDragStart = function(drag_source) {
		
		// Container erstellen
		var r = jkAbsoluteRect(drag_source);
		this.container = document.createElement('div');
		
		if (drag_source.nodeName.toLowerCase() == 'li') {
			// erst das Eltern Element 
			//var p = this.container.appendChild(drag_source.parentNode.cloneNode(false));
			//p.appendChild(drag_source.cloneNode(true));
		} else {
			this.container.appendChild(drag_source.cloneNode(true));
		}
		this.container.className = '__drag';
		this.container.style.position = 'absolute';
		
		// Relative Position zur Maus merken
		var r = jkAbsoluteRect(drag_source);
		this.drag_x_rel = r.x - ajax_event.pageX;
		this.drag_y_rel = r.y - ajax_event.pageY;
		this.container.style.left = r.x + "px";
		this.container.style.top  = r.y + "px";
		this.container.style.width  = r.w + "px";
		this.container.style.height  = r.h + "px";
		this.container.style.opacity  = "0.6";
		this.drag_canvas.appendChild(this.container);
		
	};
	
	/**
	 * registriert ein HTML-Element als gültiges Ziel
	 * das HTML-Element kann die Event-Handler 
	 * bool onDragOver(source) Ergebnis: darf source abgelegt werden?
	 * und
	 * onDragOut()
	 * enthalten, um z.B. ein highlighting zu realisieren
	 * 
	 * @param drop_target HTML-Element
	 */
	this.register_drop_target = function(drop_target) {
		this.drop_targets.push(drop_target);
	};
	
	/**
	 * callback: fn(drag_source) DragStart-Aktion mit drag_source als zu ziehenes Objekt
	 * 
	 * @param drag_source HTML-Element
	 */
	this.onDragStart = this.defaultDragStart;
	
	// Abstand des drag-Objekts zur Mausposition
	this.drag_x_rel;
	this.drag_y_rel;
}


// Zwischenspeicher für document events
var document_onmouseup   = null;
var document_onmousedown = null;
// Abstand des drag-Objekts zur Mausposition
var drag_x_rel;
var drag_y_rel;
var drag_object = null;
var drag_callback = null;

function drag_start(obj) {
	if (drag_object) {
		drag_drop();
		//alert('drag_start drag_drop');
	} else {
		// aktuelle Position ermitteln
		if (obj.style.left) {
			var objX = parseInt(obj.style.left.slice(0,-2));
			drag_x_rel = objX - ajax_event.pageX;
		} else if (obj.style.right) {
			var objX = parseInt(obj.style.right.slice(0,-2));
			drag_x_rel = objX + ajax_event.pageX;
		}
		if (obj.style.top) {
			var objY = parseInt(obj.style.top.slice(0,-2));
			drag_y_rel = objY - ajax_event.pageY;
		} else if (obj.style.bottom) {
			var objY = parseInt(obj.style.bottom.slice(0,-2));
			drag_y_rel = objY + ajax_event.pageY;
		}

		//alert(obj.style.left+':'+obj.style.top+':'+obj.style.right);
		//alert(objX+':'+objY);
		//alert(drag_x_rel+':'+drag_y_rel);
		//return;

		drag_object = obj;
		// Zwischenspeicher für document events
		document_onmouseup   = document.onmouseup;
		document_onmousedown = document.onmousedown;

		document.onmouseup   = drag_drop;
		// Sicherheitsmaßnahme: manche Browser kommen mit den Ereignissen
		// durcheinander, z.B. beim Scrollen in Überlangen Inhalten
		// (Safari) oder bei Maus-Hektik (IE); in diesem Fall läst ein
		// Mausklick den am Zeiger klebenden Container.
		//document.onmousedown = drag_drop;
		//alert(drag_object);
	}
	return false;
}

function drag_move() {
	// verschiebt den Container parallel zu Mausbewegungen
	if (drag_object.style.left) {
		drag_object.style.left  = ajax_event.pageX + drag_x_rel + "px";
	} else if (drag_object.style.right) {
		drag_object.style.right = drag_x_rel - ajax_event.pageX + "px";
	}

	if (drag_object.style.top) {
		drag_object.style.top    = ajax_event.pageY + drag_y_rel + "px";
	} else if (drag_object.style.bottom) {
		drag_object.style.bottom = drag_y_rel - ajax_event.pageY + "px";
	}

	if (drag_callback) drag_callback();
}

function drag_drop() {
	// löscht Event-Handler, lässt Container los
	document.onmouseup   = document_onmouseup;
	drag_object = null;
	drag_callback = null;
}

document.onmousemove = ajax_get_event;

/* String URL encodieren */

function urlencode_string( estring ) {
	hex = '0123456789ABCDEF';

	var c;
	encString = '';
	e_char = '';
	e_len = estring.length;

	for( e_i = 0; e_i < e_len; e_i++ ) {
		c = estring.charAt( e_i );
		if (c.match(/[a-z0-9_,-.()]/i)) {
			encString += c;
		} else {
			e_char = parseInt( estring.charCodeAt( e_i ) );

			encString += '%' + hex.charAt( (e_char >> 4) % 16 ) + hex.charAt( e_char % 16 );
		}
	}

	return encString;
}

// Hilfsfunktion zum auswerten der formulardaten
function ajax_form2url(form) {
	if (form) {
		var params = '';
		var el;
		var value;
		// Werte der input Elemente übernehmen
		var n = form.getElementsByTagName("input").length;
		for (i = 0; i < n; i++) {
			el = form.getElementsByTagName("input")[i];
			// alles übernehmen ausser buttons, unselektierte radio buttons und checkboxen
			if (((el.type != 'submit') && (el.type != 'button') && (el.type != 'radio') && (el.type != 'checkbox')) || (el.checked == true)) {
				value = urlencode_string(el.value);
				//if (console) console.log("%s",el.name+'='+value);
				params = params.concat('&'+el.name+'='+value);
			}
		}
		// Werte der select Elemente übernehmen
		var n = form.getElementsByTagName("select").length;
		for (i = 0; i < n; i++) {
			el = form.getElementsByTagName("select")[i];
			if (el.selectedIndex >= 0) {
				value = urlencode_string(el.options[el.selectedIndex].value);
				//if (console) console.log("%s",el.name+'='+value);
				params = params.concat('&'+el.name+'='+value);
			}
		}
		// Werte der textarea Elemente übernehmen
		var n = form.getElementsByTagName("textarea").length;
		for (i = 0; i < n; i++) {
			el = form.getElementsByTagName("textarea")[i];
			value = urlencode_string(el.value);
			//if (console) console.log("%s",el.name+'='+value);
			params = params.concat('&'+el.name+'='+value);
		}

		return params.replace(/^&/, '');
	}
	return '';
}

function ajax_SetTextNode(parent, text) {
	//alert(BROWSER.OP);
	if (parent) {
		//alert('['+parent.firstChild.nodeValue+']');
		if (typeof text == 'undefined') text = '';
		if (parent.firstChild) {
			if (BROWSER.OP) {
				parent.replaceChild(document.createTextNode(text), parent.firstChild);
			} else {
				parent.firstChild.nodeValue = text;
			}
		} else if (text) {
			parent.appendChild(document.createTextNode(text));
		}
	}
}

function ajax_SetTextNodeById(id, text) {
	var el = document.getElementById(id);
	if (el) ajax_SetTextNode(el, text);
}

function ajax_GetTextNode(parent) {
	//alert(BROWSER.OP);
	if (parent) {
		//alert('['+parent.firstChild.nodeValue+']');
		if (parent.firstChild) {
			return parent.firstChild.nodeValue;
		} else {
			return '';
		}
	} else {
		return '';
	}
}

function ajax_GetTextNodeById(id) {
	var el = document.getElementById(id);
	if (el) {
		return ajax_GetTextNode(el);
	} else {
		return '';
	}
}

/**
 * setzt den Wert eines Formular-Elements ermittelt durch seine ID
 * @param {string} id
 * @param {string} value
 * @return (Node) 
 */
function jkSetNodeValueById(id, value) {
	var el = document.getElementById(id);
	if (el) el.value = value;
	return el;
}

/**
 * ermittelt den Wert eines Formular-Elements durch seine ID
 * @param {string} id
 * @return (string) 
 */
function jkGetNodeValueById(id) {
	
	if (el = document.getElementById(id)) {
		return el.value;
	} else {
		return '';
	}
	
}

function cBrowser() {
	this.OP = false;
    this.DOM = false;
    this.IE = false;
    this.Version = 0;
    
	if (window.opera) this.OP = true;
	if(document.getElementById) {
		this.DOM = true;
	}
	if(document.all && !this.OP) {
		this.IE = true;
		var arVersion = navigator.appVersion.split("MSIE");
		//this.Version = parseFloat(arVersion[1]);
		if (document.documentMode) {  
			// Internet Exploter 8
			this.Version = document.documentMode; // documentMode = 8
		} else {
			// Internet Explorer 5-7
			this.Version = 5; //setzt sozusagen den Quirks-Modus
			if (document.compatMode) {
				if (document.compatMode == "CSS1Compat") {
					this.Version = 7; // IE7 Modus
				}
			}
		}
	
		//alert('IE: ' + this.Version);
	}
}
