// IDS WebHelp search
//
// The scripts enables search for the IDS WebHelp:
//  - Tested with thousands of topic entries, the search remains quick.
//  - Works in a frame environment
//  - Works with any browser that supports JavaScript 1.3 and at least partially supports the W3C DOM Level 1.
//  - Searches whole words (is ignored for eastern languages)
//  - Searches case insensitive
//
//  - Supports 
//    	OR search  (default = space separated) Example: spectral demo
//    	AND search     	Example: spectral and demo  	(when the word " AND " is present in the search input)(KdG: not perfect in combinations of >2 words (a and b OR c) is ok, (a b and c) not ok)
//    	Literal search 	Example: "spectral demo"    	(when the search input is embedded in qoutes (" or ')
//    	Word fragments 	Example: spect*                	(when the search input contains a *)
//    	Exclude words  	Example: spectral -demo        	(when a word is preceded by an minus sign)
//
// Limits: JavaScript objects have a maximum size of 16GB. The wh_data.js file contains searchable data; some browsers have a limit of 65535 lines.
//
// KdG, www.eluxis.com
//
// 	Version:
//	01  31-05-2023 [HvdB] Ranking weight changed: move matching title (and headings) up in the result list. Try literal searching first.

// ------------------- PARAMETERS ---------------------------
var showinfo = false;
var wholewords = true;
var nonwholewordslanguages = "ja-JP,ko-KR,ru-RU,zh-CN"

var replaceWords = {'words': []};
/* example:
var replaceWords = {'words': [
     {'replaceword': 'spetral', 'replacewith': 'spectral'},
     {'replaceword': 'instuction', 'replacewith': 'instruction'}
]};
*/

//Response strings (overwritten by servlet variables) 
var lf0 = "No matches found"
var lf1 = "1 result"
var lf2 = " results"
var lf3a = 'Results for';
var lf3b = 'instead of';

//-----------------------------------------------------------
function getStringFromLocalStorage() {
	//Use localStorage instead of cookies, because it has not cross-origin issues and the value is only used her in the local client-javascript.
	return localStorage.getItem("searchstring");
}

function doSearch(searchForm) {
	if (searchForm.d.value.length > 0) {
		//Store searchString in cookie
		var searchString = searchForm.d.value;
		var searchString = searchString.replace(/\+/g, ' ').replace(/\s\s+/g, ' ');
	 	searchString = searchString.trim();
		localStorage.setItem('searchstring', searchString);
		//Do the search
		Do_Search(true)
		//Display the results
		showSearchResult()
	}
}
function fillSearchForm(txt) {//fill form text from cookie value
	if (!txt) {
		txt = getStringFromLocalStorage();
	}
	if (txt != 'undefined' && txt != null) document.searchForm.d.value = txt;
}

function Do_Search(doreplace) {
	var replaced = false;
	var found = new Array();
	var searchString = getStringFromLocalStorage();
	var stxt = searchString.toLowerCase();
	
	//Whole Words
	ww = wholewords
	if (stxt.match(/\*/)) {//Wildcard found
		ww = false;
		stxt = stxt.replace(/\*/g,'');
	}
	try {// if language is defined (by servlet)
		if (nonwholewordslanguages.search(language)!=-1) {ww = false;}
	}
	catch(e) {}

	//Define search type
	var searchtype = "default";// default OR (default) or AND search
	stxt = stxt.replace(/ or /gi, ' ');
	if ((stxt.match("^\"") && stxt.match("\"$")) || (stxt.match("^'") && stxt.match("'$"))) {
		searchtype = "Literal"; //quotes found: literal search 
		stxt = stxt.substring(1, stxt.length - 1);
	}

	var s_words = stxt.split(' ');
 
	var rank;
	if (searchtype=="Literal") { //Literal search
		for (var t = 0; t < s.length; t++) {//iterate document data
			var sdata = s[t];
			rank = 0;
			var re = new RegExp(stxt, 'gi');
			if (sdata[0].search(re) != -1) {//Title
				var count = sdata[0].match(re).length;
				rank += (500 * count);
			}
			if (sdata[1].search(re) != -1) {//Description
				var count = sdata[1].match(re).length;
				rank += (40 * count);
			}
			if (sdata[2].search(re) != -1) {//Content
				var count = sdata[2].match(re).length;
				rank += (3 * count);
			}
			if (rank != 0) {
				found.push({"rank": rank,"title": sdata[0],"desc": sdata[1],"url": sdata[3]});
			}
		}
	} 
	else { // OR (default) and AND search
		if (doreplace) {
			var replacedtxt = stxt
			for (var t = 0; t < s_words.length; t++) {
				for (var j = 0; j < replaceWords.words.length; j++) {
					if (s_words[t] == replaceWords.words[j].replaceword) {
						stxt = stxt.replace(s_words[t], replaceWords.words[j].replacewith);
						replaced = true;
					}
				}
			}
			s_words = stxt.split(' ');
		} 
		for (var t = 0; t < s.length; t++) {//iterate document data
			var sdata = s[t];
			var rank = 0;
			var wordrank
			var ANDfactor = 1;
			
			//Try literal search first
			var re = new RegExp(stxt, 'gi');
			
			if (sdata[0].search(re) != -1) {//Title
				var count = sdata[0].match(re).length;
				rank += (5000 * count);
			}
			if (sdata[1].search(re) != -1) {//Description
				var count = sdata[1].match(re).length;
				rank += (4000 * count);
			}

			for (var j = 0; j < s_words.length; j++) {//iterate search words
				if (s_words[j] != "and") {//skip the word "AND"
					if (ww) {
						var re = new RegExp('\\b' + s_words[j] + '\\b', 'gi');
					} else {
						var re = new RegExp(s_words[j], 'gi');
					}
					wordrank = 0;
					if (sdata[0].search(re) != -1) {//Title
						var count = sdata[0].match(re).length;
						wordrank += (500 * count);
						rank +=  (500 * count);
					}
					if (sdata[1].search(re) != -1) {//Description
						var count = sdata[1].match(re).length;
						wordrank += (40 * count);
						rank +=  (40 * count);; 
					}
					if (sdata[2].search(re) != -1) {//Content
						var count = sdata[2].match(re).length;
						wordrank += (3 * count);
						rank +=  (3 * count);; 
					}
					if (s_words[j].search('-')==0) {//Exclude word
						re = new RegExp(s_words[j].substring(1), 'i');
						if (sdata[0].search(re) != -1 || sdata[1].search(re) != -1 || sdata[2].search(re) != -1) {
							wordrank = 0;
							rank = 0;
						}
					}
					if (s_words[j+1]=="and" || (j>0 && s_words[j-1]=="and")) {//if next or previous word is "AND"
						if (wordrank==0) ANDfactor = 0;
						rank = rank * ANDfactor;
					}	
					else ANDfactor = 1;
				}
			}
			if (rank != 0) {
				found.push({"rank": rank,"title": sdata[0],"desc": sdata[1],"url": sdata[3]});
			}
		}
	}

	var foundnr = found.length;
	if (foundnr != 0) { //Results found
		var result = '';
		// Found message
		if (foundnr == 1) {
			result += '<p class="resultinfo">' + lf1;
		} else {
			result += '<p class="resultinfo">' + foundnr + ' ' + lf2;
		}
		if (showinfo) { result += " ("+ searchtype +" search)"}
		result += '</p>';
		if (replaced) { //mistyped words are replaced
			result += '<p class="resultinfo">' + lf3a + ' ' + stxt + '. ' + lf3b + ' <a onclick="javascript:Do_Search(false)">' + replacedtxt + '</a></p>';
		}
		found.sort(function(a, b) { return b.rank - a.rank } );
		// Found results
		result += '<hr/>';
		result += '<ul id="searchresults">';
		for (var i = 0; i < found.length; i++) {
			result += '<li>';
			result += '<a href="'+ found[i].url+ '" target="mainframe" title="'+found[i].title+'" onclick="javascript:showContent(this)">'+ found[i].title+ '</a>';
			if (showinfo) {
				result += '<div class="resultinfo">Rank: ' + found[i].rank + '</div>';
			}
			result += '</li>\n';
		}
		result += '</ul>';
		result += '<hr/>';
	}
	else {
 		result = '<p>' + lf0 + '<br/><br/><br/>' + searchhelp;
		if (showinfo) { result += " ("+ searchtype +" search)"}
		result +=  '</p><hr/>';
	}
	//Place result
	var hlp = document.getElementById("resultcontainer")
	if (hlp) hlp.innerHTML = result
}
