/*----------------------------------------------------------------------------
 * JavaScript for webhelp search
 *----------------------------------------------------------------------------
 This file is part of the webhelpsearch plugin for DocBook WebHelp
 Copyright (c) 2007-2008 NexWave Solutions All Rights Reserved.
 www.nexwave.biz Nadege Quaine
 http://kasunbg.blogspot.com/ Kasun Gajasinghe
 */

//string initialization
var htmlfileList = "htmlFileInfoList.js";
var htmlfileinfoList = "htmlFileInfoList.js";
var useCJKTokenizing = false;

var w = new Object();
var scoring = new Object();

var searchTextField = '';
var no = 0;
var noWords = 0;
var partialSearch = "<font class=\"highlightText\">There is no page containing all the search terms.<br>Partial results:</font>";
var warningMsg = '<div style="padding: 5px;margin-right:5px;;background-color:#FFFF00;">';
warningMsg+='<b>Please note that due to security settings, Google Chrome does not highlight';
warningMsg+=' the search results in the right frame.</b><br>';
warningMsg+='This happens only when the WebHelp files are loaded from the local file system.<br>';
warningMsg+='Workarounds:';
warningMsg+='<ul>';
warningMsg+='<li>Try using another web browser.</li>';
warningMsg+='<li>Deploy the WebHelp files on a web server.</li>';
warningMsg+='</div>';
txt_filesfound = 'Results';
txt_enter_at_least_1_char = "You must enter at least one character.";
txt_enter_more_than_10_words = "Only first 10 words will be processed.";
txt_browser_not_supported = "Your browser is not supported. Use of Mozilla Firefox is recommended.";
txt_please_wait = "Please wait. Search in progress...";
txt_results_for = "Results for: ";

/* This function verify the validity of search input by the user
  Cette fonction verifie la validite de la recherche entrre par l utilisateur */
function Verifie(searchForm) {

    // Check browser compatibility
    if (navigator.userAgent.indexOf("Konquerer") > -1) {

        alert(txt_browser_not_supported);
        return;
    }

    searchTextField = trim(document.searchForm.textToSearch.value);
    searchTextField = searchTextField.replace(/['"]/g,'');
	var expressionInput = searchTextField;
    $.cookie('textToSearch', expressionInput);

    if (expressionInput.length < 1) {

        // expression is invalid
        alert(txt_enter_at_least_1_char);
        // reactive la fenetre de search (utile car cadres)

        document.searchForm.textToSearch.focus();
    }
    else {
    var splitSpace = searchTextField.split(" ");
       var splitWords = [];
        for (var i = 0 ; i < splitSpace.length ; i++) {
          var splitDot = splitSpace[i].split(".");
          for (var i1 = 0; i1 < splitDot.length; i1++) {
               var splitColon = splitDot[i1].split(":");
            for (var i2 = 0; i2 < splitColon.length; i2++) {
                var splitDash = splitColon[i2].split("-");
                 for (var i3 = 0; i3 < splitDash.length; i3++) {
                     if (splitDash[i3].split("").length > 0) {
                           splitWords.push(splitDash[i3]);
                       }
                 }
            }
          }
       }
       noWords = splitWords;
    	if (noWords.length > 9){
          // Allow to search maximum 10 words
    		alert(txt_enter_more_than_10_words);
    		expressionInput = '';
    		for (var x = 0 ; x < 10 ; x++){
    			expressionInput = expressionInput + " " + noWords[x]; 
    		}    		
    		Effectuer_recherche(expressionInput);
    		document.searchForm.textToSearch.focus();
    	} else {
	        // Effectuer la recherche
             expressionInput = '';
          for (var x = 0 ; x < noWords.length ; x++) {
                 expressionInput = expressionInput + " " + noWords[x]; 
             }
	        Effectuer_recherche(expressionInput);
	        // reactive la fenetre de search (utile car cadres)
	        document.searchForm.textToSearch.focus();        
    	}
    }
}

var stemQueryMap = new Array();  // A hashtable which maps stems to query words

/* This function parses the search expression, loads the indices and displays the results*/
function Effectuer_recherche(expressionInput) {

    /* Display a waiting message */
    //DisplayWaitingMessage();

    /*data initialisation*/
    var searchFor = "";       // expression en lowercase et sans les caracte    res speciaux
    //w = new Object();  // hashtable, key=word, value = list of the index of the html files
    scriptLetterTab = new Scriptfirstchar(); // Array containing the first letter of each word to look for
    var wordsList = new Array(); // Array with the words to look for
    var finalWordsList = new Array(); // Array with the words to look for after removing spaces
    var linkTab = new Array();
    var fileAndWordList = new Array();
    var txt_wordsnotfound = "";


    // --------------------------------------
    // Begin Thu's patch 
    /*nqu: expressionInput, la recherche est lower cased, plus remplacement des char speciaux*/
    //The original replacement expression is: 
    //searchFor = expressionInput.toLowerCase().replace(/<\//g, "_st_").replace(/\$_/g, "_di_").replace(/\.|%2C|%3B|%21|%3A|@|\/|\*/g, " ").replace(/(%20)+/g, " ").replace(/_st_/g, "</").replace(/_di_/g, "%24_");
    //The above expression was error prone because it did not deal with words that have a . as part of the word correctly, for example, document.txt
    
    //Do not automatically replace a . with a space
    searchFor = expressionInput.toLowerCase().replace(/<\//g, "_st_").replace(/\$_/g, "_di_").replace(/%2C|%3B|%21|%3A|@|\/|\*/g, " ").replace(/(%20)+/g, " ").replace(/_st_/g, "</").replace(/_di_/g, "%24_");
    
    //If it ends with a period, replace it with a space
    searchFor = searchFor.replace(/[.]$/,"");
    // End Thu's Patch
    // ------------------------------------------

    searchFor = searchFor.replace(/  +/g, " ");
    searchFor = searchFor.replace(/ $/, "").replace(/^ /, "");

    wordsList = searchFor.split(" ");
    wordsList.sort();

    //set the tokenizing method
    useCJKTokenizing = typeof indexerLanguage != "undefined" && (indexerLanguage == "zh" || indexerLanguage == "ja" || indexerLanguage == "ko");
    //If Lucene CJKTokenizer was used as the indexer, then useCJKTokenizing will be true. Else, do normal tokenizing.
    // 2-gram tokenizinghappens in CJKTokenizing, 
    //If doStem then make tokenize with Stemmer
    var finalArray;
    if (doStem){
	    if(useCJKTokenizing){
	        finalWordsList = cjkTokenize(wordsList);
          finalArray = finalWordsList;
	    } else { 
	        finalWordsList = tokenize(wordsList);
          finalArray = finalWordsList;
	    }
    } else if(useCJKTokenizing){
          finalWordsList = cjkTokenize(wordsList);
          finalArray = finalWordsList;
         } else{

    //load the scripts with the indices: the following lines do not work on the server. To be corrected
    /*if (IEBrowser) {
     scriptsarray = loadTheIndexScripts (scriptLetterTab);
     } */

    /**
     * Compare with the indexed words (in the w[] array), and push words that are in it to tempTab.
     */
    var tempTab = new Array();
	
    // ---------------------------------------
    // Thu's patch
    //Do not use associative array in for loop, for example:
    //for(var t in finalWordsList)
    //it causes errors when finalWordList contains 
    //stemmed words such as: kei from the stemmed word: key
    for(var t=0;t<finalWordsList.length;++t){
        var aWord=finalWordsList[t];
        //w is a Map like Object, use the current word in finalWordList as the key
        if(w[aWord] == undefined){
            txt_wordsnotfound += aWord + " ";
	        }
        else{
            tempTab.push(aWord);
    		}
    	}
    	finalWordsList = tempTab;		
    //Check all the inputs to see if the root words are in the finalWordsList, if not add them there
    var inputs = expressionInput.split(' ');
    // Thu's Patch 
    // -------------------------------------------

    
    txt_wordsnotfound = expressionInput;
	finalWordsList = removeDuplicate(finalWordsList);
    
   }
    if (finalWordsList.length) {
      //search 'and' and 'or' one time
      fileAndWordList = SortResults(finalWordsList);
      
      if (fileAndWordList == undefined){
        	var cpt = 0;
      } else {
      	  var cpt = fileAndWordList.length;
		  var maxNumberOfWords = fileAndWordList[0][0].motsnb;
      }
	  if (cpt > 0){
		var searchedWords = noWords.length;
		var foundedWords  = fileAndWordList[0][0].motslisteDisplay.split(",").length;
		//console.info("search : " + noWords.length + "   found : " + fileAndWordList[0][0].motslisteDisplay.split(",").length);
		if (searchedWords != foundedWords){
			linkTab.push(partialSearch);
		}
	  }
	  
      
      for (var i = 0; i < cpt; i++) {
			
			var hundredProcent = fileAndWordList[i][0].scoring + 100 * fileAndWordList[i][0].motsnb;
			var ttScore_first = fileAndWordList[i][0].scoring;
			var numberOfWords = fileAndWordList[i][0].motsnb;
			
            if (fileAndWordList[i] != undefined) {
                linkTab.push("<p>" + txt_results_for + " " + "<span class=\"searchExpression\">" + fileAndWordList[i][0].motslisteDisplay + "</span>" + "</p>");

                linkTab.push("<ul class='searchresult'>");
                for (t in fileAndWordList[i]) {
                    //linkTab.push("<li><a href=\"../"+fl[fileAndWordList[i][t].filenb]+"\">"+fl[fileAndWordList[i][t].filenb]+"</a></li>");
				                        
                    var ttInfo = fileAndWordList[i][t].filenb;
                    // Get scoring
                    var ttScore = fileAndWordList[i][t].scoring;
                    var tempInfo = fil[ttInfo];
				    
                    var pos1 = tempInfo.indexOf("@@@");
                    var pos2 = tempInfo.lastIndexOf("@@@");
                    var tempPath = tempInfo.substring(0, pos1);
                    var tempTitle = tempInfo.substring(pos1 + 3, pos2);
                    var tempShortdesc = tempInfo.substring(pos2 + 3, tempInfo.length);

                    
                    // toc.html will not be displayed on search result
                    if (tempPath == 'toc.html'){
                        continue;
                    }
                    /*
                    //file:///home/kasun/docbook/WEBHELP/webhelp-draft-output-format-idea/src/main/resources/web/webhelp/installation.html
                    var linkString = "<li><a href=" + tempPath + ">" + tempTitle + "</a>";
                    // var linkString = "<li><a href=\"installation.html\">" + tempTitle + "</a>";
                    */
                    var split = fileAndWordList[i][t].motsliste.split(",");
                    // var splitedValues = expressionInput.split(" ");
					// var finalArray = split.concat(splitedValues);					
					
                    arrayString = 'Array(';
                    for(var x in finalArray){
                      if (finalArray[x].length > 2 || useCJKTokenizing){
                    		arrayString+= "'" + finalArray[x] + "',";
                    	} 
                    }
                    arrayString = arrayString.substring(0,arrayString.length - 1) + ")";
                    var idLink = 'foundLink' + no;
                    var linkString = '<li><a id="' + idLink + '" href="' + tempPath + '" class="foundResult">' + tempTitle + '</a>';
                    var starWidth = (ttScore * 100/ hundredProcent)/(ttScore_first/hundredProcent) * (numberOfWords/maxNumberOfWords);
                    starWidth = starWidth < 10 ? (starWidth + 5) : starWidth;
                    // Keep the 5 stars format
                    if (starWidth > 85){
						starWidth = 85;
					}
					/*
					var noFullStars = Math.ceil(starWidth/17);
					var fullStar  = "curr";
					var emptyStar = "";
					if (starWidth % 17 == 0){
						// am stea plina
						
					} else {
						
					}
					console.info(noFullStars);
					*/
                    // Also check if we have a valid description
                    if ((tempShortdesc != "null" && tempShortdesc != '...')) {
                    
                        linkString += "\n<div class=\"shortdesclink\">" + tempShortdesc + "</div>";
                    }
                    linkString += "</li>";
                    
                    // Add rating values for scoring at the list of matches	
					linkString += "<div id=\"rightDiv\">";
					linkString += "<div id=\"star\">";
					//linkString += "<div style=\"color: rgb(136, 136, 136);\" id=\"starUser0\" class=\"user\">" 
					//				+ ((ttScore * 100/ hundredProcent)/(ttScore_first/hundredProcent)) * 1 + "</div>";
	                linkString += "<ul id=\"star0\" class=\"star\">";
					linkString += "<li id=\"starCur0\" class=\"curr\" style=\"width: " + starWidth + "px;\"></li>";
	                linkString += "</ul>";
	                
	                linkString += "<br style=\"clear: both;\">";
	                linkString += "</div>";
					linkString += "</div>";
                    //linkString += '<b>Rating: ' + ttScore + '</b>';
                                           
                    linkTab.push(linkString);
                    no++;
                }
                linkTab.push("</ul>");
            }
        }
    }

    var results = "";
    if (linkTab.length > 0) { 
        /*writeln ("<p>" + txt_results_for + " " + "<span class=\"searchExpression\">"  + cleanwordsList + "</span>" + "<br/>"+"</p>");*/
        results = "<p>";
        //write("<ul class='searchresult'>");
        for (t in linkTab) {
            results += linkTab[t].toString();
        }
        results += "</p>";
    } else {
        results = "<p>" + localeresource.search_no_results + " <span class=\"searchExpression\">" + txt_wordsnotfound + "</span>" + "</p>";
    }
    
    
    // Verify if the browser is Google Chrome and the WebHelp is used on a local machine
    // If browser is Google Chrome and WebHelp is used on a local machine a warning message will appear
    // Highlighting will not work in this conditions. There is 2 workarounds
    if (verifyBrowser()){
        document.getElementById('searchResults').innerHTML = results;
    } else {
        document.getElementById('searchResults').innerHTML = warningMsg + results;
    }
    
}


// Verify if the stemmed word is aproximately the same as the searched word
function verifyWord(word, arr){
	for (var i = 0 ; i < arr.length ; i++){
		if (word[0] == arr[i][0] 
			&& word[1] == arr[i][1] 
			//&& word[2] == arr[i][2]
			){
			return true;
		}
	}
	return false;
}

// Look for elements that start with searchedValue.
function wordsStartsWith(searchedValue){
	var toReturn = '';
	for (var sv in w){
		if (searchedValue.length < 3){
			continue;
		} else {
			if (sv.toLowerCase().indexOf(searchedValue.toLowerCase()) == 0){
				toReturn+=sv + ","; 
			}
		}
	}
	return toReturn.length > 0 ? toReturn : undefined;
}


function tokenize(wordsList){
    var stemmedWordsList = new Array(); // Array with the words to look for after removing spaces
    var cleanwordsList = new Array(); // Array with the words to look for
    // -------------------------------------------------
    // Thu's patch
    for(var j=0;j<wordsList.length;++j){
        var word = wordsList[j];
        var originalWord=word;
        if(typeof stemmer != "undefined" ){
            var stemmedWord=stemmer(word);
            if(w[stemmedWord]!=undefined){
            stemQueryMap[stemmer(word)] = word;
            }
            else{
                stemQueryMap[originalWord]=originalWord;
            }
        } else {
            if(w[word]!=undefined){
            stemQueryMap[word] = word;
        }
            else{
                stemQueryMap[originalWord]=originalWord;
            }
        }
    } 
     //stemmedWordsList is the stemmed list of words separated by spaces.
    for (var t=0;t<wordsList.length;++t) {
        wordsList[t] = wordsList[t].replace(/(%22)|^-/g, "");
        if (wordsList[t] != "%20") {
            scriptLetterTab.add(wordsList[t].charAt(0));
            cleanwordsList.push(wordsList[t]);
        }
    }

    if(typeof stemmer != "undefined" ){
        //Do the stemming using Porter's stemming algorithm
        for (var i = 0; i < cleanwordsList.length; i++) {			
            var stemWord = stemmer(cleanwordsList[i]);			
            if(w[stemWord]!=undefined){
            stemmedWordsList.push(stemWord);
        }
            else{
                stemmedWordsList.push(cleanwordsList[i]);               
            }
        }
    // End Thu's patch
    // -------------------------------------------
    } else {
        stemmedWordsList = cleanwordsList;
    }
    return stemmedWordsList;
}

//Invoker of CJKTokenizer class methods.
function cjkTokenize(wordsList){
    var allTokens= new Array();
    var notCJKTokens= new Array();
    var j=0;
    for(j=0;j<wordsList.length;j++){
        var word = wordsList[j];
        if(getAvgAsciiValue(word) < 127){
            notCJKTokens.push(word);
        } else { 
            var tokenizer = new CJKTokenizer(word);
            var tokensTmp = tokenizer.getAllTokens();
            allTokens = allTokens.concat(tokensTmp);
        }
    }
    allTokens = allTokens.concat(tokenize(notCJKTokens));
    return allTokens;
}

//A simple way to determine whether the query is in english or not.
function getAvgAsciiValue(word){
    var tmp = 0;
    var num = word.length < 5 ? word.length:5;
    for(var i=0;i<num;i++){
        if(i==5) break;
        tmp += word.charCodeAt(i);
    }
    return tmp/num;
}

//CJKTokenizer
function CJKTokenizer(input){
    this.input = input;
    this.offset=-1;
    this.tokens = new Array(); 
    this.incrementToken = incrementToken;
    this.tokenize = tokenize;
    this.getAllTokens = getAllTokens;
    this.unique = unique;

    function incrementToken(){
		if(this.input.length - 2 <= this.offset){
		//	console.log("false "+offset);
			return false;
		}
		else {
			this.offset+=1;
			return true;
		}
	}

	function tokenize(){
		//document.getElementById("content").innerHTML += x.substring(offset,offset+2)+"<br>";
		return this.input.substring(this.offset,this.offset+2);
	}

	function getAllTokens(){
		while(this.incrementToken()){
			var tmp = this.tokenize();
			this.tokens.push(tmp);
		}
        return this.unique(this.tokens);
//		document.getElementById("content").innerHTML += tokens+" ";
//		document.getElementById("content").innerHTML += "<br>dada"+sortedTokens+" ";
//		console.log(tokens.length+"dsdsds");
		/*for(i=0;i<tokens.length;i++){
			console.log(tokens[i]);
			var ss = tokens[i] == sortedTokens[i];

//			document.getElementById("content").innerHTML += "<br>dada"+un[i]+"- "+stems[i]+"&nbsp;&nbsp;&nbsp;"+ ss;
			document.getElementById("content").innerHTML += "<br>"+sortedTokens[i];
		}*/
	}

	function unique(a)
	{
	   var r = new Array();
	   o:for(var i = 0, n = a.length; i < n; i++)
	   {
	      for(var x = 0, y = r.length; x < y; x++)
	      {
		 if(r[x]==a[i]) continue o;
	      }
	      r[r.length] = a[i];
	   }
	   return r;
	} 
}


/* Scriptfirstchar: to gather the first letter of index js files to upload */
function Scriptfirstchar() {
    this.strLetters = "";
    this.add = addLettre;
}

function addLettre(caract) {

    if (this.strLetters == 'undefined') {
        this.strLetters = caract;
    } else if (this.strLetters.indexOf(caract) < 0) {
        this.strLetters += caract;
    }

    return 0;
}
/* end of scriptfirstchar */

/*main loader function*/
/*tab contains the first letters of each word looked for*/
function loadTheIndexScripts(tab) {

    //alert (tab.strLetters);
    var scriptsarray = new Array();

    for (var i = 0; i < tab.strLetters.length; i++) {

        scriptsarray[i] = "..\/search" + "\/" + tab.strLetters.charAt(i) + ".js";
    }
    // add the list of html files
    i++;
    scriptsarray[i] = "..\/search" + "\/" + htmlfileList;

    //debug
    for (var t in scriptsarray) {
        //alert (scriptsarray[t]);
    }

    tab = new ScriptLoader();
    for (t in scriptsarray) {
        tab.add(scriptsarray[t]);
    }
    tab.load();
    //alert ("scripts loaded");
    return (scriptsarray);
}

/* ScriptLoader: to load the scripts and wait that it's finished */
function ScriptLoader() {
    this.cpt = 0;
    this.scriptTab = new Array();
    this.add = addAScriptInTheList;
    this.load = loadTheScripts;
    this.onScriptLoaded = onScriptLoadedFunc;
}

function addAScriptInTheList(scriptPath) {
    this.scriptTab.push(scriptPath);
}

function loadTheScripts() {
    var script;
    var head;

    head = document.getElementsByTagName('head').item(0);

    //script = document.createElement('script');

    for (var el in this.scriptTab) {
        //alert (el+this.scriptTab[el]);
        script = document.createElement('script');
        script.src = this.scriptTab[el];
        script.type = 'text/javascript';
        script.defer = false;

        head.appendChild(script);
    }

}

function onScriptLoadedFunc(e) {
    e = e || window.event;
    var target = e.target || e.srcElement;
    var isComplete = true;
    if (typeof target.readyState != undefined) {

        isComplete = (target.readyState == "complete" || target.readyState == "loaded");
    }
    if (isComplete) {
        ScriptLoader.cpt++;
        if (ScriptLoader.cpt == ScriptLoader.scripts.length) {
            ScriptLoader.onLoadComplete();
        }
    }
}

/*
function onLoadComplete() {
    alert("loaded !!");
} */

/* End of scriptloader functions */
 
// Array.unique( strict ) - Remove duplicate values
function unique(tab) {
    var a = new Array();
    var i;
    var l = tab.length;

    if (tab[0] != undefined) {
        a[0] = tab[0];
    }
    else {
        return -1;
    }

    for (i = 1; i < l; i++) {
        if (indexof(a, tab[i], 0) < 0) {
            a.push(tab[i]);
        }
    }
    return a;
}
function indexof(tab, element, begin) {
    for (var i = begin; i < tab.length; i++) {
        if (tab[i] == element) {
            return i;
        }
    }
    return -1;

}
/* end of Array functions */


/*
 Param: mots= list of words to look for.
 This function creates an hashtable:
 - The key is the index of a html file which contains a word to look for.
 - The value is the list of all words contained in the html file.

 Return value: the hashtable fileAndWordList
 */
function SortResults(mots) {

    var fileAndWordList = new Object();
    if (mots.length == 0 || mots[0].length == 0) {
        return null;
    }
    
    
    // In generated js file we add scoring at the end of the word
    // Example word1*scoringForWord1,word2*scoringForWord2 and so on
    // Split after * to obtain the right values
    var scoringArr = Array();
    for (var t in mots) {
        // get the list of the indices of the files.
        var listNumerosDesFicStr = w[mots[t].toString()];

        if (listNumerosDesFicStr != undefined) {

            //alert ("listNumerosDesFicStr "+listNumerosDesFicStr);
            var tab = listNumerosDesFicStr.split(",");
            //for each file (file's index):
            for (var t2 in tab) {
                var tmp = '';
                var idx = '';
                var temp = tab[t2].toString();
                if (temp.indexOf('*') != -1) {
                    idx = temp.indexOf('*');
                    tmp = temp.substring(idx + 3, temp.length);
                    temp = temp.substring(0, idx);
                }
                scoringArr.push(tmp);
                if (fileAndWordList[temp] == undefined) {
                    fileAndWordList[temp] = "" + mots[t];
                } else {
                    fileAndWordList[temp] += "," + mots[t];
                }
                //console.info("fileAndWordList[" + temp + "]=" + fileAndWordList[temp] + " : " + tmp);
            }

        }
    }
    var fileAndWordListValuesOnly = new Array();
    // sort results according to values
    var temptab = new Array();
    finalObj = new Array();
    for (t in fileAndWordList) {    	
    	finalObj.push(new newObj(t,fileAndWordList[t]));
    }

    if ( finalObj.length == 0 ) {   // None of the queried words are not in the index (stemmed or not)
        return null;
    }
    finalObj = removeDerivates(finalObj);
    for (t in finalObj) {
        tab = finalObj[t].wordList.split(',');
        var tempDisplay = new Array();
        for (var x in tab) {        		
            if(stemQueryMap[tab[x]] != undefined && doStem){
                tempDisplay.push(stemQueryMap[tab[x]]); //get the original word from the stem word.                
            } else {
                tempDisplay.push(tab[x]); //no stem is available. (probably a CJK language)
            }
        }
        var tempDispString = tempDisplay.join(", ");
				var index;
				for (x in fileAndWordList) {
					if (x === finalObj[t].filesNo) {
						index = x;
						break;
					}
				}
				var scoring = findRating(fileAndWordList[index], index);	
        temptab.push(new resultPerFile(finalObj[t].filesNo, finalObj[t].wordList, tab.length, tempDispString, scoring));
        fileAndWordListValuesOnly.push(finalObj[t].wordList);        
    }
    fileAndWordListValuesOnly = unique(fileAndWordListValuesOnly);
    fileAndWordListValuesOnly = fileAndWordListValuesOnly.sort(compare_nbMots);

    var listToOutput = new Array();
    for (var fawlvoIdx in fileAndWordListValuesOnly) {
        for (t in temptab) {
            if (temptab[t].motsliste == fileAndWordListValuesOnly[fawlvoIdx]) {
                if (listToOutput[fawlvoIdx] == undefined) {
                    listToOutput[fawlvoIdx] = new Array(temptab[t]);
                } else {
                    listToOutput[fawlvoIdx].push(temptab[t]);
                }
            }
        }
    }		
  // Sort results by scoring, descending on the same group
	for (var ltoIdx in listToOutput) {
	    listToOutput[ltoIdx].sort(function(a, b){
			return b.scoring - a.scoring;
		});
	}
	// If we have groups with same number of words, 
	// will sort groups by higher scoring of each group
	for (var i = 0; i < listToOutput.length - 1; i++) {
		for (var j = i + 1; j < listToOutput.length; j++) {
			if (listToOutput[i][0].motsnb < listToOutput[j][0].motsnb 
				|| (listToOutput[i][0].motsnb == listToOutput[j][0].motsnb
				&& listToOutput[i][0].scoring < listToOutput[j][0].scoring)
				) {
				var x = listToOutput[i];
				listToOutput[i] = listToOutput[j];
				listToOutput[j] = x;
			}
		}
	}

    return listToOutput;
}

// Remove derivates words from the list of words
function removeDerivates(obj){
	var toResultObject = new Array();	
	for (i in obj){
		var filesNo  = obj[i].filesNo;
		var wordList = obj[i].wordList;
		var wList = wordList.split(",");		
		var searchedWords = searchTextField.toLowerCase().split(" ");
		for (var k = 0 ; k < searchedWords.length ; k++){
			for (var j = 0 ; j < wList.length ; j++){				
				if (wList[j].startsWith(searchedWords[k])){
					wList[j] = searchedWords[k];
				}
			}
		}
		wList = removeDuplicate(wList);
		var recreateList = '';
		for(var x in wList){
			recreateList+=wList[x] + ",";
		}
		recreateList = recreateList.substr(0, recreateList.length - 1);
		toResultObject.push(new newObj(filesNo, recreateList));
	}
	return toResultObject;
}

function newObj(filesNo, wordList){
	this.filesNo = filesNo;
	this.wordList = wordList;
}

// Add a new parameter. Scoring.
function resultPerFile(filenb, motsliste, motsnb, motslisteDisplay, scoring, group) {
	//10 - spring,time - 2 - spring, time - 55 - 3
    this.filenb = filenb;
    this.motsliste = motsliste;
    this.motsnb = motsnb;
    this.motslisteDisplay= motslisteDisplay;
    
    this.scoring = scoring;
    
}


function findRating(words, nr){
    var sum = 0;
    var xx = words.split(',');
    for (jj = 0 ; jj < xx.length ; jj++){
        var wrd = w[xx[jj]].split(',');
        for (var ii = 0 ; ii < wrd.length ; ii++){
            var wrdno = wrd[ii].split('*');
            if (wrdno[0] == nr){
                sum+=parseInt(wrdno[1]);
            }
        }
    }
    return sum;
}

function compare_nbMots(s1, s2) {
    var t1 = s1.split(',');
    var t2 = s2.split(',');
    //alert ("s1:"+t1.length + " " +t2.length)
    if (t1.length == t2.length) {
        return 0;
    } else if (t1.length > t2.length) {
        return 1;
    } else {
        return -1;
    }
    //return t1.length - t2.length);
}

// return false if browser is Google Chrome and WebHelp is used on a local machine, not a web server 
function verifyBrowser(){
    var returnedValue = true;    
    var browser = BrowserDetect.browser;
    var addressBar = window.location.href;
    if (browser == 'Chrome' && addressBar.indexOf('file://') === 0){
        returnedValue = false;
    }
    
    return returnedValue;
}

// Remove duplicate values from an array
function removeDuplicate(arr) {
   var r = new Array();
   o:for(var i = 0, n = arr.length; i < n; i++) {
      for(var x = 0, y = r.length; x < y; x++) {
         if(r[x]==arr[i]) continue o;
      }
      r[r.length] = arr[i];
   }
   return r;
}

// Create startsWith method
String.prototype.startsWith = function(str) {
	return (this.match("^"+str)==str);
}

function trim(str, chars) {
	return ltrim(rtrim(str, chars), chars);
}
 
function ltrim(str, chars) {
	chars = chars || "\\s";
	return str.replace(new RegExp("^[" + chars + "]+", "g"), "");
}
 
function rtrim(str, chars) {
	chars = chars || "\\s";
	return str.replace(new RegExp("[" + chars + "]+$", "g"), "");
}
