//Filename: RichTextEditor.js

//Rich Text Editor v1.0

//November 20, 2002

//

//A rich text editor for <textarea> fields



//global variable: DEBUG for debugging purposes
var DEBUG = false;

//=======================================
// decimalToRGB(decimal)
//=======================================
//Inputs:		decimal			decimal value
//
//Description:	convert a decimal color to hexadecimal
//
//Usage:		decimalToRGB(decimal);
//=======================================
function decimalToRGB(decimal){
  var hex_string = "";
  var theByte;
  var lowNybble;												//nybble = 4 bits
  var highNybble;

  if( DEBUG ){
    alert("Entering the decimalToRGB function\nParameters:\ndecimal = " + decimal);
  }//end if

  for (var hexpair = 0; hexpair < 3; hexpair++) {
    theByte = decimal & 0xFF;            						// get low byte
    decimal >>= 8;                       						// drop low byte
    lowNybble = theByte & 0x0F;          						// get low nybble 
    highNybble = (theByte >> 4) & 0x0F;   						// get high nybble
    hex_string += highNybble.toString(16); 						// convert nybble to hex
    hex_string += lowNybble.toString(16); 						// convert nybble to hex
  }//end for loop

  return hex_string.toUpperCase();

  if( DEBUG ){
    alert("Exiting the decimalToRGB function");
  }//end if

}//function decimalToRGB

//=======================================
// editorAction(buttonID)
//=======================================
//Inputs:		buttonID			ID of the button (with editor and action name)
//
//Description:	perform a command on the selected content
//
//Usage:		editorAction(buttonID);
//=======================================
function editorAction(buttonID){
  var buttons = Array();
  var objTextArea;
  var controlID;
  var objButton;
  var objEditor;
  var editorDocument;
  var index;
  var value;
  var positionX;
  var positionY;
  var screenWidth;
  var screenHeight;
  var position;
  var oldColor;
  var newColor;
  var popWin;

  if( DEBUG ){
    alert("Entering the editorAction function\nParameter(s):\n buttonID = " + buttonID);
  }//end if

  buttons 		= buttonID.split("_");
  objTextArea	= buttonID.replace(/^_(.*)_[^_]*$/, '$1');
  controlID     = buttons[ buttons.length - 1 ];
  objButton 	= document.all[buttonID];
  objEditor 	= document.all["_" + objTextArea + "_editor"];

  if( DEBUG ){
    alert("Recent Assignments:\nbuttons = " + buttons + "\nobjTextArea = " + objTextArea + "\ncontrolID = " + controlID + "\nobjButton = " + objButton + "\nobjEditor = " + objEditor);
  }//end if

  // check editor mode (don't perform actions in textedit mode)
  if ( objEditor.tagName.toLowerCase() == 'textarea' ){ 
    return; 
  }//end if

  editorDocument = objEditor.contentWindow.document;
  setFocus(objEditor);

  // execute command for font pulldowns
  index = objButton.selectedIndex;

  if ( index != null ){
    value = objButton[ index ].value;
    editorDocument.execCommand(controlID,0,value);
  }//end if
  else if (controlID == 'ForeColor' || controlID == 'BackColor'){
    //execute command for foreground color & background color buttons
    //calculate optimal window placement for popup dialog
    positionX    = event.screenX;
    positionY    = event.screenY + 20;
    screenWidth  = screen.width;                                 			//screen size
    screenHeight = screen.height - 20;                          			//take taskbar into account

    if( (positionX + 232) > screenWidth ){ 
      positionX = positionX - 232 - 40; 									//if mouse too far right
    }//end if       

    if( (positionY + 164) > screenHeight ){ 
      positionY = positionY - 164 - 80; 									//if mouse too far down
    }//end if       

    position    = "dialogLeft:" + positionX + "; dialogTop:" + positionY;
    oldColor 	= decimalToRGB(editorDocument.queryCommandValue(controlID));
    newColor 	= showModalDialog(editorURL + "selectColor.html", oldColor, "dialogWidth:238px; dialogHeight: 187px; " + "resizable: no; help: no; status: no; scroll: no; " + position);

    if( newColor != null ){ 
      editorDocument.execCommand(controlID, false, "#" + newColor); 
    }//end if
  }//end else if
  else{
    // execute command for buttons
    // subscript & superscript, disable one before enabling the other
    if( controlID.toLowerCase() == 'subscript' && editorDocument.queryCommandState('superscript') ){ 
      editorDocument.execCommand('superscript');
    }//end if

    if ( controlID.toLowerCase() == 'superscript' && editorDocument.queryCommandState('subscript') ){ 
      editorDocument.execCommand('subscript'); 
    }//end if

    // insert link
    if( controlID.toLowerCase() == 'createlink' ){
      editorDocument.execCommand(controlID,1);
    }//end if
    else if (controlID.toLowerCase() == 'insertimage'){
      // insert image
      showModalDialog(editorURL + "insertImage.html", editorDocument, "resizable: no; help: no; status: no; scroll: no; ");
    }//end else if
    else{
      // all other commands
      editorDocument.execCommand(controlID);
    }//end else
  }//end outer else

  updateUserInterface(objTextArea);

  if( DEBUG ){
    alert("Exiting the editorAction function");
  }//end if
}//function editorAction

//=======================================

// generateEditor

//=======================================

//Inputs:		textAreaID			ID of the textarea we are going to replace

//				Width (optional)	Width of the editor

//				Height (optional)	Height of the editor

//

//Description:	replace the HTML textarea with the rich text editor

//

//Usage:		generateEditor("textAreaID", [height], [width]);

//=======================================

function generateEditor(objTextArea, width, height){

  var imageURL;

  var objObject;

  var userAgent;

  var versionInfo;

  var MSIE;

  var Version;

  var Win32;

  var Opera;

  var RichTextEditor;

  var contents;  


  if( DEBUG ){
    alert("Entering the generateEditor function\nParameters:\nobjTextArea = " + objTextArea + "\nwidth = " + width + "\nheight = " + height);
  }//end if

  // Default Settings

  imageURL = editorURL + 'images/';       						//images url (for button icons)


  // set size to specified size or size of original object

  objObject    = document.all[objTextArea];


  if( !width ){

    if( objObject.style.width ){

      width = objObject.style.width; 							//use css style

    }//end if      

    else if( objObject.cols ){ 

      width = (objObject.cols * 8) + 22; 						//column width + toolbar

    }//end else if  

    else{ 

      width = '100%'; 											//default

    }//end else         

  }//end outer if


  if( !height ){

    if( objObject.style.height ){ 

      height = objObject.style.height; 							//use css style

    }//end if   

    else if( objObject.rows ){ 

      height = objObject.rows * 17 								//row height

    }//end else if       

    else{ 

      height = '200'; 											//default

    }//end else              

  }//end outer if


  // Check for IE 5.5+ on Windows

  userAgent 	= navigator.userAgent;

  versionInfo 	= Array();                              		//version info

  versionInfo 	= userAgent.split(";")

  MSIE  		= userAgent.indexOf('MSIE') > 0;

  Version  		= versionInfo[1].substr(6,3);

  Win32 		= userAgent.indexOf('Windows') > 0 && userAgent.indexOf('Mac') < 0 && userAgent.indexOf('Windows CE') < 0;

  Opera 		= userAgent.indexOf('Opera') > -1;


  if( !MSIE || Opera || Version < 5.5 || !Win32 ){ 

    return; 

  }//end if


  //Set up the toolbar buttons
  RichTextEditor = ''

  + '<table border=0 cellspacing=0 cellpadding=0 bgcolor="buttonface" style="padding: 1 0 0 0" width=' + width + ' unselectable="on"><tr><td>\n'

  + '<table border=0 cellspacing=2 cellpadding=0 bgcolor="buttonface" style="float: left;"  unselectable="on">\n'

  + ' <tr>\n'


  //set up the font face drop-down list

  + '  <td style="border-width: 0; padding: 2 0 0 3;">\n'

  + '   <select id="_' + objTextArea + '_FontName" onChange="editorAction(this.id)" unselectable="on">\n'

  + '   <option value="arial, helvetica, sans-serif">Arial</option>\n'

  + '   <option value="courier new, courier, mono">Courier New</option>\n'

  + '   <option value="Georgia, Times New Roman, Times, Serif">Georgia</option>\n'

  + '   <option value="Tahoma, Arial, Helvetica, sans-serif">Tahoma</option>\n'

  + '   <option value="times new roman, times, serif">Times New Roman</option>\n'

  + '   <option value="Verdana, Arial, Helvetica, sans-serif">Verdana</option>\n'

  + '   <option value="wingdings">WingDings</option>\n'

  + '   </select>'

  + '  </td>\n'

  + ' </tr>\n'

  + '</table>\n'


  //set up the font size drop-down list
  + '<table border=0 cellspacing=2 cellpadding=0 bgcolor="buttonface" style="float: left;"  unselectable="on">\n'

  + ' <tr>\n'

  + '  <td style="border-width: 0; padding: 2 1 0 0;">\n'

  +    '<select id="_' + objTextArea + '_FontSize" onChange="editorAction(this.id)" style="width:38px"  unselectable="on">\n'

  + '   <option value=1>1</option><option value=2>2</option><option value=3>3</option><option value=4>4</option><option value=5>5</option><option value=6>6</option><option value=7>7</option>\n'

  + '   </select>\n\n'

  + '  </td>\n'

  + ' </tr>\n'

  + '</table>\n'


  //set up the Bold, Italicize, Underline buttons
  + '<table border=0 cellspacing=2 cellpadding=0 bgcolor="buttonface" style="float: left;"  unselectable="on"><tr><td style="border: inset 1px;">\n'

  +    '<button title="Bold" id="_' + objTextArea + '_Bold" class="btn" onClick="editorAction(this.id)" unselectable="on"><img src="' + imageURL + 'ed_format_bold.gif" unselectable="on"></button>'

  +    '<button title="Italic" id="_' + objTextArea + '_Italic" class="btn" onClick="editorAction(this.id)" unselectable="on"><img src="' + imageURL + 'ed_format_italic.gif" unselectable="on"></button>'

  +    '<button title="Underline" id="_' + objTextArea + '_Underline" class="btn" onClick="editorAction(this.id)" unselectable="on"><img src="' + imageURL + 'ed_format_underline.gif" unselectable="on">\n'

  + '</td></tr></table>\n'


  //set up the strikethrough, subscript and superscript buttons
  + '<table border=0 cellspacing=2 cellpadding=0 bgcolor="buttonface" style="float: left;"  unselectable="on"><tr><td style="border: inset 1px;">\n'

  +    '<button title="Strikethrough" id="_' + objTextArea + '_StrikeThrough" class="btn" onClick="editorAction(this.id)" unselectable="on"><img src="' + imageURL + 'ed_format_strike.gif" unselectable="on"></button>'

  +    '<button title="Subscript" id="_' + objTextArea + '_SubScript" class="btn" onClick="editorAction(this.id)" unselectable="on"><img src="' + imageURL + 'ed_format_sub.gif" unselectable="on"></button>'

  +    '<button title="Superscript" id="_' + objTextArea + '_SuperScript" class="btn" onClick="editorAction(this.id)" unselectable="on"><img src="' + imageURL + 'ed_format_sup.gif" unselectable="on">\n'

  + '</td></tr></table>\n'


  //set up the left justify, center justify, and right justify buttons
  + '<table border=0 cellspacing=2 cellpadding=0 bgcolor="buttonface" style="float: left;"  unselectable="on"><tr><td style="border: inset 1px;">\n'

  +    '<button title="Justify Left" id="_' + objTextArea + '_JustifyLeft" class="btn" onClick="editorAction(this.id)" unselectable="on"><img src="' + imageURL + 'ed_align_left.gif" unselectable="on"></button>'

  +    '<button title="Justify Center" id="_' + objTextArea + '_JustifyCenter" class="btn" onClick="editorAction(this.id)" unselectable="on"><img src="' + imageURL + 'ed_align_center.gif" unselectable="on"></button>'

  +    '<button title="Justify Right" id="_' + objTextArea + '_JustifyRight" class="btn" onClick="editorAction(this.id)" unselectable="on"><img src="' + imageURL + 'ed_align_right.gif" unselectable="on">\n'

  + '</td></tr></table>\n'


  //set up the ordered list, unordered list, decrease indent and increase indent buttons
  + '<table border=0 cellspacing=2 cellpadding=0 bgcolor="buttonface" style="float: left;"  unselectable="on" unselectable="on"><tr><td style="border: inset 1px;">\n'

  +    '<button title="Ordered List" id="_' + objTextArea + '_InsertOrderedList" class="btn" onClick="editorAction(this.id)" unselectable="on"><img src="' + imageURL + 'ed_list_num.gif" unselectable="on"></button>'

  +    '<button title="Bulleted List" id="_' + objTextArea + '_InsertUnorderedList" class="btn" onClick="editorAction(this.id)" unselectable="on"><img src="' + imageURL + 'ed_list_bullet.gif" unselectable="on">\n'

  +    '<button title="Decrease Indent" id="_' + objTextArea + '_Outdent" class="btn" onClick="editorAction(this.id)" unselectable="on"><img src="' + imageURL + 'ed_indent_less.gif" unselectable="on"></button>'

  +    '<button title="Increase Indent" id="_' + objTextArea + '_Indent" class="btn" onClick="editorAction(this.id)" unselectable="on"><img src="' + imageURL + 'ed_indent_more.gif" unselectable="on">\n'

  + '</td></tr></table>\n'


  //set up the forecolor and backcolor buttons
  + '<table border=0 cellspacing=2 cellpadding=0 bgcolor="buttonface" style="float: left;"  unselectable="on" unselectable="on"><tr><td style="border: inset 1px;">\n'

  +    '<button title="Font Color" id="_' + objTextArea + '_ForeColor" class="btn" onClick="editorAction(this.id)" unselectable="on"><img src="' + imageURL + 'ed_color_fg.gif" unselectable="on"></button>'

  +    '<button title="Background Color" id="_' + objTextArea + '_BackColor" class="btn" onClick="editorAction(this.id)" unselectable="on"><img src="' + imageURL + 'ed_color_bg.gif" unselectable="on">\n'

  + '</td></tr></table>\n'

  
  //set up the insert horizontal rule, create hyperlink and insert image buttons
  + '<table border=0 cellspacing=2 cellpadding=0 bgcolor="buttonface" style="float: left;" unselectable="on"><tr><td style="border: inset 1px;">\n'

  +    '<button title="Horizontal Rule" id="_' + objTextArea + '_InsertHorizontalRule" class="btn" onClick="editorAction(this.id)" unselectable="on"><img src="' + imageURL + 'ed_hr.gif" unselectable="on"></button>'

  +    '<button title="Insert Web Link" id="_' + objTextArea + '_CreateLink" class="btn" onClick="editorAction(this.id)" unselectable="on"><img src="' + imageURL + 'ed_link.gif" unselectable="on"></button>'

  +    '<button title="Insert Image" id="_' + objTextArea + '_InsertImage" class="btn" onClick="editorAction(this.id)" unselectable="on"><img src="' + imageURL + 'ed_image.gif" unselectable="on">\n'

  + '</td></tr></table>\n'

  + '</td></tr></table>\n'

  + '<textarea ID="_' +objTextArea + '_editor" style="width:' +width+ '; height:' +height+ '; margin-top: -1px; margin-bottom: -1px;"></textarea>'

  + '<input type="hidden" name="' + objTextArea + '" value="">'

  ;


  //create the rich text editor

  contents = document.all[objTextArea].value;             		// get original contents

  document.all[objTextArea].outerHTML = RichTextEditor;        	// create editor frame

  document.all['_'+ objTextArea +'_editor'].value = contents;   // set contents

  setUpRTEditor('_' + objTextArea + '_HtmlMode', 'init');     	// switch to wysiwyg mode

 
  if( DEBUG ){
    alert("Exiting the generateEditor function");
  }//end if

}//function generateEditor



//=======================================

// insertHTML(objTextArea, string1, string2, selection)

//=======================================

//Inputs:		objTextArea				ID of the textarea

//				string1					HTML or text to insert

// 				string2					HTML or text to insert (optional)

//				selection				(1 or 0) give error if no text selected

//

//Description:	insert a string at the current cursor position

//              if two strings were specified insert the string between the two

//

//Usage:		insertHTML(objTextArea, string1, string2, selection);

//=======================================

function insertHTML(objTextArea, string1, string2, selection){

  var objEditor;

  var tagName;

  var createRange;

  var editorDocument;

  var Handler;

  var htmlText;


  if( DEBUG ){

    alert("Entering the insertHTML function\nParameters:\nobjTextArea = " + objTextArea + "\nstring1 = " + string1 + "\nstring2 = " + string2);

  }//end if


  objEditor = document.all["_" +objTextArea + "_editor"];    		// editor object



  if( string1 == null ){ 

    string1 = ''; 

  }//end if


  if( string2 == null ){ 

    string2 = ''; 

  }//end if


  //for browsers that are not capable of handling rich text, just add to end of textbox

  if( document.all[objTextArea] && objEditor == null ){

    document.all[objTextArea].focus();

    document.all[objTextArea].value = document.all[objTextArea].value + string1 + string2;

    return;

  }//end if


  // error checking  

  if( objEditor == null ){ 

    return alert("Unable to insert HTML.  Invalid object name '" + objTextArea + "'."); 

  }//end if


  setFocus(objEditor);

  tagName = objEditor.tagName.toLowerCase();


  // insertHTML for rich text iframe

  if( tagName == 'iframe' ){

    editorDocument = objEditor.contentWindow.document;

    createRange    = editorDocument.selection.createRange();

    htmlText       = createRange.htmlText;


    // check for control ranges

    if( createRange.length ){ 

      return alert("Unable to insert HTML.  Try highlighting content instead of selecting it."); 

    }//end if


    // insert HTML

    Handler = window.onerror;

    window.onerror = function() { alert("Unable to insert HTML for current selection."); return true; } // partial table selections cause errors

    if( htmlText.length ){ 

      // if content selected                                

      if( string2 ){ 

        createRange.pasteHTML(string1 + htmlText + string2) 		//surround the HTML text with string1 and string2

      }//end inner if 

      else{

        createRange.pasteHTML(string1); 							//overwrite the text

      }//end inner else             

    }//end outer if 

    else{                                            				

      if( selection ){ 

        // if insertion point only

        return alert("Unable to insert HTML.  You must select something first."); 

      }//end if

      createRange.pasteHTML(string1 + string2);                    	// insert strings

    }//end outer else


    window.onerror = Handler;

  }//end outermost if  

  else if( tagName == 'textarea' ){

    // insertHTML for plaintext textarea

    objEditor.focus();

    createRange  = document.selection.createRange();

    htmlText     = createRange.text;


    // insert HTML

    if( htmlText.length ){                                 

      // if content selected

      if( string2 ){ 

        createRange.text = string1 + htmlText + string2; 		//surround the HTML text with string1 and string2

      }//end if  

      else{ 

        createRange.text = string1; 							//overwrite the text

      }//end else               

    }//end if

    else{                                            

      //if insertion point only

      if( selection ){ 

        return alert("Unable to insert HTML.  You must select something first."); 

      }//end inner if

      createRange.text = string1 + string2;                  	// insert strings

    }//end inner else

  }//end else if

  else{

    alert("Unable to insert HTML.  Unknown object tag type '" +tagName+ "'."); 

  }//end else


  // move to end of new content

  createRange.collapse(false); 									// move to end of range

  createRange.select();        									// re-select


  if( DEBUG ){

    alert("Exiting the insertHTML function");

  }//end if


}//function insertHTML



//=======================================

// setFocus(objTextArea)

//=======================================

//Inputs:		objTextArea			ID of the text area

//

//Description:	set the focus to the text area

//

//Usage:		setFocus(objTextArea);

//=======================================

function setFocus(objTextArea){

  var editorDocument;

  var editorRange;

  var createRange;

  var innerFunction;


  if( DEBUG ){

    alert("Entering the setFocus function\nParameters:\nobjTextArea = " + objTextArea);

  }//end if


  // check editor mode

  if( objTextArea.tagName.toLowerCase() == 'textarea' ){    		// textarea

    innerFunction = function() { objTextArea.focus(); };

    setTimeout(innerFunction, 100);                               	// doesn't work all the time without delay

  }//end if

  else{                                                        		// wysiwyg

    editorDocument = objTextArea.contentWindow.document;      		// get iframe editor document object

    editorRange = editorDocument.body.createTextRange();    		// editor range

    createRange    = editorDocument.selection.createRange();   		// selection range

    

    // make sure it's not a controlRange

    if( createRange.length == null && !editorRange.inRange(createRange) ){                

      //is the selection in editor range?    

      editorRange.collapse();                                   	// move to start of range

      editorRange.select();                                     	// select

      createRange = editorRange;

    }//end if

  }//end else


  if( DEBUG ){

    alert("Exiting the setFocus function");

  }//end if


}//function setFocus



//=======================================

// setPlaceholders(editorDocument)

//=======================================

//Inputs:		editorDocument			reference to the editor document

//

//Description:	set the focus to the text area

//

//Usage:		setPlaceholders(editorDocument);

//=======================================

function setPlaceholders(editorDocument){

  var i;


  if( DEBUG ){

    alert("Entering the setPlaceholders function\nParameters:\neditorDocument = " + editorDocument);

  }//end if


  // for links

  for (i=0; i < editorDocument.links.length; i++) {

    editorDocument.links[i].href = editorDocument.links[i].href.replace(/^[^*]*(\*\*\*)/, "$1");

  }//end for loop


  // for images

  for (i = 0; i < editorDocument.images.length; i++) {

    editorDocument.images[i].src = editorDocument.images[i].src.replace(/^[^*]*(\*\*\*)/, "$1");

  }//end for loop


  if( DEBUG ){

    alert("Exiting the setPlaceholders function");

  }//end if


}//function setPlaceholders



//=======================================

// setUpRTEditor(objTextArea)

//=======================================

//Inputs:		objTextArea			ID of the text area

//				mode				is this initialization on page load?  Or has the user just made a change?

//

//Description:	set up the rich text editor

//

//Usage:		setUpRTEditor(buttonID, mode);

//=======================================

function setUpRTEditor(buttonID, mode){

  var buttons = Array();

  var objTextArea;

  var controlID;

  var objEditor;

  var editorDocument;

  var RichTextEditor;

  var IDList;

  var contents;

  var objButton;


  if( DEBUG ){

    alert("Entering the setUpRTEditor function\nParameters:\nbuttonID = " + buttonID + "\nmode = " + mode);

  }//end if


  buttons       = buttonID.split("_");

  objTextArea	= buttonID.replace(/^_(.*)_[^_]*$/, '$1');

  controlID     = buttons[ buttons.length-1 ];

  objEditor     = document.all["_" +objTextArea + "_editor"];


  if( DEBUG ){

    alert("Recent Assignments:\nbuttons = " + buttons + "\nobjTextArea = " + objTextArea + "\ncontrolID = " + controlID + "\nobjEditor = \n" + objEditor);

  }//end if


  // define editor

  RichTextEditor  = '<iframe ID="_' + objTextArea + '_editor"    style="width:' +objEditor.style.width+ '; height:' +objEditor.style.height+ ';"></iframe>';

  contents = objEditor.value;


  // create editor

  objEditor.outerHTML = RichTextEditor;

  objEditor           = document.all["_" + objTextArea + "_editor"];

 

  // get iframe document object

  editorDocument      = objEditor.contentWindow.document;


  // set editor contents (and default styles for editor)

  editorDocument.open();

  editorDocument.write(''

    + '<html>\n'

    + '<head>\n'

    + '<style>\n'

    + 'body { background-color: #FFFFFF;\n'

    + '       font-family: "Verdana";\n'

    + '       font-size: x-small; } \n'

    + '</style>\n'

    + '</head>\n'

    + '<body contenteditable="true" topmargin=1 leftmargin=1>'

    + contents

    + '</body>\n'

    + '</html>\n'

    );


  editorDocument.close();


  // enable buttons

  IDList = Array('Bold','Italic','Underline','StrikeThrough','SubScript','SuperScript','JustifyLeft','JustifyCenter','JustifyRight','InsertOrderedList','InsertUnorderedList','Outdent','Indent','ForeColor','BackColor','InsertHorizontalRule','CreateLink','InsertImage');


  for( i = 0; i < IDList.length; i++ ){

    objButton = document.all["_" + objTextArea + "_" + IDList[i]];

    if( objButton == null ){ 

      continue; 

    }//end if

    objButton.className = 'btn';

    objButton.disabled  = false;

  }//end for loop


  // set event handlers

  editorDocument.onkeypress     = function(){ updateUserInterface(objTextArea); }

  editorDocument.onkeyup        = function(){ updateUserInterface(objTextArea); }

  editorDocument.onmouseup      = function(){ updateUserInterface(objTextArea); }


  //these events fire before they occur

  editorDocument.body.ondrop    = function(){ updateUserInterface(objTextArea, 100); }     

  editorDocument.body.oncut     = function(){ updateUserInterface(objTextArea, 100); }

  editorDocument.body.onpaste   = function(){ updateUserInterface(objTextArea, 100); }

  editorDocument.body.onblur    = function(){ updateUserInterface(objTextArea, -1); }


  // set initial value

  objEditor.onload      = function(){ editorDocument.body.innerHTML = document.all[objTextArea].value; }


  // update hidden output field

  setPlaceholders(editorDocument);


  // update hidden output field

  document.all[objTextArea].value = editorDocument.body.innerHTML;    


  // bring focus to editor

  if( mode != 'init' ){             		

    setFocus(objEditor);					//don't focus on page load

    updateUserInterface(buttonID);			//don't update UI on page load

  }//end if


  if( DEBUG ){

    alert("Exiting the setUpRTEditor function");

  }//end if


}//function setUpRTEditor



//=======================================

// updateUserInterface(objTextArea, runDelay)

//=======================================

//Inputs:		objTextArea			ID of the textarea we are going to replace

//				runDelay			-1 = run now, no matter what

//								 	 0 = run now, if allowed

//							      1000 = run in 1 second, if allowed at that point

//

//Description:	update button status, selected fonts, hidden output field

//

//Usage:		updateUserInterface(objTextArea, runDelay);

//=======================================

function updateUserInterface(objTextArea, runDelay){

  var objEditor;

  var editorDocument;

  var editEvent;

  var IDList;

  var objButton;

  var isActive;

  var fontName = '';

  var fontSize = 0;

  var objFontName;

  var objFontSize;

  var foundFont = 0;

  var numFonts = 0;

  var currentFont = '';

  var currentFontSize = 0;


  if( DEBUG ){

    alert("Entering the updateUserInterface function\nParameters:\nobjTextArea = " + objTextArea + "\nrunDelay = " + runDelay);

  }//end if


  objEditor  = document.all["_" + objTextArea +  "_editor"];		//rich text editor object


  if( runDelay == null ){ 

    runDelay = 0; 

  }//end if


  // setup timer for delayed updates (some events take time to complete)

  if( runDelay > 0 ){ 

    return setTimeout(function(){ updateUserInterface(objTextArea); }, runDelay); 

  }//end if


  // don't execute more than 3 times a second (eg: too soon after last execution)

  if( this.tooSoon == 1 && runDelay >= 0 ){ 

    // queue all but urgent events

    this.queue = 1; return; 

  }//end if 


  this.tooSoon = 1;


  setTimeout(function(){

    this.tooSoon = 0;

    if( this.queue ){ 

      updateUserInterface(objTextArea, -1); 

    };

    this.queue = 0;

    }, 333);  // 1/3 second


  editorDocument = objEditor.contentWindow.document;           		//get iframe editor document object

  editEvent      = objEditor.contentWindow.event;

  setPlaceholders(editorDocument);

  document.all[objTextArea].value = editorDocument.body.innerHTML; 	//update hidden output field


  // update button states

  IDList = Array('Bold','Italic','Underline','JustifyLeft','JustifyCenter','JustifyRight','InsertOrderedList','InsertUnorderedList');


  for( i = 0; i < IDList.length; i++ ){                           	//for each button

    objButton = document.all["_" + objTextArea + "_" +IDList[i]];  	//get button object

    if( objButton == null ){ 

      continue; 													//if no button object

    }//end if        

    isActive = editorDocument.queryCommandState( IDList[i] );

    if( !isActive ){                                  				//option is OK

      if( objButton.className != 'btn' ){ 

        objButton.className = 'btn'; 

      }//end if

      if( objButton.disabled  != false ){ 

        objButton.disabled = false; 

      }//end if

    }//end if

    else if( isActive ){

      // option already applied or mixed content                            					

      if( objButton.className != 'btnDN' ){ 

        objButton.className = 'btnDN'; 

      }//end if

      if( objButton.disabled  != false ){ 

        objButton.disabled = false; 

      }//end if

    }//end else if

  }//end for loop


  // Loop over font pulldowns

  IDList = Array('FontName','FontSize');


  for( i = 0; i < IDList.length; i++ ){

    isActive  = editorDocument.queryCommandState( IDList[i] );

    objButton = document.all["_" + objTextArea + "_" +IDList[i]];	//button object

    objButton.disabled = false;

  }//end for loop


  //Get Font Name and Size

  fontName = editorDocument.queryCommandValue('FontName');

  fontSize = editorDocument.queryCommandValue('FontSize');


  if( fontName != null ){ 

    fontName = fontName.toLowerCase();

  }//end if


  //Set Font face pulldown

  objFontName = document.all["_" + objTextArea + "_FontName"];


  if( fontName == null ){ 

    objFontName.value = fontName; 

  }//end if

  else{

    numFonts = objFontName.length;

    for( i = 0; i < numFonts; i++ ){

      currentFont = objFontName[i].text.toLowerCase();

      if( currentFont == fontName ){

        objFontName.selectedIndex = i;

        foundFont = 1;

      }//end if

    }//end for loop

    if( foundFont != 1 ){ 

      objFontName.value = fontName;   								//for fonts not in list

    }//end if     			

  }//end else


  //Set Font size pulldown

  objFontSize = document.all["_" + objTextArea + "_FontSize"];

  if( fontSize == null ){ 

    objFontSize.value = fontSize;

  }//end if

  else{

    for( i = 0; i < 7; i++ ){

      currentFontSize = objFontSize[i].text;

      if( currentFontSize == fontSize ){ 

        objFontSize.selectedIndex = i; 

      }//end if

    }//end for loop

  }//end else


  if( DEBUG ){

    alert("Exiting the updateUserInterface function");

  }//end if

}//function updateUserInterface

