/*
	Cross Browser Eigenschaften zur Verfügung stellen
	Insbesondere fehlende Funktionen des IE im Mozilla simulieren
*/

/*
	isIE Variable initialisieren
	Array Objekt erweitern
*/
function crossBrowserLib() {
	isIE=false;
  	if (navigator.appVersion.indexOf("MSIE") != -1) isIE = true;
 
}

// Returns the version of Internet Explorer or a -1
// (indicating the use of another browser).
crossBrowserLib.prototype.getInternetExplorerVersion=function() {
  var rv = -1; // Return value assumes failure.
  if (navigator.appName == 'Microsoft Internet Explorer')
  {
    var ua = navigator.userAgent;
    var re  = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
    if (re.exec(ua) != null)
      rv = parseFloat( RegExp.$1 );
  }
  return rv;
}


/*
	alle Browser:	 Index eines Elementes im Array
	Übergabe: 
		- Array
		- Element
	Ergebnis: - Position, -1 wenn nicht gefunden
*/
crossBrowserLib.prototype.getIndexOf=function(arr,el) {
	var index = -1;  
	for(var i = 0; i < this.length; i++)
	{
      		if(this[i] == el)
      		{
        		index = i;break;
      		}
	}
	return index;
}


/** 
	Mozilla: Einen Knoten an der aktuellen Cursor Position einfügen
	Der Knoten wird in der aktuellen selection erzeugt. Die Selection wird gelöscht und ggf.
	werden Textknoten aufgesplittet
	Übergabe: - Knoten, welcher eingefügt werden soll
		  - IFrame-ID
		  
 */
 
 /**
* Mozille and Webkit: insert node at current cursor position
* @param iFrame-ID
* @param node which should be inserted
*/
crossBrowserLib.prototype.insertNodeAtSelection = function(iframeId,toBeInserted,checkObj) {
	if (isIE) return;
	var iframe=document.getElementById(iframeId);
	var iframedoc=iframe.contentWindow.document;		
	var sel = this.getSelection(iframeId);
	var range = this.createRange(iframeId,sel);
	// remove the current selection
	sel.removeAllRanges();
	range.deleteContents();
	var node = range.startContainer;
	var pos = range.startOffset;
	range = this.createRange(iframeId);

	if (!node) {
			iframedoc.body.appendChild(toBeInserted);	
			return true;		
	}
	switch (node.nodeType) {
	    case 3: // Node.TEXT_NODE
		if (checkObj && eipEditor.findObject(node)) {		// not allowed to insert something inside Powerslave text objects
				iframedoc.body.appendChild(toBeInserted);	
				return true;			
			}
		// we have to split it at the caret position.
		if (toBeInserted.nodeType == 3) {
			// do optimized insertion
			node.insertData(pos, toBeInserted.data);
			range.setEnd(node, pos + toBeInserted.length);
			range.setStart(node, pos + toBeInserted.length);
		} else {
			node = node.splitText(pos);
			if (checkObj && eipEditor.findObject(node)) {
				iframedoc.body.appendChild(toBeInserted);	
				return true;			
			}			
			node.parentNode.insertBefore(toBeInserted, node);
			range.setStart(node, 0);
			range.setEnd(node, 0);
		}
		break;
	    case 1: // Node.ELEMENT_NODE
			node = node.childNodes[pos];
			if (!node) {
				iframedoc.body.appendChild(toBeInserted);	
				return true;
			}	
			if (checkObj && eipEditor.findObject(node)) {
				iframedoc.body.appendChild(toBeInserted);	
				return true;			
			}
			node.parentNode.insertBefore(toBeInserted, node);
			range.setStart(node, 0);
			range.setEnd(node, 0);
			break;
		default:	// no node
			iframedoc.body.appendChild(toBeInserted);	
			return true;
	}
	sel.addRange(range);
	return true;
}
/*
	Ein Knoten mit einer speziellen ID suchen 
	Übergabe: - aktueller Knoten
		  - ID
	Ergebnis: - Objekt, false
*/
crossBrowserLib.prototype.findParentElementByID=function(node,id) {
	if (node.id==id) return node;
	if (node.parentNode) return this.findParentElementByID(node.parentNode,id);
	return false;
}
/*
	Einen speziellen Knoten suchen 
	Übergabe: - aktueller Knoten
		  - zu suchenden Knoten
	Ergebnis: - Objekt, false
*/
crossBrowserLib.prototype.findParentElementByNode=function(node,pnode) {
	if (node==pnode) return node;
	if (node.parentNode) return this.findParentElementByNode(node.parentNode,pnode);
	return false;
}
/*
	Ein Knoten mit einem speziellen Tagnamen suchen 
	Übergabe: - aktueller Knoten
		  - Tagname
	Ergebnis: - Objekt, false
*/
crossBrowserLib.prototype.findParentElementByTagName=function(node,tagName) {
	if (node.tagName==tagName) return node;
	
	if (node.parentNode) return this.findParentElementByTagName(node.parentNode,tagName);
	return false;
}
/*
	Ein Knoten mit einem speziellen Namen suchen 
	Übergabe: - aktueller Knoten
		  - Tagname
	Ergebnis: - Objekt, false
*/
crossBrowserLib.prototype.findParentElementByName=function(node,name) {
	if (node.name==name) return node;
	if (node.parentNode) return this.findParentElementByName(node.parentNode,name);
	return false;
}
/*
	Ein Knoten mit einem speziellen Attributwert suchen 
	Übergabe: - aktueller Knoten
		  - Wert
		  - Attributname
	Ergebnis: - Objekt, false
*/
crossBrowserLib.prototype.findParentElementByAttribute=function(node,value,attr) {
	if (node.getAttribute(attr)==value) return node;
	if (node.parentNode) return this.findParentElementByAttribute(node.parentNode,value,attr);
	return false;
}
/*
	Ein Knoten mit einer speziellen type suchen 
	Übergabe: - aktueller Knoten
		  - Typ
	Ergebnis: - Objekt, false
*/
crossBrowserLib.prototype.findParentElementByType=function(node,type) {
	try { if (node.getAttribute("type")==type) return node; } catch (e) { }
	if (node.parentNode) return this.findParentElementByType(node.parentNode,type);
	return false;
}
/*
	Mozilla: outerHTML lesen vom Internet Explorer simulieren.
	Wichtig: Erweitern vom HTMLTag Objekt funktioniert nicht zuverlässig! => diese Lösung anwenden
	Änderung: 07.10.2006: getestet und Bugs gefixt
	Übergabe: - Knoten
	Ergebnis: - HTML
*/
crossBrowserLib.prototype.getOuterHTML=function(node)
{	
	if (isIE) return node.outerHTML;
	var emptyElements = {
		HR: true, BR: true, IMG: true, INPUT: true
	};
	var specialElements = {
		TEXTAREA: true
	};
	var html = '';
	
	switch (node.nodeType) {
	case node.ELEMENT_NODE:
		html += '<';
		html += node.nodeName;
		if (!specialElements[node.nodeName]) {
		for (var a = 0; a < node.attributes.length; a++)
		  html += ' ' + node.attributes[a].nodeName.toUpperCase() +
		          '="' + node.attributes[a].nodeValue + '"';
		html += '>';
		if (!emptyElements[node.nodeName]) {
		  html += node.innerHTML;
		  html += '<\/' + node.nodeName + '>';
		}
		}
		else switch (node.nodeName) {
		case 'TEXTAREA':
		  for (var a = 0; a < node.attributes.length; a++)
		    if (node.attributes[a].nodeName.toLowerCase() != 'value')
		      html += ' ' + node.attributes[a].nodeName.toUpperCase() +
		              '="' + node.attributes[a].nodeValue + '"';
		    else
		      var content = node.attributes[a].nodeValue;
		  html += '>';
		  html += content;
		  html += '<\/' + node.nodeName + '>';
		  break;
		}
		break;
	case node.TEXT_NODE:
		html += node.nodeValue;
		break;
	case node.COMMENT_NODE:
		html += '<!' + '--' + node.nodeValue + '--' + '>';
		break;
  }
  return html;
}

/* Mozilla+IE: Selection eines IFrames lesen
	Übergabe: - IFRAME-ID
	Ergebnis: - selection
*/
crossBrowserLib.prototype.getSelection = function(iframeId) {
	if (iframeId=="") {
		if (isIE) return getSelection.selection;
		else return window.getSelection();		
	}
	var node=document.getElementById(iframeId);
	if (isIE) return node.contentWindow.document.selection;
	else return node.contentWindow.getSelection();
};

/* Mozilla+IE: Range einer Selection 
	Übergabe: 
		- IFRAME-ID	
		- Optional: Selection
	Ergebnis: - Range
*/
crossBrowserLib.prototype.createRange = function(iframeId,sel) {
	if (isIE) {
		return sel.createRange();
	} else {
		try {
			if (sel) return sel.getRangeAt(0);
		} catch (e) {  	}
		var doc;
		if (iframeId=="") doc=document; else  doc=document.getElementById(iframeId).contentWindow.document;	
		//this.focusEditor();
		return doc.createRange();
	}
};

/** Mozilla+IE: HTML Code einfügen an der aktuellen Position
	entspricht range.pasteHTML(html); beim IE
	Übergabe:	- IFRAME-ID
			- HTML
 */
crossBrowserLib.prototype.insertHTML = function(iframeId,html,sel,range,checkObj) {
	html=html.replace(/\n/g,"");
	
	if(!sel)
		var sel = this.getSelection(iframeId);
	if(!range)
		var range = this.createRange(iframeId,sel);
//	alert("Range:"+range.htmlText);
	if (isIE) {
		range.pasteHTML(html);

	} else {
		// construct a new document fragment with the given HTML
		var fragment = document.createDocumentFragment();
		var div = document.createElement("div");
		div.innerHTML = html;
		while (div.firstChild) {
			// the following call also removes the node from div
			fragment.appendChild(div.firstChild);
		}
		var node = this.insertNodeAtSelection(iframeId,fragment,checkObj);	// this also removes the selection

	}
}
/*
	IE+Mozilla: Neuen Knoten an den DOM Tree von "document" hängen
	Übergabe: - Tagname
		  - Attributestring
	Ergebnis: - Knoten
*/
crossBrowserLib.prototype.newNode = function(tag,attr)
{
   var n = document.createElement("div");
   n.innerHTML = '<'+tag+' '+attr+'>';
   var e = n.firstChild;
   document.body.appendChild(e);
   return e;
}
/*
IE+Mozilla:Koordinaten eines Knotens ermitteln
	Übergabe: - Knoten
	Ergebnis: - Objekt mit 
			.x
			.y
*/
crossBrowserLib.prototype.getPageCoords=function(element) {
	var coords = { x: 0, y: 0};
	while (element) {
		coords.x += element.offsetLeft;
		coords.y += element.offsetTop;
		element = element.offsetParent;
	}
	return coords;
}

/*
	Mozilla,IE:alle Kinderknoten eines Knotens lesen aber Textknoten nicht zurückliefern
	entspricht node.childNodes im IE
	Übergabe: - Knoten
	Ergebnis: - Knotenliste
*/
crossBrowserLib.prototype.getChilds=function(node) {
	var i=0,k=0;	
	if (isIE) return node.childNodes;
	if (!node.childNodes) return null;	
	var childs=[];
	for(i=0;i<node.childNodes.length;i++) {
		if (node.childNodes[i].nodeType==1) childs[k++]=node.childNodes[i];
	}
	return childs;
}

/*
	Mozilla: OuterHTML setzen
	Übergabe:
		- Dokument
		- Knoten
		- HTML
	
*/
crossBrowserLib.prototype.setOuterHTML=function(node,html) 
{
	if (isIE) {
		node.outerHTML=	html;
		return;
	}
	var range = document.createRange();
	range.selectNode(node);
	var docFrag = range.createContextualFragment(html);
	node.parentNode.replaceChild(docFrag, node);
}
/*
	Parent Element einer Range ermitteln
	Übergabe: - Range
	Ergebnis: - Parent Element im DOM-Tree
*/
crossBrowserLib.prototype.rangeParent=function(range) {
	if (isIE) return range.parentElement();
//	var p = range.commonAncestorContainer;
	var p = range.startContainer;
	
	while (p.nodeType == 3) p = p.parentNode;
	return p;
}
/*
getElementsByName is buggy in IE, daher diese Funktion
Uebergabe:
	- Elementname
	- Startknoten
*/
crossBrowserLib.prototype.getElementsByName=function(name,node,top) {	
	if (!isIE && !node) return document.getElementsByName(name);	
	if (!top) {
		if (!node) var node=document.body;
		this.res=[];
	}
	if (isIE && node.name==name)  this.res[this.res.length]=node;
	try {
		if (!isIE && node.getAttribute("name")==name) this.res[this.res.length]=node;
	} catch (e) { }
	var childs=this.getChilds(node);
	if (childs) {
		for(var i=0;i<childs.length;i++){
			var child=childs[i];
			this.getElementsByName(name,child,true);
		}
	}
	return this.res;		
}
/*
	Eventobjekt zurückliefern:
	Übergabe: - Eventobjekt aus Parameterübergabe (nur Gecko), IE: null
		  - alle relevanten IFrames
	Ergebnis: - Eventobjekt mit:
		. clientX,ClientY
		. absX,absY
		. iframePos.x/y
		. target
		. targetIframe
		
*/
crossBrowserLib.prototype.getEvent=function(evt,iframes) {	
                if (!isIE) { event=evt; }
                if (!event) var event=top.window.event;
                var iframepos={x:0,y:0};
                // IE: kein event -> alle iframes durchgehen und Event dort suchen!
                if(!event) {
			if (iframes) for(var i=0;i<iframes.length;i++) {
				var iframe=iframes[i];
				var win=iframe.contentWindow;
				if (win.event) {
					var iframepos=crossBrowserLib.getPageCoords(iframe);
					var event=win.event;
					event.targetIframe=iframe;
					event.iframePos=iframepos;
					return event;
				}
			}
                }
                if (isIE) {
                	if (!event) event={iframePos:0};
			event.iframePos=iframepos;
			event.targetIframe=null;
                	return event;
                }
                if (event.target) {	// Mozilla/Firefox
	                var node=event.target;
      	         	if (iframes) while(node=node.parentNode) { 
      	         		for(var i=0;i<iframes.length;i++) {
 					var iframe=iframes[i];
      	         	 		if (node==iframe.contentWindow.document) {
      	         	 			var iframepos=crossBrowserLib.getPageCoords(iframe);
      	         	 			event.iframePos=iframepos;
      	         	 			event.targetIframe=iframe;
      	         	 			return event;
      	         	 		}
      	         	 	}
      	         	 }
		}
		event.iframePos=iframepos;
		event.targetIframe=null;
                return event;		
}
/*
	Eventhandler für alle Iframe registrieren
	Übergabe: - Name (z.b. mousemove, mousedown etc. ) - ohne "on" am Anfang
		  - Eventhandler-Funktion
		  - Iframes
*/
crossBrowserLib.prototype.registerEventhandler=function(name,func,iframes,notop,enableSelection) {	
		doc=document;
		if (!notop) if (top.document) doc=top.document;
	//	alert(enableSelection);
         	if (!enableSelection) doc.onselectstart = function(){event.returnValue=false;return false;};
         	doc.ondragstart =function(){event.returnValue=false;return false;};   
         	doc.ondrag =function(){event.returnValue=false;return false;};   
		if (isIE) {
			if(!this.save_eventhandler) this.save_eventhandler=[];
			this.save_eventhandler[name]=doc["on"+name];

			doc["on"+name]=func;
		} else {
			 doc.addEventListener(name,func,true);
        	}         					
		if (!iframes) return;
		for(var i=0;i<iframes.length;i++) {
			// MouseMove
			var iframe=iframes[i];
			doc=iframe.contentWindow.document;		
         		if (!enableSelection)  doc.onselectstart = function(){event.returnValue=false;return false;};
         		doc.ondragstart =function(){event.returnValue=false;return false;};   
         		doc.ondrag =function(){event.returnValue=false;return false;}; 
			if (isIE) {
				if(!iframe.save_eventhandler) iframe.save_eventhandler=[];
				iframe.save_eventhandler[name]=doc["on"+name];
				doc["on"+name]=func;
			}
			else doc.addEventListener(name,func,true);
		}
}
/*
	Eventhandler für alle Iframe entfernen
	Übergabe: - Name (z.b. mousemove, mousedown etc. ) - ohne "on" am Anfang
		  - Eventhandler-Funktion
		  - Iframes
*/
crossBrowserLib.prototype.unregisterEventhandler=function(name,func,iframes,notop) {	
		doc=document;
		if (!notop) if (top.document) doc=top.document;
   	   		doc.onselectstart = null;
         	doc.ondragstart =function(){  if (event) event.returnValue=false;return false;};   
         	doc.ondrag =function(){  if (event) event.returnValue=false;return false;};   
		if (isIE) {
			try {
				doc["on"+name]=this.save_eventhandler[name];
			} catch (e) { }
		} else {
			 doc.removeEventListener(name,func,true);
        	}         					
				
		if (!iframes) return;
		for(var i=0;i<iframes.length;i++) {
			// MouseMove
			var iframe=iframes[i];
			doc=iframe.contentWindow.document;		
 			doc.onselectstart = doc.ondragstart = null;
			if (isIE) {
				if(iframe.save_eventhandler) {
					doc["on"+name]=iframe.save_eventhandler[name];
				}
			}
			else doc.removeEventListener(name,func,true);
		}
}
/*
	Ein Formularelement hinzufügen
	Übergabe: - Formularknoten
		  - Dokumentknoten
		  - Typ (z.B. hidden)
		  - Name
		  - Wert
*/
crossBrowserLib.prototype.addFormElement=function(form,doc,type,name,value) {	
	var node = doc.createElement("input");
	node.setAttribute("type",type);
	node.setAttribute("name",name);
	node.setAttribute("value",value); 

	form.appendChild(node);	
	return node;
}


/**
 * Recursive function that scans for INPUT fields in a page taking into account
 * frames and iframes that do not answer for getElementsByTagName
 */
crossBrowserLib.prototype.getElementsByTagNameDeep=function(page,name)
{	
	//frames in the document are implemented in this way:
	//FRAMESET=>FRAME=>#document
	//HTMLFrameElement=>HTMLDocument
	
	var r = [];
	if(page == undefined)
		return r;
	var frames = page.getElementsByTagName("frame");
	for(var i = 0; i < frames.length; i++)
	{				
		var frame = frames[i];
		try
		{
			var q = this.getElementsByTagNameDeep(frame.contentDocument,name);
			if(q.length != 0)
				for(var k = 0; k < q.length;++k)
					r.push(q[k]);
		}
		catch(e)
		{
			alert("Exception getElementsByTagNameDeep: "+ e);
		}
	}	
	
	var frames = page.getElementsByTagName("iframe");
	for(var i = 0; i < frames.length; i++)
	{				
		var frame = frames[i];
		try
		{
			var q = this.getElementsByTagNameDeep(frame.contentDocument,name);
			if(q.length != 0)
				for(var k = 0; k < q.length;++k)
					r.push(q[k]);
		}
		catch(e)
		{
			alert("Exception getElementsByTagNameDeep: "+ e);
		}
	}	
	
	var q = page.getElementsByTagName(name)
	if(q.length != 0)
		for(var k = 0; k < q.length;++k)
			r.push(q[k]);
		
	return r;
}
/*
	wichtig wg. DOCTYPE
	scrollTop lesen
	Optional: Übergabe vom Dokument
*/
crossBrowserLib.prototype.scrollTop=function(doc) {

	var scrollPos;
	if (!doc) doc=document;
	if (typeof doc.compatMode != 'undefined' &&
		 doc.compatMode != 'BackCompat') {
	   scrollPos = doc.documentElement.scrollTop;
	   if (typeof doc.body != 'undefined' && doc.body.scrollTop>0) scrollPos=doc.body.scrollTop;
	}
	else if (typeof doc.body != 'undefined') {
	   scrollPos = doc.body.scrollTop;
	}		

	else if (typeof window.pageYOffset != 'undefined') {
	   scrollPos = window.pageYOffset;
	}

//alert(scrollPos);
	return scrollPos;
}


crossBrowserLib.prototype.scrollLeft=function(doc) {
	var scrollPos;
	if (!doc) doc=document;
	if (typeof doc.compatMode != 'undefined' &&
		 doc.compatMode != 'BackCompat') {
	   scrollPos = doc.documentElement.scrollLeft;
	   if (typeof doc.body != 'undefined' && doc.body.scrollLeft>0) scrollPos=doc.body.scrollLeft;
	}	
	else if (typeof doc.body != 'undefined') {
	   scrollPos = doc.body.scrollLeft;
	}	
	if (typeof window.pageXOffset != 'undefined') {
	   scrollPos = window.pageXOffset;
	}
	return scrollPos;
}


/*
	Fensterinformationen auslesen: Breite, Höhe, Scrollwerte
	Optional: Übergabe vom Dokument	
	Ergebnis: Objekt mit
	. scrollLeft
	. scrollTop
	. width
	. height
	
*/
crossBrowserLib.prototype.windowInfo=function(doc) {
	var winH,winW;
	if (!doc) doc=document;
	if (typeof window.pageYOffset != 'undefined') {
		 winH=window.innerHeight;
		 winW=window.innerWidth;	   
	}
	else if (typeof document.compatMode != 'undefined' &&
		 document.compatMode != 'BackCompat') {
		winH=document.documentElement.offsetHeight;
		winW=document.documentElement.offsetWidth;	 
	}
	else if (typeof document.body != 'undefined') {
		winH=document.body.offsetHeight;
		winW=document.body.offsetWidth;	
	}
	var obj={width:winW,height:winH,scrollLeft:this.scrollLeft(doc),scrollTop:this.scrollTop(doc)};
	return obj; 
}

crossBrowserLib.prototype.isWebKit=function() {
    return RegExp(" AppleWebKit/").test(navigator.userAgent);
}

