
/************************ BEGIN Globals WebFeatureKit *************************/

/*
Web 2.0 Features Toolkit - ScriptLib
Author: David Bary, Date: 13.04.2006
Rights: TIMETOACT Software & Consulting GmbH
Version: 0.99
Last Modified: 13.04.2006
*/

	// 'getChildObjectsByClass' returns the childs (only direct first level childs) of an object (default is body) as object array, if they have the specified class as attribute
	// childClass[, startObj[, childTagName]]
	// childClass	-> name of the class, that the result childs must have assigned as attribute (case insensitive)
	// startObj		-> (optional, default:document.body) parent object and start point for the search of childs, that should be returned
	// childTagName	-> (optional, default:all tags are compared) if set, returns only childs with this tag name ( e.g. "div" returns only div-Tags that have the corresponding className als value for the class attribute
	function getChildObjectsByClass(childClass, startObj, childTagName) {
		startObj = ((getChildObjectsByClass.arguments.length>1) && (typeof getChildObjectsByClass.arguments[1] == "object"))?startObj:document.body;
		childTagName = getChildObjectsByClass.arguments.length>2?childTagName:"";
		var resultChilds = new Array();
		var cnt = 0;
		var allChilds = new Array();
		var childAttributeList = new Array();
		var childAttribute = "";
		if(startObj) {
			if(childTagName != "") {
				allChilds = startObj.getElementsByTagName(childTagName);
			} else {
				allChilds = startObj.childNodes;
			}
			for(var n = 0; n < allChilds.length; n++) {
				if(allChilds[n].nodeType == 1) {
					childAttributeList = allChilds[n].className;
					if(childAttributeList) {
						childAttributeList = childAttributeList.split(" ");
						for(var i = 0; i<childAttributeList.length; i++) {
							childAttribute = childAttributeList[i];
							if(childAttribute.toLowerCase() == childClass.toLowerCase()) {
								resultChilds[cnt] = allChilds[n];
								cnt++;
								i = childAttributeList.length;
							}
						}
					}
				}
			}
		}
		return resultChilds;
	}
	

	function getAllChildsByTagName(startObj, childTagName, isChildObj) {
		var childsArray = new Array();
		if(startObj.nodeType == 1) {
			if(isChildObj == true) {
				if(childTagName != "") {
					if(childTagName.toLowerCase() == startObj.nodeName.toLowerCase()) childsArray.push(startObj);
				}
				else {
					childsArray.push(startObj);
				}
			}
			for(var c = 0; c < startObj.childNodes.length; c++) {
				childsArray = childsArray.concat(getAllChildsByTagName(startObj.childNodes[c], childTagName, true));
			}
		}
		return childsArray;
	}

	function getAllObjectsByClass(childClass, startObj, childTagName) {
		startObj = ((getAllObjectsByClass.arguments.length>1) && (typeof getAllObjectsByClass.arguments[1] == "object"))?startObj:document.body;
		childTagName = getAllObjectsByClass.arguments.length>2?childTagName:"";
		var resultChilds = new Array();
		var cnt = 0;
		var allChilds = new Array();
		var childAttribute = "";
		if(startObj) {
			allChilds = getAllChildsByTagName(startObj, childTagName);
			for(var n = 0; n < allChilds.length; n++) {
				if(allChilds[n].nodeType == 1) {
					childAttributeList = allChilds[n].className;
					if(childAttributeList) {
						childAttributeList = childAttributeList.split(" ");
						for(var i = 0; i<childAttributeList.length; i++) {
							childAttribute = childAttributeList[i];
							if(childAttribute.toLowerCase() == childClass.toLowerCase()) {
								resultChilds[cnt] = allChilds[n];
								cnt++;
								i = childAttributeList.length;
							}
						}
					}
				}
			}
		}
		return resultChilds;
	}
	

	function addAttributesToQueryTexts(searchVariable, caseOption, tagName, attributesNameArray, attributesValueArray, startNode, parentNodeObj) {
		//style problems with table tags that have no border attribute and no style which sets the td border for this table-> in the new node the table's td's may have a border!!!
		var queryStringA = new Array();
		if(typeof searchVariable == "string") {
			if(searchVariable == "") return startNode;
			var queryString = searchVariable;
			var queryStringLen = queryString.length;
		} else if(typeof searchVariable == "object") {
			queryStringA = searchVariable;
			if(arrayIsEmpty(queryStringA)) return startNode;
		}
		if(tagName == "") tagName = "span";
		var tag, val, restVal, cnt, startString, endString, originalText, maxHits, attributeValue;
		var elementStartNodeObj, elementNodeObj, elementEndNodeObj, parentNodeObjReturn, newParent, baseNode;
		var childNodesArray = new Array();
		if(startNode.nodeType == 3) {
			childNodesArray[0] = startNode;
		} else {
			var childNodesArray =  startNode.childNodes;
		}
		for( var i = 0; i < childNodesArray.length; i++ ) {
			tag = childNodesArray[i];
			tn = tag.nodeName.toLowerCase();
			if(tag.childNodes.length == 0) {
				val = tag.nodeValue;
				if( (tag.nodeType == 3) && (val != null) && (val != "") ) { // if it is a textnode and contains some text, go and process that text
					if(typeof searchVariable == "string") {
						restVal = val;
						if(caseOption == "1" || caseOption == 1 ) {
							nextStartPos = restVal.indexOf(queryString);  //search caseinsensitive for the query string
						} else {
							nextStartPos = restVal.toLowerCase().indexOf(queryString.toLowerCase());  //search caseinsensitive for the query string
						}
						cnt = 0;
						maxHits = 1000; // for performance reasons, not more than this amount of replacements will be proceeded in one textnode
						while(nextStartPos >= 0 && cnt < maxHits) { // if the querystring was found, go on. As long as you didn't reach the maximum hit amount
							globalHitsCnt++;
							if(cnt>0) {
								startString = ""; // if more than on hit was found, the last endstring contained all neccesary text up to the next hit, so no start string is needed
							} else {
								startString = restVal.substring(0,nextStartPos); // get the text before the first hit
							}
							endString = restVal.substring(nextStartPos + queryStringLen,restVal.length + 1); // get the text behind the hit
							if(cnt == (maxHits - 1)) { // if the last allowed replacement string was found (maxHits reached) the endstring must contain the complete remaining string, not just up to the next hit
								endString = restVal;
							}
							// because of lowercase compare, we must use the original text, to maintain the correct lower- and uppercase characters:
							originalText = restVal.substr(nextStartPos,queryStringLen); // extract the querystring, with the correct case
							if(caseOption == "1" || caseOption == 1  ) {
								nextStartPos = endString.indexOf(queryString); // find next hit, search caseinsensitive for the query string
							} else {
								nextStartPos = endString.toLowerCase().indexOf(queryString.toLowerCase()); // find next hit, search caseinsensitive for the query string
							}

//							nextStartPos = endString.toLowerCase().indexOf(queryString.toLowerCase()); // find next hit
							restVal = endString; // assign the remaining string for further searches in the restVal
							
							if(startString!="") elementStartNodeObj = document.createTextNode(startString); // create a textnode with the startstring
						
							elementNodeObj = document.createElement(tagName); // here we create the new element, that will contain the querystring and the attributes
							elementTextNodeObj = document.createTextNode(originalText); // create the textnode with the original text
							elementNodeObj.appendChild(elementTextNodeObj); // append the textnode to the new element
							if(nextStartPos >= 0) {
								elementEndNodeObj = document.createTextNode(endString.substring(0,nextStartPos));
							} else {
								elementEndNodeObj = document.createTextNode(endString);
							}
							for(var e = 0; e < attributesNameArray.length; e++) { // for all defined attributes in the user's attribute array...
								if(attributesNameArray[e] == "className" || attributesNameArray[e] == "class") { // special case for class attribute, IE and other Browsers do need different spellings
									elementNodeObj.setAttribute("className", attributesValueArray[e]); //standard - for other browser
									elementNodeObj.setAttribute("class", attributesValueArray[e]); //standard - for other browser
								}
								else {
									attributeValue = attributesValueArray[e];
									attributeValue = attributeValue.replace(/{%QUERY%}/,originalText); // it is possible to use the query string in the attribute value, by using the replacement tag {%QUERY%} in the value
									attributeValue = attributeValue.replace(/{%NUMBER%}/,globalHitsCnt); // it is possible to use the query string in the attribute value, by using the replacement tag {%NUMBER%} in the value
									elementNodeObj.setAttribute(attributesNameArray[e], attributeValue); // assign value
								}
							}
							if(startString != "") parentNodeObj.appendChild(elementStartNodeObj);
							parentNodeObj.appendChild(elementNodeObj);
							if(endString!="") parentNodeObj.appendChild(elementEndNodeObj);
							cnt++;
						}
						if(cnt==0) { // the querystring was not found, so "copy" the node by creating a new with the same properties
							elementTextNodeObj = tag.cloneNode(true);
							parentNodeObj.appendChild(elementTextNodeObj);
						}
					} // END if(queryStringA.length == 1)
					else {
						baseNode = tag.cloneNode(true);
						baseNodeCopy = parentNodeObj.cloneNode(true);//document.createElement(parentNodeObj.nodeName);
						for(var q = 0; q < queryStringA.length; q++) {
							queryString = queryStringA[q];
							baseNode = addAttributesToQueryTexts(queryString, caseOption, tagName, attributesNameArray, attributesValueArray, baseNode, baseNodeCopy);
							baseNodeCopy = baseNode.cloneNode(false);
						}
						parentNodeObj = baseNode.cloneNode(true);
					}
				} // END if( (tag.nodeType == 3) && (val != null) && (val != "") )
				else if(tag.nodeType == 1) {
					elementNodeObj = tag.cloneNode(true);
					parentNodeObj.appendChild(elementNodeObj);
				}
			} //END  if(tag.childNodes.length == 0)
			else {
				if( (tn != "input") && (tn != "textarea") && (tn != "select") ) {
					newParent = tag.cloneNode(false);
					newParent = addAttributesToQueryTexts(searchVariable, caseOption, tagName, attributesNameArray, attributesValueArray, tag, newParent);
				} else {
					// inputs and textarea fields do not make so good with html as content in firefox, IE accepts html and highlights correct, ...
					// IE also submits this correct, but to support both, those elements are excluded from modification
					newParent = tag.cloneNode(true);
				}
				parentNodeObj.appendChild(newParent);
			}
		}
		return parentNodeObj;
	}

	function getParameterValue(parameterName, returnMultiValue) {
		var queryString = window.location.search;
		if(queryString == "") return "";
		var parameterArray = new Array();
		var parameterValue = new Array();
		var currentName, currentValue, delimiterPos;
		var cnt = 0;
		parameterArray = queryString.split("&");
		for(var n=0; n<parameterArray.length; n++) {
			delimiterPos = parameterArray[n].indexOf("=");
			if(delimiterPos > -1) {
				currentName = parameterArray[n].substring(0,delimiterPos);
				currentValue = parameterArray[n].substring(delimiterPos+1);
			} else {
				currentName = parameterArray[n];
				currentValue = "";
			}
			if(currentName == parameterName) {
				parameterValue[cnt] = currentValue;
				cnt++;
				if(!returnMultiValue) {
					n = parameterArray.length+1;
					parameterValue = parameterValue[0];
				}
			}
		}
		return parameterValue;
	}
	
	function arrayIsEmpty(array) {
		var ret = true;
		for(a in array) {
			if(a!="") ret = false;
		}
		return ret;
	}

	function createBackupOfNode(originalNode) {
		var backupNodeVariable = originalNode.cloneNode(true);
		return backupNodeVariable;
	}
	
	function restoreNodeBackup(originalNode, backupNode) {
		originalNode.parentNode.replaceChild(backupNode,originalNode);
	}

	var backupNodesArray = new Array();
	var replacedNodesArray = new Array();
	var originalStatus = new Array();
	function restoreOriginal() {
		for(var n=0; (n < replacedNodesArray.length) && (n < backupNodesArray.length); n++) {
//			if(originalStatus[n] == 2) {
				originalNode = replacedNodesArray[n];
				backupNode = backupNodesArray[n];
				restoreNodeBackup(originalNode, backupNode);
				replacedNodesArray[n] = backupNode;
				originalStatus[n] = 1;
//			}
		}
	}

	var highlightStatus = 0;
	function switchHighlight() {
		highlightStatus = (document.getElementsByName('highlightStatus')[0].checked==true?1:0);
		if(highlightStatus == 1) highlightText()
		else restoreOriginal();
	}
	
	var highlightCaseSensitivity = 0;
	function switchCaseSensitivity() {
		highlightCaseSensitivity = (document.getElementsByName('highlightCaseSensitivity')[0].checked==true?1:0);
		highlightText();
	}
	
	function highlightQuery() {
		globalHitsCnt = 0;
		var startObj, blankObj, parentObj, newParent;
		var query = new Array();
		query = getParameterValue("Highlight", false);
		if(query == "") return;
		restoreOriginal();
		var attributesNameArray = new Array("class");
		var attributesValueArray = new Array("wftContentMarker");
		var objArray = new Array();
		objArray = getAllObjectsByClass("Content");
		
		for(var h = 0; h<objArray.length; h++) {
			startObj = objArray[h];
			if(startObj != null && typeof startObj != "undefined" && startObj != "undefined") {
				blankObj = startObj.cloneNode(false);
				parentObj = addAttributesToQueryTexts(query, 0, 'highlight', attributesNameArray, attributesValueArray, startObj, blankObj);
				if(parentObj != false) {
					if(!originalStatus[h]) originalStatus[h] = 0;
					if(originalStatus[h] == 0) { // backup should only be made once!
						backupNodesArray[h] = createBackupOfNode(startObj);
					}
					startObj.parentNode.replaceChild(parentObj, startObj);
					replacedNodesArray[h] = parentObj;
					originalStatus[h]++;
				}
			}
		}
	}
	
	function highlightText() {
		globalHitsCnt = 0;
		var startObj, blankObj, parentObj, newParent;
		var query = new Array();
		query = document.getElementsByName("Highlight")[0].value;
		if(query == "") return;
		restoreOriginal();
		var attributesNameArray = new Array("class");
		var attributesValueArray = new Array("wftContentMarker");
		var objArray = new Array();
		objArray = getAllObjectsByClass("Content");
		
		for(var h = 0; h<objArray.length; h++) {
			startObj = objArray[h];
			if(startObj != null && typeof startObj != "undefined" && startObj != "undefined") {
				blankObj = startObj.cloneNode(false);
				parentObj = addAttributesToQueryTexts(query, highlightCaseSensitivity, 'highlight', attributesNameArray, attributesValueArray, startObj, blankObj);
				if(parentObj != false) {
					if(!originalStatus[h]) originalStatus[h] = 0;
					if(originalStatus[h] == 0) { // backup should only be made once!
						backupNodesArray[h] = createBackupOfNode(startObj);
					}
					startObj.parentNode.replaceChild(parentObj, startObj);
					replacedNodesArray[h] = parentObj;
					originalStatus[h]++;
				}
			}
		}
	}

/* ENDOF Web 2.0 Features Toolkit - ScriptLib */

/************************ END Globals WebFeatureKit *************************/
