//
// openWYSIWYG v1.01 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.
\* ---------------------------------------------------------------------- */

// Images Directory
imagesDir=toolpath+'editor/icons/';

// CSS Directory
cssDir=toolpath+'editor/';

// Popups Directory
popupsDir=toolpath+'editor/';

// WYSIWYG Width and Height
wysiwygWidth='100%';
wysiwygHeight='250px';

// 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]='separator';
	buttonName[5]='subscript';
	buttonName[6]='superscript';
	buttonName[7]='separator';
	buttonName[8]='justifyleft';
	buttonName[9]='justifycenter';
	buttonName[10]='justifyright';
	buttonName[11]='separator';
	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]='separator';
	buttonName2[3]='cut';
	buttonName2[4]='copy';
	buttonName2[5]='paste';
	buttonName2[6]='separator';
  buttonName2[7]='undo';
	buttonName2[8]='redo';
  buttonName2[9]='separator';
	buttonName2[10]='inserttable';
  buttonName2[11]='insertimage';
  buttonName2[12]='createlink';
	buttonName2[13]='smile';
	buttonName2[14]='cleancode';
	buttonName2[15]='separator';
	buttonName2[16]='viewSource';
	buttonName2[17]='separator';
  buttonName2[18]='help';

// 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'],
	"separator":['','',imagesDir+'separator.gif',imagesDir+'separator.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'],
  "smile":['Smile','Smile',imagesDir+'smile.gif',imagesDir+'smile_on.gif'],
  "cleancode":['CleanCode','CleanCode',imagesDir+'cleancode.gif',imagesDir+'cleancode_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'],
	"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    : 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 range=this.ownerDocument.createRange();
		range.setStartBefore(this);
		var parsedHTML=range.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;


/* ---------------------------------------------------------------------- *\
  Function    : generate_wysiwyg()
  Description : replace textarea with wysiwyg editor
  Usage       : generate_wysiwyg("textarea_id");
  Arguments   : textarea_id - ID of textarea to replace
\* ---------------------------------------------------------------------- */
function generate_wysiwyg(textareaID,width,height) {

	// Hide the textarea
	document.getElementById(textareaID).style.display='none';

  // Pass the textareaID to the "elem" variable.
  var elem=textareaID;

	// Set the width and height
	if(typeof(width)!='undefined' && width) {
		if(width.indexOf('%')==-1) width+='px';
		else if(width=='auto') width='100%';
		wysiwygWidth=width;
	}
	if(typeof(height)!='undefined' && height) {
		if(height.indexOf('%')==-1) height+='px';
		else if(height=='auto') height='100%';
		wysiwygHeight=height;
	}

	// Toolbars width is 2 pixels wider than the wysiwygs
	toolbarWidth=wysiwygWidth; //parseFloat(wysiwygWidth)+2;

  // Generate WYSIWYG toolbar one
  var toolbar;
  toolbar='<table cellpadding="0" cellspacing="0" border="0" style="text-align: left; width:'+toolbarWidth+'; border: 1px solid #666666; height: 26px; background-image: url('+toolpath+'editor/icons/background_silver.jpg);"><tr><td style="width:6px; padding-left:0px; padding-right:0px"><img src="'+imagesDir+'separator2.gif" alt="" hspace="3"></td>';

	// Create IDs for inserting Font Type and Size drop downs
	toolbar+='<td style="width:90px; padding-left:0px; padding-right:0px"><span id="FontSelect'+elem+'"></span></td>';
	toolbar+='<td style="width:60px; padding-left:0px; padding-right:0px"><span id="FontSizes'+elem+'"></span></td>';

	// Output all command buttons that belong to toolbar one
	for(var loop=0;loop<=buttonName.length;) {
    if(buttonName[loop]) {
	    var buttonObj=ToolbarList[buttonName[loop]];
		  var buttonID=buttonObj[0];
	    var buttonTitle=buttonObj[1];
      var buttonImage=buttonObj[2];
		  var buttonImageRollover=buttonObj[3];
			if(buttonName[loop]=='separator') {
		    toolbar+='<td style="width:12px; padding-left:0px; padding-right:0px" align="center"><img src="'+buttonImage+'" border=0 unselectable="on" width="2" height="18" hspace="2" unselectable="on"></td>';
			} else {
		    toolbar+='<td style="width:22px; padding-left:0px; padding-right:0px"><img src="'+buttonImage+'" border=0 unselectable="on" title="'+buttonTitle+'" id="'+buttonID+'" class="buttonOut" onClick="formatText(this.id,\''+elem+ '\');" onmouseover="if(className==\'buttonOut\') { className=\'buttonOver\' }; this.src=\''+buttonImageRollover+'\';" onmouseout="if(className==\'buttonOver\') { className=\'buttonOut\' }; this.src=\''+buttonImage+'\';" unselectable="on" width="20" height="20"></td>';
	    }
    }
    loop++;
  }
  toolbar+='<td style="padding-left:0px; padding-right:0px">&nbsp;</td></tr></table>';

  // Generate WYSIWYG toolbar two
  var toolbar2;
  toolbar2='<table cellpadding="0" cellspacing="0" border="0" style="text-align: left; width:'+toolbarWidth+'; border: 1px solid #666666; height: 24px; background-image: url('+toolpath+'editor/icons/background_silver.jpg); border-bottom: 0px; border-top: 0px; padding-left:0px; padding-right:0px"><tr><td style="width:6px; padding-left:0px; padding-right:0px"><img src="'+imagesDir+'separator2.gif" alt="" hspace="3"></td>';

  // Output all command buttons that belong to toolbar two
  for(var loop2=0;loop2<=buttonName2.length;) {
    if(buttonName2[loop2]) {
	    var buttonObj=ToolbarList[buttonName2[loop2]];
		  var buttonID=buttonObj[0];
	    var buttonTitle=buttonObj[1];
      var buttonImage=buttonObj[2];
		  var buttonImageRollover=buttonObj[3];
		  if(buttonName2[loop2]=='separator') {
		    toolbar2+='<td style="width:12px; padding-left:0px; padding-right:0px" align="center"><img src="'+buttonImage+'" border=0 unselectable="on" width="2" height="18" hspace="2" unselectable="on"></td>';
			} else if(buttonName2[loop2]=='viewSource') {
		    toolbar2+='<td style="width:22px; padding-left:0px; padding-right:0px">';
				toolbar2+='<span id="HTMLMode'+elem+'"><img src="'+buttonImage+'" border="0" unselectable="on" title="'+buttonTitle+'" id="'+buttonID+'" class="buttonOut" onClick="formatText(this.id,\''+elem+ '\');" onmouseover="if(className==\'buttonOut\') { className=\'buttonOver\' }; this.src=\''+buttonImageRollover+'\';" onmouseout="if(className==\'buttonOver\') { className=\'buttonOut\' }; this.src=\''+buttonImage+'\';" unselectable="on" width="20" height="20"></span>';
				toolbar2+='<span id="textMode'+elem+'"><img src="'+imagesDir+'view_text.gif" border="0" unselectable="on" title="viewText" id="ViewText" class="buttonOut" onClick="formatText(this.id,\'' +elem+'\');" onmouseover="if(className==\'buttonOut\') { className=\'buttonOver\' }; this.src=\''+imagesDir+'view_text_on.gif\';" onmouseout="if(className==\'buttonOver\') { className=\'buttonOut\' }; this.src=\''+imagesDir+'view_text.gif\';" unselectable="on" width="20" height="20"></span>';
	      toolbar2+='</td>';
			} else {
		    toolbar2+='<td style="width:22px; padding-left:0px; padding-right:0px"><img src="'+buttonImage+'" border=0 unselectable="on" title="'+buttonTitle+'" id="'+buttonID+'" class="buttonOut" onClick="formatText(this.id,\''+ elem+'\');" onmouseover="if(className==\'buttonOut\') { className=\'buttonOver\' }; this.src=\''+buttonImageRollover+'\';" onmouseout="if(className==\'buttonOver\') { className=\'buttonOut\' }; this.src=\''+buttonImage+'\';" unselectable="on" width="20" height="20"></td>';
	    }
    }
		loop2++;
  }
  toolbar2+='<td style="padding-left:0px; padding-right:0px">&nbsp;</td></tr></table>';

	// Create iframe which will be used for rich text editing
	var iframe='<table cellpadding="0" cellspacing="0" border="0" style="text-align: left; width:'+wysiwygWidth+'; height:'+wysiwygHeight+'; border: 1px inset #000000;"><tr><td valign="top" style=\"background-color: #ffffff; padding-left:0px; padding-right:0px\">\n'+'<iframe frameborder="0" marginheight="5" marginwidth="5" id="wysiwyg'+elem+'"></iframe>\n'+'</td></tr></table>\n';

  // Insert after the textArea both toolbar one and two
  document.getElementById(elem).insertAdjacentHTML('afterEnd',toolbar+toolbar2+iframe);

  // Insert the Font Type and Size drop downs into the toolbar
	outputFontSelect(elem);
	outputFontSizes(elem);

  // Hide the dynamic drop down lists for the Font Types and Sizes
  hideFonts(elem);
	hideFontSizes(elem);

	// Hide the "Text Mode" button
	document.getElementById('textMode'+elem).style.display='none';

	// Give the iframe the global wysiwyg height and width
  document.getElementById('wysiwyg'+elem).style.width=wysiwygWidth;
  document.getElementById('wysiwyg'+elem).style.height=wysiwygHeight;

	// Pass the textarea's existing text over to the content variable
  var content=document.getElementById(elem).value;

	var doc=document.getElementById('wysiwyg'+elem).contentWindow.document;

	// Write the textarea's content into the iframe
  doc.open();
  doc.write(content);
  doc.close();

	// Make the iframe editable in both Mozilla and IE
  doc.body.contentEditable=true;
  doc.designMode='on';

  	// Update the textarea with content in WYSIWYG when user submits form
  var browserName=navigator.appName;
  if(browserName=='Microsoft Internet Explorer') {
    for(var idx=0;idx<document.forms.length;idx++) {
      document.forms[idx].attachEvent('onsubmit',function(){updateTextArea(elem)});
    }
  } else {
  	for(var idx=0;idx<document.forms.length;idx++) {
    	document.forms[idx].addEventListener('submit',function OnSubmit(){updateTextArea(elem)},true);
    }
  }

};



/* ---------------------------------------------------------------------- *\
  Function    : formatText()
  Description : replace textarea with wysiwyg editor
  Usage       : formatText(id, n, selected);
  Arguments   : id - The execCommand (e.g. Bold)
                elem - The editor identifier that the command
								     affects (the textarea's ID)
                selected - The selected value when applicable (e.g. Arial)
\* ---------------------------------------------------------------------- */
function formatText(id,elem,selected) {

  // When user clicks toolbar button make sure it always targets its respective WYSIWYG
  document.getElementById('wysiwyg'+elem).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 loop=0;loop<=formatIDs.length;) {
		if(formatIDs[loop]==id) {
			 var disabled_id=1;
		}
	  loop++;
	}

	// Check if in Text Mode and disabled button was clicked
	if(viewTextMode==1 && disabled_id==1) {
	  //alert('You are in HTML Mode. Please switch to editing mode to use this feature.');
	} else {

	  // FontSize
	  if(id=='FontSize') {
      document.getElementById('wysiwyg'+elem).contentWindow.document.execCommand('FontSize',false,selected);
	  }

		// FontName
	  else if(id=='FontName') {
      document.getElementById('wysiwyg'+elem).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=200,popH=165;
      var leftPos=(w-popW)/2,topPos=(h-popH)/2;
      var currentColor=_dec_to_rgb(document.getElementById('wysiwyg'+elem).contentWindow.document.queryCommandValue(id));
	    window.open(popupsDir+'select_color.html?color='+currentColor+'&command='+id+'&wysiwyg='+ elem,'popup','location=0,status=0,scrollbars=0,width='+popW+',height='+popH+',top='+topPos+',left='+leftPos);
    }

		// InsertImage
	  else if(id=='InsertImage') {
      window.open(popupsDir+'insert_image.html?wysiwyg='+elem,'popup', 'location=0,status=0,scrollbars=0,resizable=0,width=400,height=190');
	  }

		// InsertTable
	  else if(id=='InsertTable') {
	    window.open(popupsDir+'create_table.html?wysiwyg='+elem,'popup', 'location=0,status=0,scrollbars=0,resizable=0,width=400,height=360');
	  }

		// CreateLink
	  else if(id=='CreateLink') {
	    window.open(popupsDir+'insert_hyperlink.html?wysiwyg='+elem,'popup', 'location=0,status=0,scrollbars=0,resizable=0,width=300,height=110');
	  }

		// ViewSource
    else if(id=='ViewSource') {
	    viewSource(elem);
	  }

		// ViewText
		else if(id=='ViewText') {
	    viewText(elem);
	  }

		// Help
		else if(id=='Help') {
	    window.open(popupsDir+'about.html','popup', 'location=0,status=0,scrollbars=0,resizable=0,width=400,height=330');
	  }

		// Smile
		else if(id=='Smile') {
			window.open(popupsDir+'select_smile.html?wysiwyg='+elem+'&toolpath='+toolpath,'popup','location=0,status=0,scrollbars=0,resizable=0,width=450,height=230');
		}

		// Clean Code
		else if(id=='CleanCode') {
			var getDocument=document.getElementById('wysiwyg'+elem).contentWindow.document;
			var iHTML=getDocument.body.innerHTML;
			getDocument.body.innerHTML=CleanCode(iHTML);
		}

		// Every other command
	  else {
      document.getElementById('wysiwyg'+elem).contentWindow.document.execCommand(id,false,null);
		}
  }
};


/* ---------------------------------------------------------------------- *\
  Function    : CodeCleaner()
  Description : Cleans Code From Word, etc
  Added By	  : aspronisi [Guest]
\* ---------------------------------------------------------------------- */

function CleanCode(str) {
   str=str.replace(/<([\w]+) class=([^ |>]*)([^>]*)/gi, '<$1$3');
   str=str.replace(/<([\w]+) style=([^"]*)"([^>]*)/gi, '<$1$3');
   str=str.replace(/width=([^ |>]*)([^>]*)/gi, '');
   str=str.replace(/type=([^ |>]*)([^>]*)/gi, '');
   str=str.replace(/classname=([^ |>]*)([^>]*)/gi, '');
   str=str.replace(/align=([^ |>]*)([^>]*)/gi, '');
   str=str.replace(/valign=([^ |>]*)([^>]*)/gi, '');
   str=str.replace(/<\\?\??xml[^>]>/gi, '');
   str=str.replace(/<\/?\w+:[^>]*>/gi, '');
   str=str.replace(/<st1:.*?>/gi, '');
   str=str.replace(/o:/gi, '');
   str=str.replace(/<span([^>])*>(&nbsp;)*\s*<\/span>/gi, '');
   str=str.replace(/<span[^>]*>/gi, '');
   str=str.replace(/<\/span[^>]*>/gi, '');
   str=str.replace(/<font[^>]*>/gi, '');
   str=str.replace(/<\/font>/gi, '');
   str=str.replace(/<p([^>])*>(&nbsp;)*\s*<\/p>/gi, '');
   str=str.replace(/<p[^>]*>/gi, '');
   str=str.replace(/<\/p[^>]*>/gi, '');
   str=str.replace(/<h([^>])[0-9]>(&nbsp;)*\s*<\/h>/gi, '');
   str=str.replace(/<h[^>][0-9]>/gi, '');
   str=str.replace(/<\/h[^>][0-9]>/gi, '');
   return str;
};


/* ---------------------------------------------------------------------- *\
  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>)
                elem - The editor identifier that the HTML
								     will be inserted into (the textarea's ID)
\* ---------------------------------------------------------------------- */
function insertHTML(html,elem) {
  var browserName=navigator.appName;
	if(browserName=='Microsoft Internet Explorer') {
	  document.getElementById('wysiwyg'+elem).contentWindow.document.selection.createRange().pasteHTML(html);
	} else {
	  var div=document.getElementById('wysiwyg'+elem).contentWindow.document.createElement('div');
		div.innerHTML=html;
		var node=insertNodeAtSelection(div,elem);
	}
}


/* ---------------------------------------------------------------------- *\
  Function    : insertNodeAtSelection()
  Description : insert HTML into WYSIWYG in rich text (mozilla)
  Usage       : insertNodeAtSelection(insertNode, elem)
  Arguments   : insertNode - The HTML being inserted (must be innerHTML
	                           inserted within a div element)
                elem       - The editor identifier that the HTML will be
								             inserted into (the textarea's ID)
\* ---------------------------------------------------------------------- */
function insertNodeAtSelection(insertNode,elem) {
  // get current selection
  var sel=document.getElementById('wysiwyg'+elem).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(elem)
  Arguments   : elem  - The editor identifier that the Font Select will update
	                    when making font changes (the textarea's ID)
\* ---------------------------------------------------------------------- */
function outputFontSelect(elem) {

  var FontSelectObj=ToolbarList['selectfont'];
  var FontSelect=FontSelectObj[2];
  var FontSelectOn=FontSelectObj[3];

	Fonts.sort();
	var FontSelectDropDown=new Array;
	FontSelectDropDown[elem]= '<table border="0" cellpadding="0" cellspacing="0"><tr><td onMouseOver="document.getElementById(\'selectFont' +elem+'\').src=\''+FontSelectOn+'\';" onMouseOut="document.getElementById(\'selectFont'+elem+ '\').src=\''+FontSelect+'\';"><img src="'+FontSelect+'" id="selectFont'+elem+'" width="85" height="20" onClick="showFonts(\''+elem+'\');" unselectable="on"><br>';
	FontSelectDropDown[elem]+='<span id="Fonts'+elem+'" class="dropdown" style="width: 145px;">';
	for(var loop=0;loop<=Fonts.length;) {
	  if(Fonts[loop]) {
      FontSelectDropDown[elem]+='<button type="button" onClick="formatText(\'FontName\',\''+elem+ '\',\''+Fonts[loop]+'\')\; hideFonts(\''+elem+'\');" 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[loop]+'; font-size: 12px;">'+Fonts[loop]+'</td></tr></table></button><br>';
    }
	  loop++;
  }
	FontSelectDropDown[elem]+='</span></td></tr></table>';
	document.getElementById('FontSelect'+elem).insertAdjacentHTML("afterBegin", FontSelectDropDown[elem]);
};



/* ---------------------------------------------------------------------- *\
  Function    : outputFontSizes()
  Description : creates the Font Sizes drop down and inserts it into
	              the toolbar
  Usage       : outputFontSelect(elem)
  Arguments   : elem  - The editor identifier that the Font Sizes will update
	                    when making font changes (the textarea's ID)
\* ---------------------------------------------------------------------- */
function outputFontSizes(elem) {

  var FontSizeObj=ToolbarList['selectsize'];
  var FontSize=FontSizeObj[2];
  var FontSizeOn=FontSizeObj[3];

	FontSizes.sort();
	var FontSizesDropDown=new Array;
	FontSizesDropDown[elem]= '<table border="0" cellpadding="0" cellspacing="0"><tr><td onMouseOver="document.getElementById(\'selectSize' +elem+'\').src=\''+FontSizeOn+'\';" onMouseOut="document.getElementById(\'selectSize'+elem+'\').src=\''+FontSize+'\';"><img src="'+FontSize+'" id="selectSize'+elem+'" width="49" height="20" onClick="showFontSizes(\''+elem+'\');" unselectable="on"><br>';
  FontSizesDropDown[elem]+='<span id="Sizes'+elem+'" class="dropdown" style="width: 170px;">';
	for (var loop=0;loop<=FontSizes.length;) {
	  if(FontSizes[loop]) {
      FontSizesDropDown[elem]+='<button type="button" onClick="formatText(\'FontSize\',\''+elem+'\',\''+FontSizes[loop]+'\')\;hideFontSizes(\''+elem+'\');" 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[loop]+'">size '+FontSizes[loop]+'</font></td></tr></table></button><br>';
    }
	  loop++;
  }
	FontSizesDropDown[elem]+='</span></td></tr></table>';
	document.getElementById('FontSizes'+elem).insertAdjacentHTML("afterBegin",FontSizesDropDown[elem]);
};



/* ---------------------------------------------------------------------- *\
  Function    : hideFonts()
  Description : Hides the list of font names in the font select drop down
  Usage       : hideFonts(elem)
  Arguments   : elem  - The editor identifier (the textarea's ID)
\* ---------------------------------------------------------------------- */
function hideFonts(elem) {
  document.getElementById('Fonts'+elem).style.display='none';
};



/* ---------------------------------------------------------------------- *\
  Function    : hideFontSizes()
  Description : Hides the list of font sizes in the font sizes drop down
  Usage       : hideFontSizes(elem)
  Arguments   : elem  - The editor identifier (the textarea's ID)
\* ---------------------------------------------------------------------- */
function hideFontSizes(elem) {
  document.getElementById('Sizes'+elem).style.display='none';
};



/* ---------------------------------------------------------------------- *\
  Function    : showFonts()
  Description : Shows the list of font names in the font select drop down
  Usage       : showFonts(elem)
  Arguments   : elem  - The editor identifier (the textarea's ID)
\* ---------------------------------------------------------------------- */
function showFonts(elem) {
  if(document.getElementById('Fonts'+elem).style.display=='block') {
    document.getElementById('Fonts'+elem).style.display='none';
	}
  else {
    document.getElementById('Fonts'+elem).style.display='block';
    document.getElementById('Fonts'+elem).style.position='absolute';
  }
};



/* ---------------------------------------------------------------------- *\
  Function    : showFontSizes()
  Description : Shows the list of font sizes in the font sizes drop down
  Usage       : showFonts(elem)
  Arguments   : elem  - The editor identifier (the textarea's ID)
\* ---------------------------------------------------------------------- */
function showFontSizes(elem) {
  if (document.getElementById('Sizes'+elem).style.display=='block') {
    document.getElementById('Sizes'+elem).style.display='none';
	}
  else {
    document.getElementById('Sizes'+elem).style.display='block';
    document.getElementById('Sizes'+elem).style.position='absolute';
  }
};



/* ---------------------------------------------------------------------- *\
		Function    : viewSource()
		Description : Shows the HTML source code generated by the WYSIWYG editor
		Usage       : showFonts(elem)
		Arguments   : elem - The editor identifier (the textarea's ID)
\* ---------------------------------------------------------------------- */
function viewSource(elem) {
  var getDocument=document.getElementById('wysiwyg'+elem).contentWindow.document;
  var browserName=navigator.appName;

	// 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'+elem).style.display='none';
	document.getElementById('textMode'+elem).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(elem)
  Arguments   :elem  - The editor identifier (the textarea's ID)
\* ---------------------------------------------------------------------- */
function viewText(elem) {
  var getDocument=document.getElementById('wysiwyg'+elem).contentWindow.document;
  var browserName=navigator.appName;

	// 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'+elem).style.display='none';
	document.getElementById('HTMLMode'+elem).style.display='block';

	// reset the font values
  getDocument.body.style.fontSize='';
	getDocument.body.style.fontFamily='';
	viewTextMode=0;
};



/* ---------------------------------------------------------------------- *\
  Function    : updateTextArea()
  Description : Updates the text area value with the HTML source of the WYSIWYG
  Usage       : updateTextArea(elem)
  Arguments   :elem  - The editor identifier (the textarea's ID)
\* ---------------------------------------------------------------------- */
function updateTextArea(elem) {
  document.getElementById(elem).value=document.getElementById('wysiwyg'+elem).contentWindow.document.body.innerHTML;
};
