// start info
if(typeof jsReport != 'undefined'){
	jsVersion = new Array(
	/*Name			=*/ 'String Functions',
	/*Version 		=*/ '1.11',
	/*Date 			=*/ 20030226,
	/*Author		=*/ 'Maurice van Creij',
	/*ProjectCode	=*/ 'l1_stringfuncs',
	/*Summary		=*/ 'Manipulate strings, arrays and csv\'s',
	/*Dependencies	=*/ new Array('stringfuncs.js'),
	/*Browsers		=*/ new Array('NS','MO','IE','OP'),
	/*Changes		=*/ new Array(
					  	'1.11: Expanded "array2csv" and "csv2array" with "matrix2csv" and "csv2matrix" functions.',
					  	'1.1: compareString() now weighs the length differences in the comparison.',
					  	'1.0: A modular version was compiled from code-scraps'
					  	),
	/*Usage			=*/ new Array(
						'<script language="JavaScript" src="/~wmittens/includes/stringfuncs.js" type="text/javascript"></script>'
					  	)
	)
}else{
// end info

	// string2array manipulation
		function isElementOfArray(sItem,sArray){
			// returns the index of an item in an array
			var tellerB=0;
			var booFoundSelfInList = false;
			while(!booFoundSelfInList && tellerB<=sArray.length){
				if(sItem==sArray[tellerB]) booFoundSelfInList=true;
				tellerB=tellerB+1;
			}
			if(tellerB>sArray.length) tellerB=0;
		return tellerB-1;
		}

		function timesInArray(sItem,sArray){
			var intNumber = 0;
			for(var intA=0; intA<sArray.length; intA++){
				if(sArray[intA]==sItem) intNumber+=1;
			}
			return intNumber
		}
		
		function isInArrayOrCSV(sItem,sArray){
			sString = ','+sArray+',';
			sItem = ','+sItem+',';
			if(sString.indexOf(sItem)>-1){return true}else{return false}
		}
		
		function editCsv(csvEdit,strEdit,booAdd){
			var arrEdit = new Array();
			// prepare the csv for replaces
			csvEdit = ',' + csvEdit + ',';
			// add or remove
			if(booAdd){
				// add to CSV
				csvEdit += strEdit + ',';
			}else{
				// split the csv using the replace string as a seperator
				csvEdit = csvEdit.split(','+strEdit+',')+'';
			}
			// trim the limits
			csvEdit = csvEdit.substr(1,csvEdit.length-2);
			// return the new csv
			return csvEdit;
		}

		function csv2array(csvIn,strEol){
			// validate input
			if(typeof(strEol)=='undefined') strEol=',';
			// declarations
			var arrOut = new Array();
			// remove trailing EOF marker
			if(csvIn.substr(csvIn.length-1,1)==strEol) csvIn = csvIn.substr(0,csvIn.length-1);
			// split the array
			arrOut = csvIn.split(strEol);
			// validate entries
			for(var intB=0; intB<arrOut.length; intB++){
				// cure all integers which ended up as strings
				if(!isNaN(arrOut[intB])) arrOut[intB]=arrOut[intB]*1;
			}
			return arrOut;
		}
		
		function array2csv(arrIn,strEol){
			// validate input
			if(typeof(strEol)=='undefined') strEol=',';
			// declarations
			var csvOut = '';
			// for all elements
			for(var intB=0; intB<arrIn.length; intB++){
				csvOut += arrIn[intB] + strEol;
			}
			return csvOut;
		}
		
		function csv2matrix(csvIn,strEol,strEof){
			// validate input
			if(typeof(strEol)=='undefined') strEol=',';
			if(typeof(strEof)=='undefined') strEof=';';
			// declarations
			var arrTemp = new Array();
			var arrOut = new Array();
			// split at end of file markers
			arrTemp = csv2array(csvIn,strEof);
			// split at end of line markers
			for(var intA=0; intA<arrTemp.length; intA++){
				arrOut[intA] = csv2array(arrTemp[intA],strEol);
			}
			return arrOut;
		}
		
		function matrix2csv(arrIn,strEol,strEof){
			// validate input
			if(typeof(strEol)=='undefined') strEol=',';
			if(typeof(strEof)=='undefined') strEof=';';
			// declarations
			var csvOut = '';
			// for all sub arrays
			for(var intA=0; intA<arrIn.length; intA++){
				csvOut += array2csv(arrIn[intA],strEol);
				csvOut += strEof;
			}
			return csvOut;
		}
		
		function reverseArray(arrIn){
			var arrOut = new Array();
		
			tellerB = arrIn.length;
			for(var tellerA=0;tellerA<arrIn.length;tellerA++){
				tellerB -= 1;
				arrOut[tellerB] = arrIn[tellerA];
			}	
			
			return arrOut;
		}
		
			// custom sort sub-functions	
			function sortNumbers(a,b){return a-b}
			function reverseSort(a,b){if(a>b){return -1};if(a<b){return 1};return 0}
			function sortFirstSubArrayElement(a,b){
				if(typeof a[0]!='undefined'){y=a[0]}else{y=a};
				if(typeof b[0]!='undefined'){z=b[0]}else{z=b};
				if(y>z){return -1};if(y<z){return 1};return 0
			} 
		
		// sorting arrays using an order-matrix
		function sortMatrix(arrMatrix,arrOrder){
			aID = new Array();
			bID = new Array();
			
			if(arrOrder[0]!=-1 && arrMatrix.length==arrOrder.length){
				// compile sort array
				for(var intA=0; intA<arrMatrix.length; intA++){
					aID[intA] = new Array(arrOrder[intA],arrMatrix[intA]);
				}
				// invoke bubble-sort
					aID = aID.sort(sortFirstSubArrayElement);
				// compile return array
				for(var intA=0; intA<arrMatrix.length; intA++){
					bID[intA] = aID[intA][1];
				}
			}else{
				//if it didn't work out
				bID = arrMatrix; 
			}
		return bID;
		}		
		
		
	// string manipulation
		function tagStrip(inString){
			tagStart = inString.indexOf("<");
			tagEnd = inString.indexOf(">");
			
			beforeString = inString.substring(0,tagStart);
			afterString = inString.substring((tagEnd+1),inString.length);
			outString = beforeString + " " +afterString;
		return outString;
		}
		
		function cleanString(inString,findString,replaceString){
			// global case insensitive
			rExp = new RegExp(findString,"gi");
			// regExp replace
			outString = inString.replace(rExp, replaceString);
		return outString
		}
		
		function HTMLencode(inStr) { //-- translate all "reserved" characters of a string to HTML equivalents
		outStr=' '; //not '' for a NS bug!
			for (i=0; i < inStr.length; i++) {
				aChar=inStr.substring (i, i+1);
				switch(aChar){
				case '<': outStr += "&lt;"; break; 
				case "'": outStr += "&rsquo;"; break; 
				case ';': outStr += "&#059;"; break; 
				case '>': outStr += "&gt;"; break;
				case ' ': outStr += "&nbsp;"; break; 
				case '	': outStr += "&nbsp;&nbsp;&nbsp;"; break;
				default: outStr += aChar;
				}
			}
		return outStr.substring(1, outStr.length);
		}		
		
		function makeNumber(strIn) {
			var tellerB, strIn;
			var isNumber = true;
			
			for (tellerB = 0; tellerB < strIn.length; tellerB++) {
				// Check if the current character is a number.
				var strTest = strIn.charAt(tellerB);
				if (!( (strTest>="0")&&(strTest<="9")||(strTest=="-") )){isNumber = false}
			}
			
			return strIn*1;
		}
		
		// compare all fields for the searched strong fragment
		function compareString(strSearch,strCompare,arrDelimiters){
			var intFoundLength = 0;
			var fltCompare = 0;
			// prepare both strings
			strSearch = strSearch.toLowerCase();
			strCompare = strCompare.toLowerCase();
			// default delimiter
			if(typeof arrDelimiters == 'undefined') arrDelimiters = new Array(' ');
			// split the fragment up in units according to the given delimiters
			csvFragment = strSearch;
			for(var intA=0; intA<arrDelimiters.length; intA++){
				csvFragment = (csvFragment+'').split(arrDelimiters[intA]);
			}
			arrFragment = (csvFragment+'').split(',');
			// check the existence of each fragment-unit in the compare-string keep score based on occurance and fragment-unit length
			for(var intA=0; intA<arrFragment.length; intA++){
				if(strCompare.indexOf(arrFragment[intA])>-1) intFoundLength += arrFragment[intA].length;
			}
			// calculate the fraction of similar fragment-units in the compare-string
			fltCompare = intFoundLength / strSearch.length;
			// calculate the length difference factor and use it to weigh the scores in favour of similar lengths
			fltLengthCompare = 1-Math.abs((strCompare.length-strSearch.length)/(strCompare.length+strSearch.length));
			// pass it back		
			return fltCompare*fltLengthCompare;
		}
		
		function guessStringLength(strIn,intCharMinWidth,intCharMaxWidth){
			var fltApproxLength = 0;
			var fltRelWidth = 1.0;
			// calculate the values to measure with
			var fltAvgCharWidth = (intCharMaxWidth+intCharMinWidth)/2;
			var fltCorMax = intCharMaxWidth / fltAvgCharWidth; 
			var fltCorMin = intCharMinWidth / fltAvgCharWidth;
			// for all characters
			for(var intA=0; intA<strIn.length; intA++){
				strChar = strIn.charAt(intA)
				// pick it's relative width
				switch (strChar){ 
					case "f" : fltRelWidth = fltCorMin; break; 
					case "i" : fltRelWidth = fltCorMin; break; 
					case "j" : fltRelWidth = fltCorMin; break; 
					case "l" : fltRelWidth = fltCorMin; break;
					case "I" : fltRelWidth = fltCorMin; break; 
					case "J" : fltRelWidth = fltCorMin; break; 
					case " " : fltRelWidth = fltCorMin; break;
					case "m" : fltRelWidth = fltCorMax; break; 						
					case "w" : fltRelWidth = fltCorMax; break; 	
					case "x" : fltRelWidth = fltCorMax; break; 	
					case "M" : fltRelWidth = fltCorMax; break; 						
					case "W" : fltRelWidth = fltCorMax; break; 	
					case "X" : fltRelWidth = fltCorMax; break; 	
					default : fltRelWidth = 1.0;
				}
				// add it to the total
				fltApproxLength += fltAvgCharWidth * fltRelWidth;
			}
			// return the approximated length
			return Math.round(fltApproxLength);
		}
		
		// checks every step of a function call before executing it.
		function smartEval(strAddress){
			var booSuccess = false;
		// Build a check string to validate te address
			// split off the end-brackets and variables '(vars)' from the address
			var strCheck = strAddress.split('(')[0];
		// validate the path of the address
			arrPath = strCheck.split('.');
			// take the first part of the address, and set it as the first to check
			strPath = arrPath[0];
			// start out assuming the path works
			booPath = true;
			// skip the first part since it's allready been added to the default start string
			for(var intA=1; intA<arrPath.length; intA++){
				if(typeof eval(strPath)=='undefined') booPath = false;
				// add subsequent address parts to check
				strPath += '.' + arrPath[intA]
			}
		// validate the address
			if(booPath){
				if(typeof eval(strCheck)!='undefined'){
					// execute the address
					eval(strAddress);
					booSuccess = true;
				}
			}
			// return it's result
			//return booSuccess;
		}	
		
		

}