//
// openWYSIWYG v1.0 Copyright (c) 2006 openWebWare.com
// This copyright notice MUST stay intact for use.
//
// An open source WYSIWYG editor for use in web based applications.
// For full source code and docs, visit http://www.openwebware.com/
//
// This library is free software; you can redistribute it and/or modify 
// it under the terms of the GNU Lesser General Public License as published 
// by the Free Software Foundation; either version 2.1 of the License, or 
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but 
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
// License for more details.
//
// You should have received a copy of the GNU Lesser General Public License along 
// with this library; if not, write to the Free Software Foundation, Inc., 59 
// Temple Place, Suite 330, Boston, MA 02111-1307 USA 


/* ---------------------------------------------------------------------- *\
  Global Variables: Set global variables such as images directory, 
                        WYSIWYG Height, Width, and CSS Directory.
\* ---------------------------------------------------------------------- */
var browserName = navigator.appName;

// Images Directory
imagesDir = "/include/textarea/icons/";

// CSS Directory
cssDir = "/include/textarea/styles/";

// Popups Directory
popupsDir = "/include/textarea/popups/";

// WYSIWYG Width and Height
wysiwygWidth = 760;
wysiwygHeight = 250;

//directory for an upload
wysiwygDirectoryHere = "";
wysiwygDir = "";

// Include Style Sheet
document.write('<link rel="stylesheet" type="text/css" href="' +cssDir+ 'styles.css">\n');


/* ---------------------------------------------------------------------- *\
  Toolbar Settings: Set the features and buttons available in the WYSIWYG
                        Toolbar.
\* ---------------------------------------------------------------------- */


// List of available font types
  var Fonts = new Array();
  Fonts[0] = "Arial";
  Fonts[1] = "Sans Serif";
  Fonts[2] = "Tahoma";
  Fonts[3] = "Verdana";
  Fonts[4] = "Courier New";
  Fonts[5] = "Georgia";
  Fonts[6] = "Times New Roman";
  Fonts[7] = "Impact";
  Fonts[8] = "Comic Sans MS";

// List of available block formats (not in use)
var BlockFormats = new Array();
  BlockFormats[0]  = "Address";
  BlockFormats[1]  = "Bulleted List";
  BlockFormats[2]  = "Definition";
  BlockFormats[3]  = "Definition Term";
  BlockFormats[4]  = "Directory List";
  BlockFormats[5]  = "Formatted";
  BlockFormats[6]  = "Heading 1";
  BlockFormats[7]  = "Heading 2";
  BlockFormats[8]  = "Heading 3";
  BlockFormats[9]  = "Heading 4";
  BlockFormats[10] = "Heading 5";
  BlockFormats[11] = "Heading 6";
  BlockFormats[12] = "Menu List";
  BlockFormats[13] = "Normal";
  BlockFormats[14] = "Numbered List";

// List of available font sizes
  var FontSizes = new Array();
  FontSizes[0]  = "1";
  FontSizes[1]  = "2";
  FontSizes[2]  = "3";
  FontSizes[3]  = "4";
  FontSizes[4]  = "5";
  FontSizes[5]  = "6";
  FontSizes[6]  = "7";

// Order of available commands in toolbar one
  var buttonName = new Array();
  buttonName[0]  = "bold";
  buttonName[1]  = "italic";
  buttonName[2]  = "underline";
  buttonName[3]  = "strikethrough";
  buttonName[4]  = "seperator";
  buttonName[5]  = "subscript";
  buttonName[6]  = "superscript";
  buttonName[7]  = "seperator";
  buttonName[8]  = "justifyleft";
  buttonName[9]  = "justifycenter";
  buttonName[10] = "justifyright";
  buttonName[11] = "seperator";
  buttonName[12] = "unorderedlist";
  buttonName[13] = "orderedlist";
  buttonName[14] = "outdent";
  buttonName[15] = "indent";

// Order of available commands in toolbar two
  var buttonName2 = new Array();
  buttonName2[0]  = "forecolor";
  //buttonName2[1]  = "backcolor";
  buttonName2[2]  = "seperator";
  buttonName2[3]  = "cut";
  buttonName2[4]  = "copy";
  buttonName2[5]  = "paste";
  buttonName2[6]  = "seperator";
  buttonName2[7]  = "undo";
  buttonName2[8]  = "redo";
  buttonName2[9]  = "seperator";
  buttonName2[10]  = "inserttable";
  buttonName2[11]  = "insertimage";
  buttonName2[12]  = "createlink";
  buttonName2[13]  = "seperator";
  buttonName2[14]  = "viewSource";
  buttonName2[15]  = "seperator";
  buttonName2[16]  = "help";
  buttonName2[17]  = "seperator";
  buttonName2[18]  = "editor";

// List of available actions and their respective ID and images
var ToolbarList = {
   //Name              buttonID                 buttonTitle           buttonImage                            buttonImageRollover
      "bold":           ['Bold',                 'Bold',               imagesDir + 'bold.gif',               imagesDir + 'bold_on.gif'],
      "italic":         ['Italic',               'Italic',             imagesDir + 'italics.gif',            imagesDir + 'italics_on.gif'],
      "underline":      ['Underline',            'Underline',          imagesDir + 'underline.gif',          imagesDir + 'underline_on.gif'],
      "strikethrough":  ['Strikethrough',        'Strikethrough',      imagesDir + 'strikethrough.gif',      imagesDir + 'strikethrough_on.gif'],
      "seperator":      ['',                     '',                   imagesDir + 'seperator.gif',          imagesDir + 'seperator.gif'],
      "subscript":      ['Subscript',            'Subscript',          imagesDir + 'subscript.gif',          imagesDir + 'subscript_on.gif'],
      "superscript":    ['Superscript',          'Superscript',        imagesDir + 'superscript.gif',        imagesDir + 'superscript_on.gif'],
      "justifyleft":    ['Justifyleft',          'Justifyleft',        imagesDir + 'justify_left.gif',       imagesDir + 'justify_left_on.gif'],
      "justifycenter":  ['Justifycenter',        'Justifycenter',      imagesDir + 'justify_center.gif',     imagesDir + 'justify_center_on.gif'],
      "justifyright":   ['Justifyright',         'Justifyright',       imagesDir + 'justify_right.gif',      imagesDir + 'justify_right_on.gif'],
      "unorderedlist":  ['InsertUnorderedList',  'InsertUnorderedList',imagesDir + 'list_unordered.gif',     imagesDir + 'list_unordered_on.gif'],
      "orderedlist":    ['InsertOrderedList',    'InsertOrderedList',  imagesDir + 'list_ordered.gif',       imagesDir + 'list_ordered_on.gif'],
      "outdent":        ['Outdent',              'Outdent',            imagesDir + 'indent_left.gif',        imagesDir + 'indent_left_on.gif'],
      "indent":         ['Indent',               'Indent',             imagesDir + 'indent_right.gif',       imagesDir + 'indent_right_on.gif'],
      "cut":            ['Cut',                  'Cut',                imagesDir + 'cut.gif',                imagesDir + 'cut_on.gif'],
      "copy":           ['Copy',                 'Copy',               imagesDir + 'copy.gif',               imagesDir + 'copy_on.gif'],
      "paste":          ['Paste',                'Paste',              imagesDir + 'paste.gif',              imagesDir + 'paste_on.gif'],
      "forecolor":      ['ForeColor',            'ForeColor',          imagesDir + 'forecolor.gif',          imagesDir + 'forecolor_on.gif'],
      "backcolor":      ['BackColor',            'BackColor',          imagesDir + 'backcolor.gif',          imagesDir + 'backcolor_on.gif'],
      "undo":           ['Undo',                 'Undo',               imagesDir + 'undo.gif',               imagesDir + 'undo_on.gif'],
      "redo":           ['Redo',                 'Redo',               imagesDir + 'redo.gif',               imagesDir + 'redo_on.gif'],
        "inserttable":  ['InsertTable',          'InsertTable',        imagesDir + 'insert_table.gif',       imagesDir + 'insert_table_on.gif'],
      "insertimage":    ['InsertImage',          'InsertImage',        imagesDir + 'insert_picture.gif',     imagesDir + 'insert_picture_on.gif'],
      "createlink":     ['CreateLink',           'CreateLink',         imagesDir + 'insert_hyperlink.gif',   imagesDir + 'insert_hyperlink_on.gif'],
      "viewSource":     ['ViewSource',           'ViewSource',         imagesDir + 'view_source.gif',        imagesDir + 'view_source_on.gif'],
      "viewText":       ['ViewText',             'ViewText',           imagesDir + 'view_text.gif',          imagesDir + 'view_text_on.gif'],
      "editor":         ['NoEditor',             'NoEditor',           imagesDir + 'noEditor.gif',           imagesDir + 'noEditor.gif'],
      "help":           ['Help',                 'Help',               imagesDir + 'help.gif',               imagesDir + 'help_on.gif'],
      "selectfont":     ['SelectFont',           'SelectFont',         imagesDir + 'select_font.gif',        imagesDir + 'select_font_on.gif'],
      "selectsize":     ['SelectSize',           'SelectSize',         imagesDir + 'select_size.gif',        imagesDir + 'select_size_on.gif']
};

/*----------------------------------------------------------------------
   Function:     Select()
   Description:  Supports blockformat list that maps directly to a command
 ----------------------------------------------------------------------*/
function Select(selectname)
{ var cursel = document.getElementById(selectname).selectedIndex;

  /* First one is always a label */
  if (cursel != 0) {
    var selected = document.getElementById(selectname).options[cursel].value;
    document.getElementById('wysiwygbody').contentWindow.document.execCommand(selectname, false, selected);
    document.getElementById(selectname).selectedIndex = 0;
  }
  document.getElementById("wysiwygbody").contentWindow.focus();
}

/*----------------------------------------------------------------------
   Function:     Insert()
   Description:  Supports html inserted at the end of the current text
 ----------------------------------------------------------------------*/
function Insert(selectname)
{ var cursel = document.getElementById(selectname).selectedIndex;

  /* First one is always a label */
  if (cursel != 0) {
    var selected = document.getElementById(selectname).options[cursel].value;
    document.getElementById(selectname).selectedIndex = 0;
    insertHTML(selected, "body");
  }
  document.getElementById("wysiwygbody").contentWindow.focus();
}

/* ---------------------------------------------------------------------- *\
  Function    : insertAdjacentHTML(), insertAdjacentText() and insertAdjacentElement()
  Description : Emulates insertAdjacentHTML(), insertAdjacentText() and 
                    insertAdjacentElement() three functions so they work with 
                                                Netscape 6/Mozilla
  Notes       : by Thor Larholm me@jscript.dk
\* ---------------------------------------------------------------------- */
if(typeof HTMLElement!="undefined" && !HTMLElement.prototype.insertAdjacentElement){
  HTMLElement.prototype.insertAdjacentElement = function
  (where,parsedNode)
      {
        switch (where){
            case 'beforeBegin':
                  this.parentNode.insertBefore(parsedNode,this)
                  break;
            case 'afterBegin':
                  this.insertBefore(parsedNode,this.firstChild);
                  break;
            case 'beforeEnd':
                  this.appendChild(parsedNode);
                  break;
            case 'afterEnd':
                  if (this.nextSibling) 
      this.parentNode.insertBefore(parsedNode,this.nextSibling);
                  else this.parentNode.appendChild(parsedNode);
                  break;
            }
      }

      HTMLElement.prototype.insertAdjacentHTML = function
  (where,htmlStr)
      {
            var r = this.ownerDocument.createRange();
            r.setStartBefore(this);
            var parsedHTML = r.createContextualFragment(htmlStr);
            this.insertAdjacentElement(where,parsedHTML)
      }


      HTMLElement.prototype.insertAdjacentText = function
  (where,txtStr)
      {
            var parsedText = document.createTextNode(txtStr)
            this.insertAdjacentElement(where,parsedText)
      }
};


// Create viewTextMode global variable and set to 0
// enabling all toolbar commands while in HTML mode
viewTextMode = 0;


/** ----- 
  Alternatives to insertAdjacentHTML to work with safari and other browsers
**/
function checkElem(a)
{   var r = [];
    //Force the arg into an array, if it isn't already
    if (a.constructor != Array) a = [ a ];

    for (var i = 0; i < a.length; i++)
    {      //if string
        if ( a[i].constructor == String)  
        {      //Create a temporary element to house the html
            var div = document.createElement("div");
               //Inject the html, to convert it into a DOM structure
            div.innerHTML = a[i];
               //*Extract the DOM structure back out
            for (var j = 0; j < div.childNodes.length;  j++)
                r[r.length] = div.childNodes[j];  
        }
        else  if (a[i].length)  //array
        {     //**Array of Dom Nodes
            for (var j = 0;  j < a[i].length; j++)
               r[r.length] = a[i][j];
        }
        else   //Otherwise, assume it's a DOM node
           r[r.length] = a[i];
    }
    return r;
}

function before(parent, before, elem)
{   //**Check to see if no parent node was provided (2 parameters)
    if (elem == null)
    {   elem = before;
        before = parent;
        parent = before.parentNode;
    }

      //**Get the new array of elements
    var elems = checkElem(elem);

      //**Move through the array backwards, since we are prepending
   for (var i = elems.length - 1; i >=0; i--)
      parent.insertBefore(elems[i], before);
}

function append(parent, elem)
{     //Get the array of elements
    var elems = checkElem(elem);

      //**Append
    for (var i = 0; i < elems.length; i++)
        parent.appendChild(elems[i]);
}


/* ---------------------------------------------------------------------- *\
  Function    : generate_wysiwyg()
  Description : replace textarea with wysiwyg editor
  Usage       : generate_wysiwyg("textarea_id");
  Arguments   : textarea_id - ID of textarea to replace
                height of the area (assuming a common width)
\* ---------------------------------------------------------------------- */
function generate_wysiwyg(textareaID, height, width, dir, directoryHere) {
 
  if (height != null)  wysiwygHeight = height;  //*use the value of height passed in
  if (width != null)   wysiwygWidth = width;
  if (dir != null)  wysiwygDir = dir;
  if (directoryHere != null)  wysiwygDirectoryHere = directoryHere;

  if (textareaID == "INVALID")  return;
  var elem = document.getElementById(textareaID);
  if (elem.currentStyle) //**IE -- cannot get calculated dimensions
  {   height = wysiwygHeight;    
      width = wysiwygWidth;    
  } 
  else if (window.getComputedStyle)  //**Mozilla - can get them - so use them
  {     var compStyle = window.getComputedStyle(elem, "");
        height = parseFloat(compStyle.height);
        width = parseFloat(compStyle.width);
  }
  else
  {   height = wysiwygHeight;    
      width = wysiwygWidth;    
  } 

  if (height != 0)
     wysiwygHeight = height;
  if (width != 0)
     wysiwygWidth = width;

    // Check to make sure it is a supported browser before we remove the textArea
  var detect = navigator.userAgent.toLowerCase();
  if ((detect.indexOf('konqueror')+1) || (detect.indexOf('omniweb')+1) || (detect.indexOf('opera')+1))
      return;
   
  if ((detect.indexOf('msie')+1) || (!(detect.indexOf('compatible')+1)) || (detect.indexOf('safari')+1))
      ;
  else
      return;

    // Hide the textarea and textEntryHelp link
  document.getElementById(textareaID).style.display = 'none'; 
  if (document.getElementById('textEntryHelp') != null)
     document.getElementById('textEntryHelp').style.display = 'none';   //**AUD

  // Pass the textareaID to the "n" variable.
  var n = textareaID;

  // Toolbars width is 2 pixels wider than the wysiwygs
  toolbarWidth = parseFloat(wysiwygWidth) + 2;

  // Generate WYSIWYG toolbar one
  var toolbar;
  toolbar =  '<table cellpadding="0" cellspacing="0" border="0" class="toolbar1" style="width:' + toolbarWidth + 'px;"><tr><td style="width: 6px;"><img src="' +imagesDir+ 'seperator2.gif" alt="" hspace="3"></td>';
  
  // Create IDs for inserting Font Type and Size drop downs
  //AUD toolbar += '<td style="width: 90px;"><span id="FontSelect' + n + '"></span></td>';
      //AUD - put in a format list instead

  toolbar += '<td style="width: 100px;"><select id="formatblock" onchange="Select(this.id);">  <option value="">Format</option> <option value="<p>">Normal</option> <option value="<h1>">Heading 1 <H1></option> <option value="<h2>">Heading 2 <H2></option> <option value="<h3>">Heading 3 <H3></option> <option value="<h4>">Heading 4 <H4></option> </select></td>';

  toolbar += '<td style="width: 50px;"><span id="FontSizes'  + n + '"></span></td>';

  toolbar += '<td style="width: 12px;" align="center"><img src=' +imagesDir + 'seperator.gif  border=0 unselectable="on" width="2" height="18" hspace="2" unselectable="on"></td>';

  // Output all command buttons that belong to toolbar one
  for (var i = 0; i <= buttonName.length;) { 
    if (buttonName[i]) {
          var buttonObj            = ToolbarList[buttonName[i]];
          var buttonID             = buttonObj[0];
          var buttonTitle          = buttonObj[1];
          var buttonImage          = buttonObj[2];
          var buttonImageRollover  = buttonObj[3];
          
          if (buttonName[i] == "seperator") {
                toolbar += '<td style="width: 12px;" align="center"><img src="' +buttonImage+ '" border=0 unselectable="on" width="2" height="18" hspace="2" unselectable="on"></td>';
          }
          else {
                toolbar += '<td style="width: 22px;"><img src="' +buttonImage+ '" border=0 unselectable="on" title="' +buttonTitle+ '" id="' +buttonID+ '" class="button" onClick="formatText(this.id,\'' + n + '\');" onmouseover="if(className==\'button\'){className=\'buttonOver\'}; this.src=\'' + buttonImageRollover + '\';" onmouseout="if(className==\'buttonOver\'){className=\'button\'}; this.src=\'' + buttonImage + '\';" unselectable="on" width="20" height="20"></td>';
          }
    }
    i++;
  }

  toolbar += '<td>&nbsp;</td></tr></table>';  

  // Generate WYSIWYG toolbar two
  var toolbar2;
  toolbar2 = '<table cellpadding="0" cellspacing="0" border="0" class="toolbar2" style="width:' + toolbarWidth + 'px;"><tr><td style="width: 6px;"><img src="' +imagesDir+ 'seperator2.gif" alt="" hspace="3"></td>';
 
  //** AUD
  toolbar2 += '<td style="width: 80px;"><select id="insert" onchange="Insert(this.id);">  <option value="">Insert</option> <option value="<hr>">Horiz. Line</option> <option value="<br>">New Line</option> </select></td>';

  toolbar2 += '<td style="width: 12px;" align="center"><img src=' +imagesDir + 'seperator.gif  border=0 unselectable="on" width="2" height="18" hspace="2" unselectable="on"></td>';

  // Output all command buttons that belong to toolbar two
  for (var j = 0; j <= buttonName2.length;) {
    if (buttonName2[j]) {
          var buttonObj            = ToolbarList[buttonName2[j]];
          var buttonID             = buttonObj[0];
          var buttonTitle          = buttonObj[1];
          var buttonImage          = buttonObj[2];
          var buttonImageRollover  = buttonObj[3];
        
          if (buttonName2[j] == "seperator") {
                toolbar2 += '<td style="width: 12px;" align="center"><img src="' +buttonImage+ '" border=0 unselectable="on" width="2" height="18" hspace="2" unselectable="on"></td>';
          }
          else if (buttonName2[j] == "viewSource"){
                toolbar2 += '<td style="width: 22px;">';
                toolbar2 += '<span id="HTMLMode' + n + '"><img src="'  +buttonImage+  '" border=0 unselectable="on" title="' +buttonTitle+ '" id="' +buttonID+ '" class="button" onClick="formatText(this.id,\'' + n + '\');" onmouseover="if(className==\'button\'){className=\'buttonOver\'}; this.src=\'' +buttonImageRollover+ '\';" onmouseout="if(className==\'buttonOver\'){className=\'button\'}; this.src=\'' + buttonImage + '\';" unselectable="on"  width="20" height="20"></span>';
                toolbar2 += '<span id="textMode' + n + '"><img src="' +imagesDir+ 'view_text.gif" border=0 unselectable="on" title="viewText"          id="ViewText"       class="button" onClick="formatText(this.id,\'' + n + '\');" onmouseover="if(className==\'button\'){className=\'buttonOver\'}; this.src=\'' +imagesDir+ 'view_text_on.gif\';"    onmouseout="if(className==\'buttonOver\'){className=\'button\'}; this.src=\'' +imagesDir+ 'view_text.gif\';" unselectable="on"  width="20" height="20"></span>';
            toolbar2 += '</td>';
        }
        else {
                toolbar2 += '<td style="width: 22px;"><img src="' +buttonImage+ '" border=0 unselectable="on" title="' +buttonTitle+ '" id="' +buttonID+ '" class="button" onClick="formatText(this.id,\'' + n + '\');" onmouseover="if(className==\'button\'){className=\'buttonOver\'}; this.src=\'' +buttonImageRollover+ '\';" onmouseout="if(className==\'buttonOver\'){className=\'button\'}; this.src=\'' + buttonImage + '\';" unselectable="on" width="20" height="20"></td>';
        }
    }
    j++;
  }

  toolbar2 += '<td>&nbsp;</td></tr></table>';  

 
      // Create iframe which will be used for rich text editing
  var iframe = '<table cellpadding="0" cellspacing="0" border="0" style="width:' + wysiwygWidth + 'px; height:' + wysiwygHeight + 'px;border: 1px inset #CCCCCC; background-color:white;"><tr><td valign="top">\n' + '<iframe frameborder="0" id="wysiwyg' + n + '"></iframe>\n' + '</td></tr></table>\n';

  // Insert after the textArea both toolbar one and two (AUD added the div so we can show/hide
  //document.getElementById(n).insertAdjacentHTML("afterEnd", "<div id='wysiwygAll'>" +  toolbar + toolbar2 + iframe + "</div>");
  before(document.getElementById(n), "<div id='wysiwygAll'>" +  toolbar + toolbar2 + iframe + "</div>");

  // Insert the Font Type and Size drop downs into the toolbar
  //AUD outputFontSelect(n);
  outputFontSizes(n); 

  // Hide the dynamic drop down lists for the Font Types and Sizes
  //AUD hideFonts(n);
  hideFontSizes(n);

  // Hide the "Text Mode" button
  document.getElementById("textMode" + n).style.display = 'none'; 

      // Give the iframe the global wysiwyg height and width
  document.getElementById("wysiwyg" + n).style.height = wysiwygHeight + "px";
  document.getElementById("wysiwyg" + n).style.width = wysiwygWidth + "px";

  var doc = document.getElementById("wysiwyg" + n).contentWindow.document;

      // Write the textarea's content into the iframe
  doc.open();
  doc.write(document.getElementById("body").value);
  doc.close();

      // Make the iframe editable in both Mozilla and IE
  doc.body.contentEditable = true;
  doc.designMode = "on";

        // NEED to update orig text area from form js
};



/* ---------------------------------------------------------------------- *\
  Function    : formatText()
  Description : replace textarea with wysiwyg editor
  Usage       : formatText(id, n, selected);
  Arguments   : id - The execCommand (e.g. Bold)
                n  - The editor identifier that the command 
                                                     affects (the textarea's ID)
                selected - The selected value when applicable (e.g. Arial)
\* ---------------------------------------------------------------------- */
function formatText(id, n, selected) {

  // When user clicks toolbar button make sure it always targets its respective WYSIWYG
  document.getElementById("wysiwyg" + n).contentWindow.focus();

  // When in Text Mode these execCommands are disabled
  var formatIDs = new Array("FontSize","FontName","Bold","Italic","Underline","Subscript","Superscript","Strikethrough","Justifyleft","Justifyright","Justifycenter","InsertUnorderedList","InsertOrderedList","Indent","Outdent","ForeColor","BackColor","InsertImage","InsertTable","CreateLink");
  
  // Check if button clicked is in disabled list
  for (var i = 0; i <= formatIDs.length;) {
       if (formatIDs[i] == id) {
           var disabled_id = 1; 
        }
        i++;
  }

  // Check if in Text Mode and disabled button was clicked
  if (viewTextMode == 1 && disabled_id == 1) {
        alert ("You are in HTML Mode. This feature has been disabled.");
  }

  else {

        // FontSize
        if (id == "FontSize") {
            document.getElementById("wysiwyg" + n).contentWindow.document.execCommand("FontSize", false, selected);
        }
        
        // FontName
        else if (id == "FontName") {
            document.getElementById("wysiwyg" + n).contentWindow.document.execCommand("FontName", false, selected);
        }

        // ForeColor and BackColor
        else if (id == 'ForeColor' || id == 'BackColor') {
            var w = screen.availWidth;
            var h = screen.availHeight;
            var popW = 210, popH = 165;
            var leftPos = (w-popW)/2, topPos = (h-popH)/2;
            var currentColor = _dec_to_rgb(document.getElementById("wysiwyg" + n).contentWindow.document.queryCommandValue(id));
   
            window.open(popupsDir + 'select_color.html?color=' + currentColor + '&command=' + id + '&wysiwyg=' + n,'popup','location=0,status=0,scrollbars=0,width=' + popW + ',height=' + popH + ',top=' + topPos + ',left=' + leftPos);
        }
        
            // InsertImage
        else if (id == "InsertImage") {
            if (wysiwygDir != "" && wysiwygDirectoryHere != "")
               window.open(popupsDir + 'insert_image.html?wysiwyg=' + n + '&dir=' + wysiwygDir + '&directoryHere=' + wysiwygDirectoryHere,'popup','location=0,status=0,scrollbars=0,resizable=0,width=400,height=270');
            else
               window.open(popupsDir + 'insert_image.html?wysiwyg=' + n, 'popup','location=0,status=0,scrollbars=0,resizable=0,width=400,height=127');
        }
        
            // InsertTable
        else if (id == "InsertTable") {
          window.open(popupsDir + 'create_table.html?wysiwyg=' + n,'popup','location=0,status=0,scrollbars=0,resizable=0,width=400,height=360');
        }
        
            // CreateLink
        else if (id == "CreateLink") {
            if (wysiwygDir != "" && wysiwygDirectoryHere != "")
               window.open(popupsDir + 'insert_hyperlink.html?wysiwyg=' + n + '&dir=' + wysiwygDir + '&directoryHere=' + wysiwygDirectoryHere,'popup','location=0,status=0,scrollbars=0,resizable=0,width=400,height=280');
            else
               window.open(popupsDir + 'insert_hyperlink.html?wysiwyg=' + n,'popup','location=0,status=0,scrollbars=0,resizable=0,width=400,height=128');
        }
        
            // ViewSource
        else if (id == "ViewSource") {
             viewSource(n);
        }

        // ViewText
        else if (id == "ViewText") {
             viewText(n);
        }

            // Help
        else if (id == "Help") {
           window.open(popupsDir + 'about.html','popup','location=0,status=0,scrollbars=0,resizable=0,width=400,height=330');
        }

           //**Remove the editor
        else if (id == "NoEditor") {
           
           content=document.getElementById("wysiwygbody").contentWindow.document.body.innerHTML;
           if (content != null && content.length > 0)
               document.getElementById("body").value = "<html>" + content;
           document.getElementById("body").style.display = 'block';
           document.getElementById("wysiwygAll").style.display = 'none';
           document.getElementById('textEntryHelp').style.display = 'block'; 

        }
        
            // Every other command
        else {
           document.getElementById("wysiwyg" + n).contentWindow.document.execCommand(id, false, null);
        }
  }
};



/* ---------------------------------------------------------------------- *\
  Function    : insertHTML()
  Description : insert HTML into WYSIWYG in rich text
  Usage       : insertHTML(<b>hello</b>, "textareaID")
  Arguments   : html - The HTML being inserted (e.g. <b>hello</b>)
                n  - The editor identifier that the HTML 
                will be inserted into (the textarea's ID)
\* ---------------------------------------------------------------------- */
function insertHTML(html, n) {

      if (browserName == "Microsoft Internet Explorer") {        
          document.getElementById("wysiwyg" + n).contentWindow.focus();
          document.getElementById('wysiwyg' + n).contentWindow.document.selection.createRange().pasteHTML(html); 
      } 
       
      else {
          var span = document.getElementById('wysiwyg' + n).contentWindow.document.createElement("span");
             
          span.innerHTML = html;
          var node = insertNodeAtSelection(span, n);
      }
}


/* ---------------------------------------------------------------------- *\
  Function    : insertNodeAtSelection()
  Description : insert HTML into WYSIWYG in rich text (mozilla)
  Usage       : insertNodeAtSelection(insertNode, n)
  Arguments   : insertNode - The HTML being inserted (must be innerHTML 
                                 inserted within a div element)
                n          - The editor identifier that the HTML will be 
                                                             inserted into (the textarea's ID)
\* ---------------------------------------------------------------------- */
function insertNodeAtSelection(insertNode, n) {
  // get current selection
  var sel = document.getElementById('wysiwyg' + n).contentWindow.getSelection();

  // get the first range of the selection
  // (there's almost always only one range)
  var range = sel.getRangeAt(0);

  // deselect everything
  sel.removeAllRanges();

  // remove content of current selection from document
  range.deleteContents();

  // get location of current selection
  var container = range.startContainer;
  var pos = range.startOffset;

  // make a new range for the new selection
  range=document.createRange();

  if (container.nodeType==3 && insertNode.nodeType==3) {

      // if we insert text in a textnode, do optimized insertion
      container.insertData(pos, insertNode.nodeValue);

      // put cursor after inserted text
      range.setEnd(container, pos+insertNode.length);
      range.setStart(container, pos+insertNode.length);
  } 

  else {
      var afterNode;
    
      if (container.nodeType==3) {
         // when inserting into a textnode
         // we create 2 new textnodes
         // and put the insertNode in between

         var textNode = container;
         container = textNode.parentNode;
         var text = textNode.nodeValue;

         // text before the split
         var textBefore = text.substr(0,pos);
         // text after the split
         var textAfter = text.substr(pos);

         var beforeNode = document.createTextNode(textBefore);
         afterNode = document.createTextNode(textAfter);

         // insert the 3 new nodes before the old one
         container.insertBefore(afterNode, textNode);
         container.insertBefore(insertNode, afterNode);
         container.insertBefore(beforeNode, insertNode);
   
         // remove the old node
         container.removeChild(textNode);
     } 

     else {
           // else simply insert the node
        afterNode = container.childNodes[pos];
        container.insertBefore(insertNode, afterNode);
     }

     range.setEnd(afterNode, 0);
     range.setStart(afterNode, 0);
   }

   sel.addRange(range);
};



/* ---------------------------------------------------------------------- *\
  Function    : _dec_to_rgb
  Description : convert a decimal color value to rgb hexadecimal
  Usage       : var hex = _dec_to_rgb('65535');   // returns FFFF00
  Arguments   : value   - dec value
\* ---------------------------------------------------------------------- */

function _dec_to_rgb(value) {
  var hex_string = "";
  for (var hexpair = 0; hexpair < 3; hexpair++) {
       var myByte = value & 0xFF;            // get low byte
       value >>= 8;                          // drop low byte
       var nybble2 = myByte & 0x0F;          // get low nybble (4 bits)
       var nybble1 = (myByte >> 4) & 0x0F;   // get high nybble
       hex_string += nybble1.toString(16);   // convert nybble to hex
       hex_string += nybble2.toString(16);   // convert nybble to hex
  }
  return hex_string.toUpperCase();
};



/* ---------------------------------------------------------------------- *\
  Function    : outputFontSelect()
  Description : creates the Font Select drop down and inserts it into 
                    the toolbar
  Usage       : outputFontSelect(n)
  Arguments   : n   - The editor identifier that the Font Select will update
                          when making font changes (the textarea's ID)
\* ---------------------------------------------------------------------- */
function outputFontSelect(n) {

  var FontSelectObj        = ToolbarList['selectfont'];
  var FontSelect           = FontSelectObj[2];
  var FontSelectOn         = FontSelectObj[3];
  
  Fonts.sort();
  var FontSelectDropDown = new Array;
  FontSelectDropDown[n] = '<table border="0" cellpadding="0" cellspacing="0"><tr><td onMouseOver="document.getElementById(\'selectFont' + n + '\').src=\'' + FontSelectOn + '\';" onMouseOut="document.getElementById(\'selectFont' + n + '\').src=\'' + FontSelect + '\';"><img src="' + FontSelect + '" id="selectFont' + n + '" width="85" height="20" onClick="showFonts(\'' + n + '\');" unselectable="on"><br>';
  FontSelectDropDown[n] += '<span id="Fonts' + n + '" class="dropdown" style="width: 145px;">';

  for (var i = 0; i <= Fonts.length;) {
     if (Fonts[i]) {
         FontSelectDropDown[n] += '<button type="button" onClick="formatText(\'FontName\',\'' + n + '\',\'' + Fonts[i] + '\')\; hideFonts(\'' + n + '\');" onMouseOver="this.className=\'mouseOver\'" onMouseOut="this.className=\'mouseOut\'" class="mouseOut" style="width: 120px;"><table cellpadding="0" cellspacing="0" border="0"><tr><td align="left" style="font-family:' + Fonts[i] + '; font-size: 12px;">' + Fonts[i] + '</td></tr></table></button><br>';
     }        
     i++;
  }
  FontSelectDropDown[n] += '</span></td></tr></table>';
  //document.getElementById('FontSelect' + n).insertAdjacentHTML("afterBegin", FontSelectDropDown[n]);
  before(document.getElementById('FontSelect' + n), FontSelectDropDown[n]);
};


/* ---------------------------------------------------------------------- *\
  Function    : outputFontSizes()
  Description : creates the Font Sizes drop down and inserts it into 
                    the toolbar
  Usage       : outputFontSelect(n)
  Arguments   : n   - The editor identifier that the Font Sizes will update
                          when making font changes (the textarea's ID)
\* ---------------------------------------------------------------------- */
function outputFontSizes(n) {

  var FontSizeObj        = ToolbarList['selectsize'];
  var FontSize           = FontSizeObj[2];
  var FontSizeOn         = FontSizeObj[3];

  FontSizes.sort();
  var FontSizesDropDown = new Array;
  FontSizesDropDown[n] = '<table border="0" cellpadding="0" cellspacing="0"><tr><td onMouseOver="document.getElementById(\'selectSize' + n + '\').src=\'' + FontSizeOn + '\';" onMouseOut="document.getElementById(\'selectSize' + n + '\').src=\'' + FontSize + '\';"><img src="' + FontSize + '" id="selectSize' + n + '" width="49" height="20" onClick="showFontSizes(\'' + n + '\');" unselectable="on"><br>';
  FontSizesDropDown[n] += '<span id="Sizes' + n + '" class="dropdown" style="width: 170px;">';

  for (var i = 0; i <= FontSizes.length;) {
      if (FontSizes[i]) {
          FontSizesDropDown[n] += '<button type="button" onClick="formatText(\'FontSize\',\'' + n + '\',\'' + FontSizes[i] + '\')\;hideFontSizes(\'' + n + '\');" onMouseOver="this.className=\'mouseOver\'" onMouseOut="this.className=\'mouseOut\'" class="mouseOut" style="width: 145px;"><table cellpadding="0" cellspacing="0" border="0"><tr><td align="left" style="font-family: arial, verdana, helvetica;"><font size="' + FontSizes[i] + '">size ' + FontSizes[i] + '</font></td></tr></table></button><br>';
      }        
      i++;
  }
  FontSizesDropDown[n] += '</span></td></tr></table>';
  //document.getElementById('FontSizes' + n).insertAdjacentHTML("afterBegin", FontSizesDropDown[n]);
  before(document.getElementById('FontSizes' + n), FontSizesDropDown[n]);
};



/* ---------------------------------------------------------------------- *\
  Function    : hideFonts()
  Description : Hides the list of font names in the font select drop down
  Usage       : hideFonts(n)
  Arguments   : n   - The editor identifier (the textarea's ID)
\* ---------------------------------------------------------------------- */
function hideFonts(n) {
  document.getElementById('Fonts' + n).style.display = 'none'; 
};



/* ---------------------------------------------------------------------- *\
  Function    : hideFontSizes()
  Description : Hides the list of font sizes in the font sizes drop down
  Usage       : hideFontSizes(n)
  Arguments   : n   - The editor identifier (the textarea's ID)
\* ---------------------------------------------------------------------- */
function hideFontSizes(n) {
  document.getElementById('Sizes' + n).style.display = 'none'; 
};



/* ---------------------------------------------------------------------- *\
  Function    : showFonts()
  Description : Shows the list of font names in the font select drop down
  Usage       : showFonts(n)
  Arguments   : n   - The editor identifier (the textarea's ID)
\* ---------------------------------------------------------------------- */
function showFonts(n) { 
  if (document.getElementById('Fonts' + n).style.display == 'block') {
      document.getElementById('Fonts' + n).style.display = 'none';
  }
  else {
    document.getElementById('Fonts' + n).style.display = 'block'; 
    document.getElementById('Fonts' + n).style.position = 'absolute';
  }
};



/* ---------------------------------------------------------------------- *\
  Function    : showFontSizes()
  Description : Shows the list of font sizes in the font sizes drop down
  Usage       : showFonts(n)
  Arguments   : n   - The editor identifier (the textarea's ID)
\* ---------------------------------------------------------------------- */
function showFontSizes(n) { 
  if (document.getElementById('Sizes' + n).style.display == 'block') {
       document.getElementById('Sizes' + n).style.display = 'none';
  }
  else {
       document.getElementById('Sizes' + n).style.display = 'block'; 
       document.getElementById('Sizes' + n).style.position = 'absolute';
  }
};



/* ---------------------------------------------------------------------- *\
  Function    : viewSource()
  Description : Shows the HTML source code generated by the WYSIWYG editor
  Usage       : showFonts(n)
  Arguments   : n   - The editor identifier (the textarea's ID)
\* ---------------------------------------------------------------------- */
function viewSource(n) {
    var getDocument = document.getElementById("wysiwyg" + n).contentWindow.document;

      // View Source for IE        
    if (browserName == "Microsoft Internet Explorer") {
        var iHTML = getDocument.body.innerHTML;
        getDocument.body.innerText = iHTML;
    }
 
    // View Source for Mozilla/Netscape
    else {
       var html = document.createTextNode(getDocument.body.innerHTML);
       getDocument.body.innerHTML = "";
       getDocument.body.appendChild(html);
    }
  
    // Hide the HTML Mode button and show the Text Mode button
    document.getElementById('HTMLMode' + n).style.display = 'none'; 
    document.getElementById('textMode' + n).style.display = 'block';

    // set the font values for displaying HTML source
    getDocument.body.style.fontSize = "12px";
    getDocument.body.style.fontFamily = "Courier New"; 

    viewTextMode = 1;
};



/* ---------------------------------------------------------------------- *\
  Function    : viewSource()
  Description : Shows the HTML source code generated by the WYSIWYG editor
  Usage       : showFonts(n)
  Arguments   : n   - The editor identifier (the textarea's ID)
\* ---------------------------------------------------------------------- */
function viewText(n) { 
  var getDocument = document.getElementById("wysiwyg" + n).contentWindow.document;

      // View Text for IE                
  if (browserName == "Microsoft Internet Explorer") {
      var iText = getDocument.body.innerText;
      getDocument.body.innerHTML = iText;
  }
  
     // View Text for Mozilla/Netscape
  else {
      var html = getDocument.body.ownerDocument.createRange();
      html.selectNodeContents(getDocument.body);
      getDocument.body.innerHTML = html.toString();
  }
  
     // Hide the Text Mode button and show the HTML Mode button
  document.getElementById('textMode' + n).style.display = 'none'; 
  document.getElementById('HTMLMode' + n).style.display = 'block';

     // reset the font values
  getDocument.body.style.fontSize = "";
  getDocument.body.style.fontFamily = ""; 
  viewTextMode = 0;
};

   /**Ensure that not saving text mode  - not source mode
   **/
function ensureText(n)
{   if (viewTextMode == 1)
         viewText(n);
}


/* ---------------------------------------------------------------------- *\
  Function    : updateTextArea()
  Description : Updates the text area value with the HTML source of the WYSIWYG
  Usage       : updateTextArea(n)
  Arguments   : n   - The editor identifier (the textarea's ID)
\* ---------------------------------------------------------------------- */
function updateTextArea(n) {
  document.getElementById(n).value = document.getElementById("wysiwyg" + n).contentWindow.document.body.innerHTML;
};
