
// OmniHelp functions for search, OHver 1.0
// Copyright (c) 2008 by Jeremy H. Griffith.  All rights reserved.

var foundSearch = new Array()
var foundTerms = new Array()
var checkHighlight = 0
var foundLastSearch = false
var didSearch = false
var searchDone = false
var lastNewSearch = ""
var lastBoolSearch = ""
var lastDocBoolSearch = ""
var ftsCtrlHigh = 120

function useSearch() {
	currNavCtrl = 2
	writeSearchCtrlFile()
	writeSearchDocFile(false)
	setCookies()
}


function writeSearchCtrlFile() {
	if ((boolSearch == lastBoolSearch) && (lastNavCtrl == 2)) {
		return
	}

	var str = new Sarray()
	var obj = parent.isIE4 ? parent.document.all["leftNavCtrl"] : parent.document.getElementById("leftNavCtrl")
	str.add(ftsCtrlHigh)
	str.add(', *')
	obj.rows = str.out()

	lastNavCtrl = 2
	lastBoolSearch = boolSearch
	var doc = parent.navctrl.document
	doc.open()
	doc.write(parent.docHeader)
	doc.write('<head><title>OmniHelp Nav Control: Search, OHver 0.8</title>\n')
	parent.ctrlCSS(doc)
	doc.write('</head>\n<body class="navctrl"><table class="navctrl">\n')
	writeSearchCtrl(doc)
	doc.write('\n</table></body></html>')
	doc.close()
}

function writeSearchCtrl(doc) {
	var str = new Sarray('<tr>')
	ctrlCount = 1
	if (includeToc) {
		ctrlCount++
		str.add('<th class="nav" width="')
		str.add(widthTocCell)
		str.add('"><a class="navlink" href="javascript:parent.ctrl.useToc()">')
		str.add(ContentsButTxt)
		str.add('</a></th>\n')
	}
	if (includeIdx) {
		ctrlCount++
		str.add('<th class="nav" width="')
		str.add(widthIdxCell)
		str.add('"><a class="navlink" href="javascript:parent.ctrl.useIx()">')
		str.add(IndexButTxt)
		str.add('</a></th>\n')
	}
	str.add('<th class="navx" width="')
	str.add(widthFtsCell)
	str.add('">')
	str.add(SearchButTxt)
	str.add('</th>\n')
	if (includeRel) {
		ctrlCount++
		str.add('<th class="nav" width="')
		str.add(widthRelCell)
		str.add('"><a class="navlink" href="javascript:parent.ctrl.useRel()">')
		str.add(RelatedButTxt)
		str.add('</a></th>\n')
	}
	str.add('</tr><tr><td')
	if (ctrlCount > 1) {
		str.add(' colspan="')
		str.add(ctrlCount)
		str.add('"')
	}
	str.add('><form name="navSearch" method="post" onsubmit="javascript:parent.ctrl.doSearch();return false;">\n')
	str.add('<table class="navfts"><tr><td class="navxsmall">\n')
	str.add('<input class="text" type="text" name="searchstring"')
	if (lastSearch.length > 0) {
		str.add(' value="')
		str.add(lastSearch)
		str.add('"')
	}
	str.add(' size="20" />&nbsp;\n')
	str.add('<input class="button" type="submit" value="')
	str.add(FindButTxt)
	str.add('" onClick="javascript:void parent.ctrl.doSearch(); return false" />\n')
	str.add('</td></tr><tr><td class="navxxsmall">\n')
	str.add('<input class="radio" type="radio" name="bools" value="new"')
	if (boolSearch == "new") {
		str.add(' checked="checked"')
	}
	str.add(' onclick="javascript:parent.ctrl.setSearch(\'new\')" />')
	str.add(NewButTxt)
	str.add('\n<input class="radio" type="radio" name="bools" value="and"')
	if (boolSearch == "and") {
		str.add(' checked="checked"')
	}
	str.add(' onclick="javascript:parent.ctrl.setSearch(\'and\')" />')
	str.add(ANDButTxt)
	str.add('\n<input class="radio" type="radio" name="bools" value="or"')
	if (boolSearch == "or") {
		str.add(' checked="checked"')
	}
	str.add(' onclick="javascript:parent.ctrl.setSearch(\'or\')" />')
	str.add(ORButTxt)
	str.add('\n<input class="radio" type="radio" name="bools" value="not"')
	if (boolSearch == "not") {
		str.add(' checked="checked"')
	}
	str.add(' onclick="javascript:parent.ctrl.setSearch(\'not\')" />')
	str.add(NOTButTxt)
	str.add('\n</td></tr><tr><td><p class="ftsm">')
	if (parent.listButton) {
		str.add('<button type="button" id="ftsList"')
		str.add(' onClick="javascript:parent.ctrl.doList()">')
		str.add(ListButTxt)
		str.add('</button>\n')
	}
	str.add(EnterSearchMsg)
	str.add('</p></td></tr></table></form></td></tr>\n')

	doc.write(str.out())
}

function setSearch(str) {
	boolSearch = str
	setCookies()
}


function doList() {
	writeSearchDocFile(true)
	return false
}


function doSearch() {
	lastSearch = parent.navctrl.document.navSearch.searchstring.value
	didSearch = true
	searchDone = false
	writeSearchDocFile(false)
	setCookies()
	return false
}


function writeSearchDocFile(list) {
	lastNavDoc = 2
	var doc = parent.nav.document
	doc.open()
	doc.write(parent.docHeader)
	doc.write('<head><title>OmniHelp Search File, OHver 0.8</title>\n')
	parent.ctrlCSS(doc)
	doc.write('</head>\n<body class="nav">\n')
	if (ftsItems.length == 0) {
		doc.write('<p class="fts">', NoSearchMsg, '</p>')
	} else if (list) {
		writeSearchTermList(doc)
	} else if (didSearch) {
		writeSearchItems(doc)
	}
	doc.write('\n</body></html>')
	doc.close()

	setTimeout("parent.nav.scrollTo(0,0)", 2000)
}


function writeSearchItems(doc) {
	var itemNum = 0
	var searchStr = ''
	var wordDat = new Array()
	var searchWord = new Array()
	var searchWordFound = false
	var searchWordPos = 0
	var regEx = false
	var searchEx = new RegExp('.*')
	var searchList = new Array()
	var i = 0
	var str = new Sarray()

	function mergeRefs(oRef, aRef) {
		var nRef = new Array()
		var oPos = 0
		var aPos = 0
		var nPos = 0
		var oLen = oRef.length
		var aLen = aRef.length

		while ((oPos < oLen) || (aPos < aLen)) {
			if ((oPos < oLen) && (aPos < aLen)) {
				if (oRef[oPos] == aRef[aPos]) {
					nRef[nPos] = oRef[oPos]
					oPos++
					aPos++
				} else if (oRef[oPos] < aRef[aPos]) {
					nRef[nPos] = oRef[oPos]
					oPos++
				} else {
					nRef[nPos] = aRef[aPos]
					aPos++
				}
			} else if (aPos >= aLen) {
				nRef[nPos] = oRef[oPos]
				oPos++
			} else {
				nRef[nPos] = aRef[aPos]
				aPos++
			}
			nPos++
		}
		return nRef
	}


	if (searchDone) {
		// just redisplay last results if any
		if (!foundLastSearch) {
			writeSearchFailed(doc)
		} else {
			foundLastSearch = false
			for (itemNum = 0 ; itemNum < tocItems.length ; itemNum++) {
				if (foundSearch[itemNum]) {
					writeOneSearchItem(doc, itemNum)
				}
			}
		}
		return
	}

	foundLastSearch = false
	searchDone = true

	// find array for word(s) in searchWords[]
	var fullSearchStr = lastSearch.toLowerCase()
	var searchArr = fullSearchStr.split(" ")
	var searchNum = 0
	var searchType = boolSearch

	for (searchNum = 0; searchNum < searchArr.length; searchNum++) {
		searchStr = searchArr[searchNum]
		if (searchStr.length == 0) {
			continue
		}

		if (!lastNewSearch && (searchType != "new")) {
			searchType = "new"
			parent.navctrl.document.navSearch.bools[0].checked = true
		}

		if (searchType == "new") {
			foundTerms.length = 0
		}

		searchWordFound = false
		searchWordPos = 0
		regEx = (searchStr.charAt(0) == '/')

		if (regEx) {
			var term = searchStr.lastIndexOf('/')
			if (term > 1) {
				searchEx = new RegExp(searchStr.substring(1, term))
			} else {
				searchEx = new RegExp(searchStr.substring(1))
			}
			for (itemNum = 0 ; itemNum < ftsItems.length ; itemNum++) {
				wordDat = ftsItems[itemNum]
				if (wordDat[0].match(searchEx)) {
					if (searchType != "not") {
						foundTerms[foundTerms.length] = wordDat[0]
					}
					searchWord = mergeRefs(searchWord, wordDat[1])
					searchWordFound = true
				}
			}
		} else {
			for (itemNum = 0 ; itemNum < ftsItems.length ; itemNum++) {
				wordDat = ftsItems[itemNum]
				if (searchStr == wordDat[0]) {
					if (searchType != "not") {
						foundTerms[foundTerms.length] = searchStr
					}
					searchWord = wordDat[1]
					searchWordFound = true
					break
				}
			}
		}

		if (searchType != "new") {
			str.add(lastNewSearch)
			str.add(' ')
			str.add((searchType == "and") ? ANDButTxt : ((searchType == "or") ? ORButTxt : NOTButTxt))
			str.add(' ')
		}
		str.add('"')
		str.add(searchStr)
		str.add('"')
		lastNewSearch = str.out()
		str.clear()

		if (searchWordFound) {
			if (searchType == "new") {
				for (itemNum = 0 ; itemNum < tocItems.length ; itemNum++) {
					foundSearch[itemNum] = false
					if ((searchWordPos < searchWord.length) && (itemNum == searchWord[searchWordPos])) {
						if (checkCondToc(itemNum)) {
							foundSearch[itemNum] = true
						}
						searchWordPos++
					}						
				}
			} else if (searchType == "and") {
				for (itemNum = 0 ; itemNum < tocItems.length ; itemNum++) {
					if (foundSearch[itemNum]) {
						while ((searchWordPos < searchWord.length) && (itemNum > searchWord[searchWordPos])) {
							searchWordPos++
						}
						if ((searchWordPos >= searchWord.length) || (itemNum < searchWord[searchWordPos])) {
							foundSearch[itemNum] = false
						} else {
							searchWordPos++
						}
					}
				}
			} else if (searchType == "or") {
				for (itemNum = 0 ; itemNum < tocItems.length ; itemNum++) {
					if (foundSearch[itemNum] == false) {
						if ((itemNum == searchWord[searchWordPos]) && checkCondToc(itemNum)) {
							foundSearch[itemNum] = true
							searchWordPos++
						}
					}
				}
			} else if (searchType == "not") {
				for (itemNum = 0 ; itemNum < tocItems.length ; itemNum++) {
					if (foundSearch[itemNum]) {
						while ((searchWordPos < searchWord.length) && (itemNum > searchWord[searchWordPos])) {
							searchWordPos++
						}
						if ((searchWordPos < searchWord.length) && (itemNum == searchWord[searchWordPos])) {
							foundSearch[itemNum] = false
							searchWordPos++
						}
					}
				}
			}
		} else {  // not found
			if ((searchType == "new") || (searchType == "and")) {
				foundTerms.length = 0
				for (itemNum = 0 ; itemNum < tocItems.length ; itemNum++) {
					foundSearch[itemNum] = false
				}
			}
		}

		searchType = "and"
	}

	for (itemNum = 0 ; itemNum < tocItems.length ; itemNum++) {
		if (foundSearch[itemNum] == true) {
			writeOneSearchItem(doc, itemNum)
		}
	}

	if (!foundLastSearch) {
		writeSearchFailed(doc)
		foundTerms.length = 0
	}
}


function writeOneSearchItem(doc, num) {
	if (!foundLastSearch) {
		doc.write('<p class="fts">', SearchResultsMsg)
		doc.write(lastNewSearch)
		doc.writeln(':<br /></p>')
		foundLastSearch = true
	}

	var str = new Sarray('<p class="fts" title="')
	str.add(tocItems[num][1])
	str.add('"><a href="javascript:parent.ctrl.setFtsDoc(')
	str.add(num)
	str.add(')">')
	str.add(tocItems[num][1])
	str.add('</a></p>')
	doc.write(str.out())
}

function setFtsDoc(num) {
	setDoc(num)
	if (parent.ftsHighlight)
		setTimeout("docFtsHighlight()", 500)
}


function docFtsHighlight() {
	var term = 0
	var doc = parent.main.document
	var txt = ""
	var rtxt = new Sarray()
	var ltxt = ""
	var str = ""
	var pos = -1
	var len = 0

	if (foundTerms.length == 0) {
		return
	}

	if (!doc.body || (typeof(doc.body.innerHTML) == "undefined")) {
		if (checkHighlight > 5) {
			checkHighlight = 0
		} else {
			checkHighlight++
			setTimeout("docFtsHighlight()", 500)
		}
		return
	}
	checkHighlight = 0

	txt = doc.body.innerHTML
	for (term = 0; term < foundTerms.length; term++) {
		str = foundTerms[term]
		len = str.length
		if (!len) {
			continue
		}
		ltxt = txt.toLowerCase()
		while (txt.length > 0) {
			pos = ltxt.indexOf(str, pos + 1)
			if (pos < 0) {  // no matches left
				rtxt.add(txt)
				break
			} else if ((txt.lastIndexOf('>', pos) < txt.lastIndexOf('<', pos)) // match in tag or JS
				 || (ltxt.lastIndexOf('/script>', pos) < ltxt.lastIndexOf('<script', pos))
				 || alphanum(ltxt.charAt(pos + len))  // or match is within a word
				 || ((pos > 0) && alphanum(ltxt.charAt(pos - 1)))) {
				pos += len
 			} else {
				rtxt.add(txt.substr(0, pos))
				rtxt.add('<span style="')
				rtxt.add(parent.ftsHighlightStyle)
				rtxt.add('">')
				rtxt.add(txt.substr(pos, len))
				rtxt.add('</span>')
				txt = txt.substr(pos + len)
				ltxt = ltxt.substr(pos + len)
				pos = -1
			}
		}
		txt = rtxt.out()
		rtxt.clear()
	}

  doc.body.innerHTML = txt;
}

function alphanum(ch) {
	if (((ch >= "a") && (ch <= "z"))
	 || ((ch >= "0") && (ch <= "9")))
		return true;
	return false;
}

function writeSearchFailed(doc) {
	if (boolSearch != "new") {
		boolSearch = "new"
		parent.navctrl.document.navSearch.bools[0].checked = true
	}
	doc.write('<p class="fts">', NoSearchResultsMsg)
	doc.write(lastNewSearch)
	doc.writeln('.</p>')
}

function writeSearchTermList(doc) {
	var itemNum = 0
	var wordDat = new Array()
	var str = new Sarray()

	doc.write('<p class="fts">', SearchTermsMsg, '<br />')
	for (itemNum = 0 ; itemNum < ftsItems.length ; itemNum++) {
		wordDat = ftsItems[itemNum]
		str.add('<br /><a href="javascript: void parent.ctrl.setTerm(\'')
		str.add(wordDat[0])
		str.add('\')">')
		str.add(wordDat[0])
		str.add(' (')
		str.add(wordDat[1].length)
		str.add(')</a>\n')
		doc.write(str.out())
		str.clear()
	}
	doc.write('</p>')
}

function setTerm(link) {
	lastSearch = link
	parent.navctrl.document.navSearch.searchstring.value = lastSearch
	setCookies()
}


// end of ohfts.js

