//<!-- <script type="text/javascript"> -->

//=============================================================================
// Utilities onsubmit="updateRTE('msg');


// test the browser model
var oRTE = {};
var count = 0;
function updateRTE(rte, hdnElem) 
{
	var oHdnMessage;
	var oHdnMessage_html;
	
	oHdnMessage = document.getElementById(hdnElem);
	oRTE = document.getElementById(rte);
	//set message value
	if(oRTE.contentDocument)
	oHdnMessage_html = oRTE.contentDocument.lastChild.lastChild.innerHTML
	else
	oHdnMessage_html = document.frames[rte].document.body.innerHTML;
	
	if (escape(oHdnMessage.value) == "%3Cbr%3E%0D%0A%0D%0A%0D%0A") 
	{
		oHdnMessage_html.value = "";
	}

	oHdnMessage.value = stripHTML(stripSPAN(oHdnMessage_html));
}

function stripHTML(oldString) 
{
//   var newString = oldString.replace(/<(?!(?:br|!))[^>]*>/ig,"");
//   newString = newString.replace(/\r\n/g," ");
//   newString = newString.replace(/\n/g," ");
   var newString = oldString.replace(/<p>/ig,"");
   newString = newString.replace(/<\/p>/ig,"\n");
   newString = newString.replace(/&nbsp;/ig, " ");
   newString = trim(newString);

   return newString;
}

function stripSPAN(oldString) 
{
   var stripped = oldString.replace(/(<[\/]?span([^>]*)>)/ig,"");
   stripped = stripped.replace(/(<br([^>]*)[\/]?>)/ig,"\n");
   return stripped;
}

function trim(inputString) {
   // Removes leading and trailing spaces from the passed string. Also removes
   // consecutive spaces and replaces it with one space. If something besides
   // a string is passed in (null, custom object, etc.) then return the input.
   if (typeof inputString != "string") return inputString;
   var retValue = inputString;
   var ch = retValue.substring(0, 1);

   while (ch == " ") { // Check for spaces at the beginning of the string
      retValue = retValue.substring(1, retValue.length);
      ch = retValue.substring(0, 1);
   }
   ch = retValue.substring(retValue.length - 1, retValue.length);

   while (ch == " ") { // Check for spaces at the end of the string
      retValue = retValue.substring(0, retValue.length - 1);
      ch = retValue.substring(retValue.length - 1, retValue.length);
   }

	// Note that there are two spaces in the string - look for multiple spaces within the string
   while (retValue.indexOf("  ") != -1) {
		// Again, there are two spaces in each of the strings
      retValue = retValue.substring(0, retValue.indexOf("  ")) + retValue.substring(retValue.indexOf("  ") + 1, retValue.length);
   }
   return retValue; // Return the trimmed string back to the user
}

function setStyle(style)
{
	oRE.setStyle(style);
	oRE.focus();
}

var bIsNetscape = (navigator.appName == "Netscape");

function clrdebug()
{
	var oDbg = document.getElementById('debug');
	if ( oDbg ) oDbg.innerHTML = '';
}
function debug(txt)
{
	var oDbg = document.getElementById('debug');
	if ( oDbg ) oDbg.innerHTML += txt + '<br>'
}
function debugObj(o)
{
	for ( var i in o )
	{
		if ( bIsNetscape && (typeof(i) == 'string') )
		{
			if ( i.substr(0,4) == 'DOM_' ) continue;
		}
		debug( i + ':' + o[i] );
	}
}

//=============================================================================
// RichEdit constructor
function RichEdit(name, editStyle, charStyle, sText)
{
	// initialise some internal values
	this.bInFocus = false;

	// save the character style for later
	this.style = charStyle;

	// create an insertion point.
	document.write('<div id="' + name + '"></div>');
	this.oInsertionPoint = document.getElementById(name);

	// the 'text' box - or where the text goes
	this.oDiv = document.createElement('div');

	// set the styles
	this.copyStyle(this.oDiv, editStyle);
	this.oDiv.style.overflow = "auto";
	this.oDiv.style.wordWrap = "break-word";
	//this.oDiv.style.whiteSpace = "moz-pre-wrap";

	// insert the text
	if ( sText ) this.setHTML(sText);

	// link back to this object
	this.oDiv.oRichEdit = this;

	// handle clicks
	this.oDiv.onclick = RichEdit.prototype.onDivClick;

	if ( bIsNetscape )
	{
		// In Netscape, <div> elements don't have keyboard events, so
		// create a small, hidden text <input> box to catch them
		var oTextSpan = document.createElement('span');
		oTextSpan.style.position = 'absolute';
		oTextSpan.style.visibility = 'hidden';

		this.oTextbox = document.createElement('input');
		this.oTextbox.type = 'text';
		this.oTextbox.style.width = "1px";
		oTextSpan.appendChild(this.oTextbox);
		this.oInsertionPoint.appendChild(oTextSpan);

		// add event handlers
		this.oTextbox.oRichEdit = this;
		this.oTextbox.onkeypress = RichEdit.prototype.onDivKeyPress; // changed to onDivKeyDown
		this.oTextbox.onkeydown = RichEdit.prototype.onDivKeyDown;
		this.oTextbox.onfocus = RichEdit.prototype.onDivFocus;
		this.oTextbox.onblur = RichEdit.prototype.onDivBlur;
	}
	else
	{
		// in IE, just attache everything to the <div>
		this.oDiv.onkeypress = RichEdit.prototype.onDivKeyPress;
		this.oDiv.onkeydown = RichEdit.prototype.onDivKeyDown;
		this.oDiv.onfocus = RichEdit.prototype.onDivFocus;
		this.oDiv.onblur = RichEdit.prototype.onDivBlur;
	}

	// create the cursor
	this.oCursor = document.createElement('span');
	this.copyStyle(this.oCursor, this.style);
	this.oCursor.innerHTML = '|';

	this.oCursor.style.position = 'relative';
	this.oCursor.style.verticalAlign = 'bottom';
	//this.oCursor.style.float = 'left';

	// <blink> is a Netscape thing, so... DIY
	var oCursor = this.oCursor;
	window.setTimeout(function(){RichEdit.prototype.onBlinkCursor(oCursor);},500);

	this.oInsertionPoint.appendChild(this.oDiv);
}
RichEdit.prototype.onBlinkCursor = function(oCursor)
{
	if ( oCursor.style.visibility == 'hidden' ) oCursor.style.visibility = 'visible';
	else oCursor.style.visibility = 'hidden';

	window.setTimeout(function(){RichEdit.prototype.onBlinkCursor(oCursor);},500);
}

RichEdit.prototype.focus = function()
{
	// grab the input focus
	if ( bIsNetscape ) this.oTextbox.focus();
	else this.oDiv.focus();
}

RichEdit.prototype.getCursorPos = function()
{
	// return an object describing the current cursor position:
	//    previous: the node before the cursor
	//    current: the current node
	//    next: the node following the cursor
	//    insert: A node to insert new nodes before. Not always the same as current
	if ( this.bInFocus )
	{
		var oParent = this.oCursor.parentNode;
		if ( oParent == this.oDiv )
		{
			// this can happen when an element other than <span> is current.
			var oCurrent = this.oCursor.nextSibling;
			var oNext = oCurrent ? oCurrent.nextSibling : null;
			return {prev:this.oCursor.previousSibling,current:oCurrent,next:oNext,insert:this.oCursor};
		}
		if ( !oParent )
		{
			return {prev:this.oDiv.lastChild,current:null,next:null,insert:null};
		}
		return {prev:oParent.previousSibling,current:oParent,next:oParent.nextSibling,insert:oParent};
	}

	if ( !this.oLastCursorPos )
	{
		this.oLastCursorPos = {prev:this.oDiv.lastChild,current:null,next:null,insert:null};
	}
	return this.oLastCursorPos;
}
RichEdit.prototype.assimilateStyle = function(oElt)
{
	if ( !oElt ) oElt = this.oDiv.lastChild;

	// when the cursor moves, it is natural that it should take on
	// the style of its surroundings
	while ( oElt && oElt.previousSibling && (!oElt.bHasStyle || (oElt == this.oCursor)) )
	{
		oElt = oElt.previousSibling;
	}
	if ( oElt && oElt.tagName.toLowerCase() == 'span' )
	{
		this.setStyle(oElt.style);
		if ( this.onstylechange != undefined ) this.onstylechange(this.style);
	}
}
RichEdit.prototype.setCursorPos = function(oSpan, bCopyStyle)
{
	// set the position of the cursor to just before oSpan
	// or if null/undefined, append to the end.
	var oElt;
	bCopyStyle = false;
	if ( oSpan )
	{
		if ( this.bInFocus )
		{
			if ( oSpan.tagName.toLowerCase() != 'span' ) this.oDiv.insertBefore(this.oCursor, oSpan);
			else if ( oSpan.firstChild ) oSpan.insertBefore(this.oCursor, oSpan.firstChild);
			else oSpan.appendChild(this.oCursor);
		}
		else this.oLastCursorPos = {prev:oSpan.previousSibling,current:oSpan,next:oSpan.nextSibling,insert:oSpan};
		oElt = oSpan;
	}
	else
	{
		oElt = this.oDiv.lastChild;
		if ( this.bInFocus ) this.oDiv.appendChild(this.oCursor);
		else this.oLastCursorPos = null;
	}

	if ( (bCopyStyle == undefined) || (bCopyStyle == true) ) this.assimilateStyle(oElt);
}

RichEdit.prototype.onBlur = function()
{
	// when focus goes somewhere else, record the last position
	// and hide the cursor
	this.oLastCursorPos = this.getCursorPos();

	// insert can sometimes be the cursor itself and since this
	// is being removed, copy current.
	this.oLastCursorPos.insert = this.oLastCursorPos.current;

	this.bInFocus = false;
	this.oCursor.parentNode.removeChild(this.oCursor);
	inform = false;
}
RichEdit.prototype.onFocus = function()
{
	// focus has returned, so re-insert the cursor
	var oPos = this.getCursorPos();
	this.bInFocus = true;
	this.setCursorPos(oPos.current, false);
	inform = true;
}
RichEdit.prototype.copyStyle = function(oElt, style, template)
{
	// the template is used to determine what to copy
	if ( !template ) template = style;

	// set the styles
	for ( var iStyle in template )
	{
		if ( style[iStyle] != undefined ) oElt.style[iStyle] = style[iStyle];
	}
	oElt.bHasStyle = true;
}
RichEdit.prototype.setStyle = function(style)
{
	this.copyStyle(this, style, this.style);
	this.copyStyle(this.oCursor, style, this.style);
}
RichEdit.prototype.compareStyle = function(oSpan1, oSpan2)
{
	// return true if the style of the spans is equivalent
	var style1 = oSpan1.style;
	var style2 = oSpan2.style;

	// equivalence depends only on the styles we are interested in.
	for ( var iStyle in this.style )
	{
		if ( style1[iStyle] !== style2[iStyle] ) return false;
	}
	return true;
}
RichEdit.prototype.insertNode = function(oNode)
{
	// insert a node at the current insertion point.
	var oPos = this.getCursorPos();
	if ( oPos.insert ) this.oDiv.insertBefore(oNode, oPos.insert);
	else this.oDiv.appendChild(oNode);

	// any node inserted into the document must notify the control
	// when it is clicked on so that the cursor may be moved
	oNode.onclick = RichEdit.prototype.onSpanClick;
	oNode.oRichEdit = this;
}
RichEdit.prototype.insertText = function(sText, oStyle)
{
	// insert a text string
	if ( !oStyle ) oStyle = this.style;

	var n = sText.length;
	for ( var i = 0; i < n; i++ )
	{
		// for each character, insert a new <span> element with current style
		var oSpan = document.createElement('span');
		this.copyStyle(oSpan, oStyle, this.style);
		var c = sText.charAt(i);

		// not all keyboard characters translate well to HTML text
		switch ( c )
		{
		case '\n':	oSpan = document.createElement('br');	break;
		case ' ':	oSpan.innerHTML = '&nbsp;';				break;
		case '<':	oSpan.innerHTML = '&lt;';				break;
		case '>':	oSpan.innerHTML = '&gt;';				break;
		case '&':	oSpan.innerHTML = '&amp;';				break;
		case '"':	oSpan.innerHTML = '&quot;';				break;
		case "'":	oSpan.innerHTML = '&#39;';				break;
		default:	oSpan.innerHTML = c;					break;
		}
		this.insertNode(oSpan);
	}
}
RichEdit.prototype.onKeyPress = function(evt)
{
	// handle keyboard events

	// in Netscape, handle movement keys here
	//if(count == 0)
	//	event.keyCode = 36;
	//count++;
	
	if ( bIsNetscape && this.onKeyDown(evt) ) return;

	var keyCode = evt.keyCode || evt.which;
	if ( keyCode == 13 ) // return
	{
		// insert a line break before the cursor
		this.insertNode(document.createElement('br'));
		if (document.all)
		{
		  window.event.cancelBubble = true;
      	  window.event.returnValue = false;
		}
		else
		{
		  evt.preventDefault();
		}
	}
	else
	{
		var key = String.fromCharCode(keyCode).toLowerCase();
		var oStyle = {};
  	switch (key)
    {
      case 'a':
      oStyle = {color:"#ffff00", backgroundColor:"#ffff00"};
      break;
      case 'b':
      oStyle = {color:"#3399cc",backgroundColor:"#3399cc"};
      break;
      case 'c':
      oStyle = {color:"#ffccff",backgroundColor:"#ffccff"};
      break;
      case 'd':
      oStyle = {color:"#cccccc",backgroundColor:"#cccccc"};
      break;
      case 'e':
      oStyle = {color:"#ff9900",backgroundColor:"#ff9900"};
      break;
      case 'f':
      oStyle = {color:"#ffcc99",backgroundColor:"#ffcc99"};
      break;
      case 'g':
      oStyle = {color:"#d21894",backgroundColor:"#d21894"};
      break;
      case 'h':
      oStyle = {color:"#ffff99",backgroundColor:"#ffff99"};
      break;
      case 'i':
      oStyle = {color:"#66ff66",backgroundColor:"#66ff66"};
      break;
      case 'j':
      oStyle = {color:"#ff9999",backgroundColor:"#ff9999"};
      break;
      case 'k':
      oStyle = {color:"#330033",backgroundColor:"#330033"};
      break;
      case 'l':
      oStyle = {color:"#ff0000",backgroundColor:"#ff0000"};
      break;
      case 'm':
      oStyle = {color:"#ccff00",backgroundColor:"#ccff00"};
      break;
      case 'n':
      oStyle = {color:"#cc9966",backgroundColor:"#cc9966"};
      break;
      case 'o':
      oStyle = {color:"#999999",backgroundColor:"#999999"};
      break;
      case 'p':
      oStyle = {color:"#ccffcc",backgroundColor:"#ccffcc"};
      break;
      case 'q':
      oStyle = {color:"#cc3300",backgroundColor:"#cc3300"};
      break;
      case 'r':
      oStyle = {color:"#ff66cc",backgroundColor:"#ff66cc"};
      break;
      case 's':
      oStyle = {color:"#99ccff",backgroundColor:"#99ccff"};
      break;
      case 't':
      oStyle = {color:"#3366cc",backgroundColor:"#3366cc"};
      break;
      case 'u':
      oStyle = {color:"#ffff66",backgroundColor:"#ffff66"};
      break;
      case 'v':
      oStyle = {color:"#0000ff",backgroundColor:"#0000ff"};
      break;
      case 'w':
      oStyle = {color:"#009900",backgroundColor:"#009900"};
      break;
      case 'x':
      oStyle = {color:"#996666",backgroundColor:"#996666"};
      break;
      case 'y':
      oStyle = {color:"#ff6666",backgroundColor:"#ff6666"};
      break;
      case 'z':
      oStyle = {color:"#cccc66",backgroundColor:"#cccc66"};
      break;
		  default:
		  oStyle = {color:'#ffffff'};
    }
		// insert the character before the cursor
		if (keyCode != 8 /*&& !(keyCode >= 33 && keyCode <= 46) */ )
		{
			this.insertText(key, oStyle);
		}
		
		//this.onKeyDown(evt);
		
	}
	// keep the cursor in view.
	this.seeCursor();
	return false;
}

RichEdit.prototype.moveTop = function()
{
	if(bIsNetscape)
	{
		this.setCursorPos(this.oDiv.firstChild);
	}
	else
	{
		var oPos = this.getCursorPos();
		var oPrev = oPos.prev;
		var oNext = oPos.next;
		var oNext2, oPrev2;
		var nLeft = this.oCursor.offsetLeft;
		var nTop = this.oCursor.offsetTop;

		oPrev = oPos.current;
		while ( oPrev )
		{
			if ( oPrev.offsetLeft == 0 )
			{
				this.setCursorPos(oPrev);
			}
			oPrev = oPrev.previousSibling;
		}
		if ( !oPrev ) this.setCursorPos(this.oDiv.firstChild);
	}
}

RichEdit.prototype.onKeyDown = function(evt)
{
	var bRet = false;
	var keyCode = evt.keyCode;
	//var charCode = evt.charCode || evt.which;

	// find the cursor
	var oPos = this.getCursorPos();

	var oPrev = oPos.prev;
	var oNext = oPos.next;
	var oNext2, oPrev2;
	var nLeft = this.oCursor.offsetLeft;
	var nTop = this.oCursor.offsetTop;
	
	if(keyCode)
	{
	  bRet = true;
		switch ( keyCode )
		{
		case 37: // left arrow
			if ( oPrev ) this.setCursorPos(oPrev);
			else this.setCursorPos(this.oDiv.firstChild);
			break;
		case 39: // right arrow
			this.setCursorPos(oNext);
			break;
		case 38: // up arrow
			// search backwards for a character above and to the left of this one
			while ( oPrev )
			{
				oPrev2 = oPrev.previousSibling;
				if ( !oPrev2 )
				{
					this.setCursorPos(oPrev);
					break;
				}
				if ( (oPrev.tagName.toLowerCase() == 'br') && (oPrev2.offsetLeft < nLeft) )
				{
					this.setCursorPos(oPrev);
					break;
				}
				if ( (oPrev2.tagName.toLowerCase() != 'br') && (oPrev2.offsetTop < nTop) && (oPrev2.offsetLeft <= nLeft) )
				{
					this.setCursorPos(oPrev2);
					break;
				}
				oPrev = oPrev2;
			}
			break;
		case 40: // down arrow
			// search forewards for a character just below the cursor
			while ( oNext )
			{
				oNext2 = oNext.nextSibling;
				if ( !oNext2 )
				{
					this.setCursorPos();
					break;
				}
				if ( oNext2.offsetTop > nTop )
				{
					if ( oNext2.offsetLeft >= nLeft )
					{
						this.setCursorPos(oNext2);
						break;
					}
					// special case, end of the next line
					if ( (oNext2.offsetTop > oNext.offsetTop) && (oNext.tagName.toLowerCase() != 'br') )
					{
						this.setCursorPos(oNext2);
						break;
					}
					if ( oNext2.tagName.toLowerCase() == 'br' )
					{
						this.setCursorPos(oNext2);
						break;
					}
				}
				oNext = oNext2;
			}
			break;
		case 8 : // backsp
			if ( oPrev )
			{
				this.oDiv.removeChild(oPrev);
				//this.assimilateStyle(oPos.current);
				if(document.all)
				{
					window.event.cancelBubble = true;
					window.event.returnValue = false;
				}
			}
			break;
		case 46: // del
			if ( oPos.current )
			{
				this.oDiv.removeChild(oPos.current);
				this.setCursorPos(oPos.next);
			}
			break;
		case 36: // home
			if ( evt.ctrlKey ) this.setCursorPos(this.oDiv.firstChild);
			else
			{
				// search backwards to the beginning of the line
				oPrev = oPos.current;
				while ( oPrev )
				{
					if ( oPrev.offsetLeft == 0 )
					{
						this.setCursorPos(oPrev);
						break;
					}
					oPrev = oPrev.previousSibling;
				}
				if ( !oPrev ) this.setCursorPos(this.oDiv.firstChild);
			}
			break;
		case 35: // end
			if ( evt.ctrlKey ) this.setCursorPos();
			else
			{
				// search forwards to the end of the line
				while ( oNext )
				{
					if ( (oNext.tagName.toLowerCase() == 'br') || (oNext.offsetTop > nTop) )
					{
						this.setCursorPos(oNext);
						break;
					}
					oNext = oNext.nextSibling;
				}
				if ( !oNext ) this.setCursorPos();
			}
			break;
		case 33: // page up
			// implementation left as exercise for the reader
			break;
		case 34: // page down
			// implementation left as exercise for the reader
			break;
		default:
		bRet = false;
			break;
		}
	}
		this.seeCursor();
		return bRet;
}
RichEdit.prototype.seeCursor = function()
{
	var oPos = this.getCursorPos();
	if ( !oPos.insert ) return;

	var sh = this.oDiv.scrollHeight;
	var st = this.oDiv.scrollTop;
	var ot = oPos.insert.offsetTop;

	var dh = this.oDiv.offsetHeight;
	var oh = this.oCursor.offsetHeight;

	// st should be less than ot
	// and greater than ot + oh - dh
	if ( st > ot ) this.oDiv.scrollTop = ot;
	else if ( st < (ot + oh - dh) ) this.oDiv.scrollTop = ot + oh - dh;
}
RichEdit.prototype.getScratchPad = function()
{
	// get a hidden <div> scratch-pad to work on
	if ( !this.oPad )
	{
		this.oPad = document.createElement('div');
		this.oPad.style.position = 'absolute';
		this.oPad.style.visibility = 'hidden';
		this.oInsertionPoint.appendChild(this.oPad);
	}
	else
	{
		// clear anything that might have been there
		this.oPad.innerHTML = '';
	}
	return this.oPad;
}
RichEdit.prototype.getHTML = function()
{
	// return a compact version of HTML contents in text form

	// remove the cursor first
	var oCursorPos = this.getCursorPos();
	if ( this.bInFocus )
	{
		this.oDiv.removeChild(this.oCursor);
	}

	var oPad = this.getScratchPad();

	// iterate through each character-element or image
	// and merge into the scratch-pad
	var oElt = this.oDiv.firstChild;
	var oPost = null;
	while ( oElt )
	{
		if ( oPost &&
			(oPost.tagName.toLowerCase() == 'span') &&
			(oElt.tagName.toLowerCase() == 'span') &&
			this.compareStyle(oPost,oElt) )
		{
			// styles are the same, so merge
			oPost.innerHTML += oElt.innerHTML;
		}
		else
		{
			oPost = oElt.cloneNode(true);
			oPad.appendChild(oPost);
		}
		oElt = oElt.nextSibling;
	}

	if ( this.bInFocus ) this.setCursorPos(oCursorPos.current);

	return oPad.innerHTML;
}
RichEdit.prototype.setHTML = function(sHTML)
{
	if(sHTML == '')
	   return;
	this.oDiv.innerHTML = '';
	this.oLastCursorPos = null;
	this.bInFocus = false;

	// get a hidden scratchpad to work on
	var oPad = this.getScratchPad();
	oPad.innerHTML = sHTML;

	// iterate through each element of oPad and extract text, <br>, <img>, etc
	var oElt = oPad.firstChild;
	if ( oElt.nodeType == 3 ) // text
	{
		this.insertText(sHTML);
	}
	else
	{
		while ( oElt )
		{
			var oNext = oElt.nextSibling;
			if(oElt.nodeType == 3)
			{
				this.insertText(oElt.nodeValue);
			}
			else if ( oElt.tagName.toLowerCase() == 'span' )
			{
				// must convert special HTML codes back to text so they
				// can be translated properly by insertText()
				var sText = oElt.innerHTML.replace('&amp;','&');
				sText = sText.replace('&quot;','"');
				sText = sText.replace('&nbsp;',' ');
				sText = sText.replace('&lt;','<');
				sText = sText.replace('&gt;','>');
				sText = sText.replace('&#39;',"'");

				// insert the text from the element with the element's style
				this.insertText(sText, oElt.style);
			}
			else
			{
				// don't know what it is, so insert it verbatim
				this.insertNode(oElt);
			}

			oElt = oNext;
		}
	}
	if(this.oRichEdit)
			this.oRichEdit.moveTop();
}

//=============================================================================
// Textbox event handlers
RichEdit.prototype.onDivKeyDown = function(e)
{
	// fetch event object
	var evt = e ? e : window.event;
	this.oRichEdit.onKeyDown(evt);
}
RichEdit.prototype.onDivKeyPress = function(e)
{
	// fetch event object
	var evt = e ? e : window.event;
	this.oRichEdit.onKeyPress(evt);
}
RichEdit.prototype.onDivFocus = function()
{
	if(!bIsNetscape)
		this.oRichEdit.moveTop();
	this.oRichEdit.onFocus();
}
RichEdit.prototype.onDivBlur = function()
{
	this.oRichEdit.onBlur();
}
RichEdit.prototype.onDivClick = function()
{
	if ( !this.oRichEdit.bInFocus )
	{
		this.oRichEdit.setCursorPos();
		this.oRichEdit.focus();
		this.oRichEdit.moveTop();
	}		
}
RichEdit.prototype.onSpanClick = function()
{
	this.oRichEdit.setCursorPos(this);
	this.oRichEdit.focus();
}
RichEdit.prototype.insertImage = function(src)
{
	// insert a new <img> element at the current position
	var oImg = document.createElement('img');
	oImg.src = src;

	this.insertNode(oImg);
}
//</script>