// 検索結果が200件を越えているかどうかのフラッグ
var overMaxCountFlag = false;
/** N-Gramアルゴリズムを利用して、全文検索を行う。
 * 検索結果はSearchResultの配列として返却される。
 * 検索結果が0件の場合、長さが0の配列として返却され、nullが返ることは無い。
 * searchWords は検索キーワードリスト
 * searchBookNameは選択されている分冊のフォルダ名。マニュアル一覧がない場合は0になる
 * 検索は閾値が設定できる。
 */
function search(searchWords, searchBookName)
{
	var result = new Array();
	for (i = 0; i < pages.length; i++)
	{
		if (searchBookName != "" && searchBookName != books[pages[i].bookId].bookFolderName)
		{
			continue;
		}
		//ヒットした回数
		var times = 0;
		//タイトルがヒットされたかどうかのflag
		var titleHitflag = false;
		//本文がヒットされたかどうかのflag
		var textHitflag = false; 
		//タイトルがヒットされた回数
		var titleHitTimes = 0;
		//本文がヒットされた回数
		var textHitTimes = 0;
		//各検索キーワードの登場回数
		var wordsHitTime = new Array();
		for (j = 0; j < searchWords.length; j++)
		{
			var reg = new RegExp(searchWords[j], "g");
			var textResult = pages[i].regText.match(reg);
			var titleResult = 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;
			}
			wordsHitTime[j] = oneWordHitTime;
		}
		if (isResult(wordsHitTime, 2))
		{
			if (titleHitTimes > 0)
			{
				titleHitflag = true;
			}
			if (textHitTimes > 0)
			{
				textHitflag = true;
			}
			result[result.length] = new SearchResult(pages[i].bookId, i, pages[i].pageTitle, textHitflag, titleHitflag, times);
		}
		//200件以上になると、検索を止めて、出てきた200件を戻る
		if (result.length == 200)
		{
			overMaxCountFlag = true;
			break;
		}
		else
		{
			overMaxCountFlag = false;
		}
	}
	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++)
	{
		if (searchBookName == "" && relatedWords[i].book != -1)
		{
			continue;
		}
		if (searchBookName != "")
		{
			if (relatedWords[i].book == -1) 
			{
				continue;
			} 
			else if (searchBookName != books[relatedWords[i].book].bookFolderName) 
			{
				continue;
			}
		}
		// searchWord is escaped.
		if(escapeWord(relatedWords[i].key) == searchWord)
		{
			related = relatedWords[i].words;
			break;
		}
	}
	
	return related;
}

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

		// searchWord is escaped.
		if(escapeWord(synonyms[i].key)  == searchWord)
		{
			synonym = synonyms[i].words;
			break;
		}
	}
	
	return synonym;
}

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