////////////////////////////////////////////////////
// wordWindow object
////////////////////////////////////////////////////
function wordWindow() {
	// private properties
	this._form = null;

	// private methods
	this._getWordObject = _getWordObject;
	//this._getSpellerObject = _getSpellerObject;
	this._wordInputStr = _wordInputStr;
	this._adjustIndexes = _adjustIndexes;
	this._isWordChar = _isWordChar;
	this._lastPos = _lastPos;
	
	// public properties
	this.wordChar = /[a-zA-Z]/;
	this.windowType = "wordWindow";
	this.originalSpellings = new Array();
	this.suggestions = new Array();
	this.checkWordBgColor = "pink";
	this.normWordBgColor = "white";
	this.text = "";
	this.indexes = new Array();
	//this.speller = this._getSpellerObject();

	// public methods
	this.resetForm = resetForm;
	this.getTextObjectArray = getTextObjectArray;
	this.getTextVal = getTextVal;
	this.setFocus = setFocus;
	this.removeFocus = removeFocus;
	this.setText = setText;
	this.getTotalWords = getTotalWords;
	this.writeBody = writeBody;
	this.printForHtml = printForHtml;
}

function resetForm() {
	if( this._form ) {
		this._form.reset();
	}
	return true;
}

function getTextObjectArray() {
	return this._form.elements;
}

function getTextVal( wordIndex ) {
	if( this._form ) {
		if( this._form.elements[wordIndex] ) {
			return this._form.elements[wordIndex].value;
		}
	}
}

function setFocus( wordIndex ) {
	var word = this._getWordObject( wordIndex );
	if( word ) {
		if( word.type == "text" ) {
			word.focus();
			word.style.backgroundColor = this.checkWordBgColor;
		}
	}
}

function removeFocus( wordIndex ) {
	var word = this._getWordObject( wordIndex );
	if( word ) {
		if( word.type == "text" ) {
			word.blur();
			word.style.backgroundColor = this.normWordBgColor;
		}
	}
}

function setText( wordIndex, newText ) {
	var word = this._getWordObject( wordIndex );
	var beginStr;
	var endStr;
	if( word ) {
		var pos = this.indexes[wordIndex];
		var oldText = word.value;
		// update the text given the index of the string
		beginStr = this.text.substring( 0, pos );
		endStr = this.text.substring( pos + oldText.length, this.text.length );
		this.text = beginStr + newText + endStr;
		
		// adjust the indexes on the stack given the differences in 
		// length between the new word and old word. 
		var lengthDiff = newText.length - oldText.length;
		this._adjustIndexes( wordIndex, lengthDiff );
		
		word.size = newText.length;
		word.value = newText;
		this.removeFocus( wordIndex );
	}
}

function getTotalWords() {
	return this.originalSpellings.length;
}

function writeBody() {
	var d = window.document;
	var is_html = false;
	var end_idx = 0;
	var begin_idx = 0;
	var wordtxt = new String( this.text );
	var orig = this.originalSpellings;
	if( wordtxt ) {
		d.open();
		d.writeln( '<form>' );

		//!!! plain text, or HTML mode?
		d.writeln( '<div class="plainText">' );
		
		// iterate through each occurrence of a misspelled word. 
		for( var i = 0; i < orig.length; i++ ) {
		
			// find the position of the current misspelled word,
			// starting at the last misspelled word. 
			// and keep looking if it's a substring of another word
			do {
				begin_idx = wordtxt.indexOf( orig[i], end_idx );
				end_idx = begin_idx + orig[i].length;
				// word not found? messed up!
				if( begin_idx == -1 ) break; 
				// look at the characters immediately before and after 
				// the word. If they are word characters we'll keep looking.
				var before_char = wordtxt.charAt( begin_idx - 1 );
				var after_char = wordtxt.charAt( end_idx );
			} while ( 
				this._isWordChar( before_char ) 
				|| this._isWordChar( after_char )
			);

			// keep track of its position in the original text. 
			this.indexes[i] = begin_idx;

			// write out the characters before the current misspelled word
			for( var j = this._lastPos( i ); j < begin_idx; j++ ) {
				// !!! html mode? make it html compatible
				d.write( this.printForHtml( wordtxt.charAt( j )));
			}

			// write out the misspelled word. 
			d.write( this._wordInputStr( orig[i] ));

			// if it's the last word, write out the rest of the text
			if( i == orig.length-1 ){
				d.write( printForHtml( wordtxt.substr( end_idx )));
			}			
		}

		d.writeln( '</div>' );
		d.writeln( '</form">' );
		d.close();
	}
	// set the _form property
	if( d.forms[0] ) {
		this._form = d.forms[0];
	}
}

// return the character index in the full text after the last word we evaluated
function _lastPos( idx) {
	if( idx > 0 )
		return this.indexes[idx-1] + this.originalSpellings[idx-1].length;
	else
		return 0;
}

function printForHtml( n ) {
	var htmlstr = n;
	if( htmlstr.length == 1 ) {
		// do simple case statement if it's just one character
		switch ( n ) {
			case "\n":
				htmlstr = '<br/>';
				break;
			case "<":
				htmlstr = '&lt;';
				break;
			case ">":
				htmlstr = '&gt;';
				break;
		}
		return htmlstr;
	} else {
		htmlstr = htmlstr.replace( /</g, '&lt' );
		htmlstr = htmlstr.replace( />/g, '&gt' );
		htmlstr = htmlstr.replace( /\n/g, '<br/>' );
		return htmlstr;
	}
}

function _isWordChar( letter ) {
	if( letter.search( this.wordChar ) == -1 ) {
		return false;
	} else {
		return true;
	}
}

function _getWordObject( wordIndex ) {
	if( this._form ) {
		if( this._form.elements[wordIndex] ) {
			return this._form.elements[wordIndex];
		}
	}
	return null;
}

function _wordInputStr( word ) {
	var str = '<input readonly ';
	str += 'class="blend" type="text" value="' + word + '" size="' + word.length + '">';
	return str;
}

function _adjustIndexes( wordIndex, lengthDiff ) {
	for( var i = wordIndex + 1; i < this.originalSpellings.length; i++ ) {
		this.indexes[i] = this.indexes[i] + lengthDiff;
	}
}
