// Public functions --------------------------------

// spellCheck - spell check a field
function spellCheck(formName, fieldName, spelltext)
{
	var spellform = document.forms['spell_form'];

	spellform.spell_formname.value = formName;
	spellform.spell_fieldname.value = fieldName;
	spellform.spellstring.value = document.forms[formName][fieldName].value;

	openSpellWin(640, 480);
	spellform.submit();

	return true;
}

// Private functions -------------------------------

// globals
var wordindex = -1, offsetindex = 0;
var ignoredWords = [];

// misspelled word object
function misp(word, start, end, suggestions)
{
	// The word, start index, end index, and array of suggestions.
	this.word = word;
	this.start = start;
	this.end = end;
	this.suggestions = suggestions;
}

// replace the word in the misps array at the "wordindex" index.  The
// misps array is generated by a PHP script after the string to be spell
// checked is evaluated with pspell
function replaceWord()
{
	var frm = document.fm1;
	var strstart = '';
	var strend;

	// if this isn't the beginning of the string then get all of the string
	// that is before the word we are replacing
	if (misps[wordindex].start != 0)
		strstart = mispstr.slice(0, misps[wordindex].start + offsetindex);

	// get the end of the string after the word we are replacing
	strend = mispstr.slice(misps[wordindex].end + 1 + offsetindex);

	// rebuild the string with the new word
	mispstr = strstart +  frm.changeto.value  + strend;

	// update offsetindex to compensate for replacing a word with a word
	// of a different length.
	offsetindex += frm.changeto.value.length - misps[wordindex].word.length;

	// update the word so future replaceAll calls don't change it
	misps[wordindex].word = frm.changeto.value;

	nextWord(false);
}

// replaces all instances of currently selected word with contents chosen by user.
// note: currently only replaces words after highlighted word.  I think we can re-index
// all words at replacement or ignore time to have it wrap to the beginning if we want
// to.
function replaceAll()
{
	var frm = document.fm1;
	var strstart = '';
	var strend;
	var idx;
	var origword;
	var localoffsetindex = offsetindex;

	origword = misps[wordindex].word;

	// reindex everything past the current word
	for (idx = wordindex; idx < misps.length; idx++)
	{
		misps[idx].start += localoffsetindex;
		misps[idx].end += localoffsetindex;
	}

	localoffsetindex = 0;

	for (idx = 0; idx < misps.length; idx++)
	{
		if (misps[idx].word == origword)
		{
			if (misps[idx].start != 0)
				strstart = mispstr.slice(0, misps[idx].start + localoffsetindex);

			// get the end of the string after the word we are replacing
			strend = mispstr.slice(misps[idx].end + 1 + localoffsetindex);

			// rebuild the string with the new word
			mispstr = strstart +  frm.changeto.value  + strend;

			// update offsetindex to compensate for replacing a word with a word
			// of a different length.
			localoffsetindex += frm.changeto.value.length - misps[idx].word.length;
		}

		// we have to re-index everything after replacements
		misps[idx].start += localoffsetindex;
		misps[idx].end += localoffsetindex;
	}

	// add the word to the ignore array
	ignoredWords[origword] = true;

	// reset offsetindex since we reindexed
	offsetindex = 0;

	nextWord(false);
}

// highlight the word that was selected using the nextWord function
function highlightWord()
{
	var strstart = '';
	var strend;

	// if this isn't the beginning of the string then get all of the string
	// that is before the word we are replacing

	if (misps[wordindex].start != 0)
		strstart = mispstr.slice(0, misps[wordindex].start + offsetindex);

	// get the end of the string after the word we are replacing

	strend = mispstr.slice(misps[wordindex].end + 1 + offsetindex);

	// rebuild the string with a span wrapped around the misspelled word
	// so we can highlight it in the div the user is viewing the string in

	var divptr, newValue;
	divptr = document.getElementById("spellview");

	newValue = un_htmlspecialchars(strstart) + '<span class="highlight" id="h1">' + misps[wordindex].word + '</span>' + un_htmlspecialchars(strend);
	setInnerHTML(divptr, newValue.replace(/_\|_/g, '<br />'));

	var spellview_height = typeof(document.getElementById("spellview").currentStyle) != "undefined" ? parseInt(document.getElementById("spellview").currentStyle.height) : document.getElementById("spellview").offsetHeight;
	var word_position = document.getElementById("h1").offsetTop;
	var current_position = document.getElementById("spellview").scrollTop;

	// The spellview is not tall enough!  Scroll down!
	if (spellview_height <= (word_position + current_position))
		document.getElementById("spellview").scrollTop = word_position + current_position - spellview_height + 32;
}

// Called by onLoad handler to start the process of evaluating misspelled words.
function startsp()
{
	nextWord(false);
}

function getCorrectedText()
{
	return mispstr;
}

// Display the next misspelled word to the user and populate the suggested spellings box.
function nextWord(ignoreall)
{
	var frm = document.fm1;
	var sug = document.fm1.suggestions;
	var sugidx = 0;
	var newopt;
	var isselected = 0;

	// Push ignored word onto ignoredWords array.
	if (ignoreall)
		ignoredWords[misps[wordindex].word] = true;

	// update the index of all words we have processed
	// This must be done to accomodate the replaceAll function.
	if (wordindex >= 0)
	{
		misps[wordindex].start += offsetindex;
		misps[wordindex].end += offsetindex;
	}

	// increment the counter for the array of misspelled words
	wordindex++;

	// draw it and quit if there are no more misspelled words to evaluate
	if (misps.length <= wordindex)
	{
		var divptr;
		divptr = document.getElementById("spellview");
		setInnerHTML(divptr, un_htmlspecialchars(mispstr).replace(/_\|_/g, "<br />"));

		clearBox(sug);
		alert(txt['done']);
		frm.change.disabled = true;
		frm.changeall.disabled = true;
		frm.ignore.disabled = true;
		frm.ignoreall.disabled = true;

		// put line feeds back
		mispstr = mispstr.replace(/_\|_/g, "\n");

		// get a handle to the field we need to re-populate
		window.opener.document.forms[spell_formname][spell_fieldname].value = mispstr;
		window.close();
		return true;
	}

	// check to see if word is supposed to be ignored
	if (typeof(ignoredWords[misps[wordindex].word]) != "undefined")
	{
		nextWord(false);
		return false;
	}

	// clear out the suggestions box
	clearBox(sug);

	// re-populate the suggestions box if there are any suggested spellings for the word
	if (misps[wordindex].suggestions.length)
	{
		for (sugidx = 0; sugidx < misps[wordindex].suggestions.length; sugidx++)
		{
			if (sugidx == 0)
				isselected = 1;
			else
				isselected = 0;
			newopt = new Option(misps[wordindex].suggestions[sugidx], misps[wordindex].suggestions[sugidx], 0, isselected);
			sug.options[sugidx] = newopt;

			if (isselected)
			{
				frm.changeto.value = misps[wordindex].suggestions[sugidx];
				frm.changeto.select();
			}
		}
	}
	highlightWord();

	return false;
}

function un_htmlspecialchars(thetext)
{
	thetext = thetext.replace(/\</g, "&lt;");
	thetext = thetext.replace(/\>/g, "&gt;");
	thetext = thetext.replace(/\n/g, "<br />");
	thetext = thetext.replace(/\ \ /g, " &nbsp;");

	return thetext;
}

// remove all items from the suggested spelling box
function clearBox(box)
{
	var length = box.length;

	// delete old options -- remember that select boxes automatically re-index
	for (var i = 0; i < length; i++)
		box.options[0] = null;
}

function openSpellWin(width, height)
{
	window.open("", "spellWindow", "toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=yes,resizable=no,width=" + width + ",height=" + height);
}