// 検索結果が200件を越えているかどうかのフラッグ
var overMaxCountFlag = false;
/** N-Gramアルゴリズムを利用して、全文検索を行う。
 * 検索結果はSearchResultの配列として返却される。
 * 検索結果が0件の場合、長さが0の配列として返却され、nullが返ることは無い。
 * searchWords は検索キーワードリスト
 * searchBookNameは選択されている分冊のフォルダ名。マニュアル一覧がない場合は0になる
 * 検索は閾値が設定できる。
 */
function search(searchWords, searchBookName)
{
	var result = new Array();
	
	for (a = 0; a < Acts.length; a++)
	{
		for (i = 0; i < pages.length; i++)
		{
			if (Acts[a] == books[pages[i].bookId].bookFolderName)
			{
				//ヒットした回数
				var times = 0;
				//タイトルがヒットされたかどうかのflag
				var titleHitflag = false;
				//本文がヒットされたかどうかのflag
				var textHitflag = false;
				//タイトルがヒットされた回数
				var titleHitTimes = 0;
				//本文がヒットされた回数
				var textHitTimes = 0;
				//タイトルか本文にヒットした検索ワードの種類数
				var orHitTimes = 0;
				
				//各検索キーワードの登場回数
				var wordsHitTime = new Array();
				for (j = 0; j < searchWords.length; j++)
				{
					var reg = new RegExp(searchWords[j], "g");
					
					var textResult = unescapeHTML(pages[i].regText).match(reg);
					var titleResult = unescapeHTML(pages[i].regPageTitle).match(reg);
					//１つキーワードの登場回数
					var oneWordHitTime = 0;
					if (textResult != null)
					{
						oneWordHitTime += textResult.length;
						times += textResult.length;
						textHitTimes += textResult.length;
					}
					if (titleResult != null)
					{	
						oneWordHitTime += titleResult.length;
						times += titleResult.length;
						titleHitTimes += titleResult.length;
					}
					if (titleResult != null || textResult != null)
					{
						orHitTimes += 1;
					}
					wordsHitTime[j] = oneWordHitTime;
				}
				if (isResult(wordsHitTime, 2))
				{
					if(orHitTimes >= searchWords.length){
						if (pages[i].pageType != undefined){
							result[result.length] = new SearchResult(pages[i].bookId, i, pages[i].pageTitle, textHitTimes, titleHitTimes, pages[i].pageType);
						}else if (pages[i].fileName == "subtitle"){
							pages[i].fileName = "index.htm";
							pages[i].pageType = "book";
							result[result.length] = new SearchResult(pages[i].bookId, i, pages[i].pageTitle, textHitTimes, titleHitTimes, "book");
						}else if (pages[i].fileName == "preface"){
							//pages[i].fileName = "index_chap_00.htm";
							//pages[i].pageType = "chapter";
							//result[result.length] = new SearchResult(pages[i].bookId, i, pages[i].pageTitle, textHitTimes, titleHitTimes, "chapter");
						}else if (pages[i].fileName == "appendix"){
							//tmp = ""
							//if(parseInt(pages[i-1].fileName)+1 < 10){
							//	tmp = "0";
							//}
							//pages[i].fileName = "index_chap_" + tmp + (parseInt(pages[i-1].fileName)+1) + ".htm";
							//pages[i].pageType = "chapter";
							//result[result.length] = new SearchResult(pages[i].bookId, i, pages[i].pageTitle, textHitTimes, titleHitTimes, "chapter");
						}else if (isFinite(pages[i].fileName)){
							// 章ページへの検索無効
							//tmp = ""
							//if(parseInt(pages[i].fileName) < 10){
							//	tmp = "0";
							//}
							//pages[i].fileName = "index_chap_" + tmp + parseInt(pages[i].fileName) + ".htm";
							//pages[i].pageType = "chapter";
							//result[result.length] = new SearchResult(pages[i].bookId, i, pages[i].pageTitle, textHitTimes, titleHitTimes, "chapter");
						}else{
							pages[i].pageType = "manual";
							result[result.length] = new SearchResult(pages[i].bookId, i, pages[i].pageTitle, textHitTimes, titleHitTimes, "manual");
						}
					}
				}
				//200件以上になると、エラーメッセージ用フラグを立てる
				if (result.length == 200)
				{
					overMaxCountFlag = true;
				}
			}
		}
	}
	
	for (i = 0; i < pages.length; i++)
	{
		if (searchBookName != "" && searchBookName != books[pages[i].bookId].bookFolderName || Acts.includes(books[pages[i].bookId].bookFolderName) == true)
		{
			continue;
		}
		//ヒットした回数
		var times = 0;
		//タイトルがヒットされたかどうかのflag
		var titleHitflag = false;
		//本文がヒットされたかどうかのflag
		var textHitflag = false;
		//タイトルがヒットされた回数
		var titleHitTimes = 0;
		//本文がヒットされた回数
		var textHitTimes = 0;
		//タイトルか本文にヒットした検索ワードの種類数
		var orHitTimes = 0;
		
		//各検索キーワードの登場回数
		var wordsHitTime = new Array();
		for (j = 0; j < searchWords.length; j++)
		{
			var reg = new RegExp(searchWords[j], "g");
			
			var textResult = unescapeHTML(pages[i].regText).match(reg);
			var titleResult = unescapeHTML(pages[i].regPageTitle).match(reg);
			//１つキーワードの登場回数
			var oneWordHitTime = 0;
			if (textResult != null)
			{
				oneWordHitTime += textResult.length;
				times += textResult.length;
				textHitTimes += textResult.length;
			}
			if (titleResult != null)
			{	
				oneWordHitTime += titleResult.length;
				times += titleResult.length;
				titleHitTimes += titleResult.length;
			}
			if (titleResult != null || textResult != null)
			{
				orHitTimes += 1;
			}
			wordsHitTime[j] = oneWordHitTime;
		}
		if (isResult(wordsHitTime, 2))
		{
			if(orHitTimes >= searchWords.length){
				if (pages[i].pageType != undefined){
					result[result.length] = new SearchResult(pages[i].bookId, i, pages[i].pageTitle, textHitTimes, titleHitTimes, pages[i].pageType);
				}else if (pages[i].fileName == "subtitle"){
					pages[i].fileName = "index.htm";
					pages[i].pageType = "book";
					result[result.length] = new SearchResult(pages[i].bookId, i, pages[i].pageTitle, textHitTimes, titleHitTimes, "book");
				}else if (pages[i].fileName == "preface"){
					//pages[i].fileName = "index_chap_00.htm";
					//pages[i].pageType = "chapter";
					//result[result.length] = new SearchResult(pages[i].bookId, i, pages[i].pageTitle, textHitTimes, titleHitTimes, "chapter");
				}else if (pages[i].fileName == "appendix"){
					//tmp = ""
					//if(parseInt(pages[i-1].fileName)+1 < 10){
					//	tmp = "0";
					//}
					//pages[i].fileName = "index_chap_" + tmp + (parseInt(pages[i-1].fileName)+1) + ".htm";
					//pages[i].pageType = "chapter";
					//result[result.length] = new SearchResult(pages[i].bookId, i, pages[i].pageTitle, textHitTimes, titleHitTimes, "chapter");
				}else if (isFinite(pages[i].fileName)){
					// 章ページへの検索無効
					//tmp = ""
					//if(parseInt(pages[i].fileName) < 10){
					//	tmp = "0";
					//}
					//pages[i].fileName = "index_chap_" + tmp + parseInt(pages[i].fileName) + ".htm";
					//pages[i].pageType = "chapter";
					//result[result.length] = new SearchResult(pages[i].bookId, i, pages[i].pageTitle, textHitTimes, titleHitTimes, "chapter");
				}else{
					pages[i].pageType = "manual";
					result[result.length] = new SearchResult(pages[i].bookId, i, pages[i].pageTitle, textHitTimes, titleHitTimes, "manual");
				}
			}
		}
		//200件以上になると、エラーメッセージ用フラグを立てる
		if (result.length == 200)
		{
			overMaxCountFlag = true;
		}
	}
	return result;
}
/**
 * 閾値以上の場合は検索結果になる。
 * wordsHitTimeは各キーワードの登場回数の配列
 * thresholdは設定されていた閾値
 * 戻り値：閾値以上の場合はtrue
 */
function isResult(wordsHitTime, threshold)
{
	var zeroCount = 0;
	for (var h = 0; h < wordsHitTime.length; h++)
	{
		if (wordsHitTime[h] == 0)
		{
			zeroCount++;
		}
	}
	var hitRate = (wordsHitTime.length - zeroCount)/wordsHitTime.length;
	var rate = threshold / 3;
	if (hitRate >= rate)
	{
		return true;
	}
	else
	{
		return false;
	}
}
/**
 * 関連語の検索を行う。（検索キーワードが1ワードのみの場合行う）
 * 検索結果は配列として返却される。
 * 検索結果が0件の場合、長さが0の配列として返却され、nullが返ることは無い。
 * searchWord は検索キーワード
 * searchBookNameは選択されている分冊名。マニュアル一覧がない場合は0になる
 */
function searchRelatedWord(searchWord, searchBookName)
{	
	var related = new Array();
	for(i = 0; i < relatedWords.length; i++)
	{
		// searchWord is escaped.
		if(escapeWord(relatedWords[i].key).toLowerCase() == searchWord)
		{
			if (searchBookName == "" && relatedWords[i].book == -1) {
				related = related.concat(relatedWords[i].words);
			} else {
				if (relatedWords[i].book == -1) {
					continue;
				} else if (searchBookName == books[relatedWords[i].book].bookFolderName) {
					related = related.concat(relatedWords[i].words);
				}
			}
		}
	}
	
	return related;
}

/**
 * 類義語の検索を行う。（検索キーワードが1ワードのみの場合行う）
 * 検索結果は配列として返却される。
 * 検索結果が0件の場合、長さが0の配列として返却され、nullが返ることは無い。
 * searchWord は検索キーワード
 * searchBookNameは選択されている分冊名。マニュアル一覧がない場合は0になる
 */
function searchSynonym(searchWord, searchBookName)
{
	var synonym = new Array();
	for(i = 0; i < synonyms.length; i++)
	{
		// searchWord is escaped.
		if(escapeWord(synonyms[i].key).toLowerCase() == searchWord)
		{
			if (searchBookName == "" && synonyms[i].book == -1) {
				synonym = synonym.concat(synonyms[i].words);
			} else {
				if (synonyms[i].book == -1) {
					continue;
				} else if (searchBookName == books[synonyms[i].book].bookFolderName) {
					synonym = synonym.concat(synonyms[i].words);
				}
			}
		}
	}
	
	return synonym;
}

function escapeWord (str) {
	 return str.replace(/([^A-Za-z0-9])/g , "\\$1");
}
