/* -----------------------------------------------------------------------------
   Heavily modified by Eric Svensson
   The code has among a lot of things become object oriented.
----------------------------------------------------------------------------- */


////////////////////////////////////////////////////////////////////////////////
//
// Richtext Editor: Fork (RTEF) VERSION: 0.004
// Released: 9/07/2006
// For the latest release visit http://rtef.info
// For support visit http://rtef.info/deluxebb
//
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
//
// The MIT License
//
// Copyright (c) 2006 Timothy Bell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
////////////////////////////////////////////////////////////////////////////////



function RTEF() {

    // Constants

    this.minWidth = 500;					// minumum width
    this.wrapWidth = 1268;					// width at which all icons will appear on one bar
    this.maxchar = 64000;					// maximum number of characters per save
    this.lang = "en";						// xhtml language
    this.lang_direction = "ltr";			// language direction:ltr=left-to-right,rtl=right-to-left
    this.encoding = "utf-8";				// xhtml encoding
    this.zeroBorder = "#c0c0c0";			// guideline color - see showGuidelines()
    this.btnText = "submit";				// Button value for non-designMode() & fullsceen rte

    this.keep_absolute = true;			// !!!Disabled - see line 565 for details!!!!!
    // By default IE will try to convery all hyperlinks to absolute paths. By
    // setting this value to "false" it will retain the relative path.

    this.IF_BTNROW = "row";
    this.IF_BTNROW_LEFTF = "rowleftf";
    this.IF_BTNROW_END = "rowend";
    this.IF_TOPROW = "toprow";
    this.IF_SEPARATOR = "separator";
    this.IF_BAR = "bar";
    this.IF_IMG = "image";
    this.IF_FONTFORMAT = "fontformat";
    this.IF_FONTFAMILY = "fontfamily";
    this.IF_FONTSIZE = "fontsize";
    this.IF_FONTAPPLY = "fontapply";
    this.IF_CUT = "cut";
    this.IF_COPY = "copy";
    this.IF_PASTE = "paste";
    this.IF_PASTETEXT = "pastetext";
    this.IF_PASTEWORD = "pasteword";
    this.IF_UNDO = "undo";
    this.IF_REDO = "redo";
    this.IF_JUSTLEFT = "justleft";
    this.IF_JUSTCENTER = "justcenter";
    this.IF_JUSTFULL = "justfull";
    this.IF_JUSTRIGHT = "justright";
    this.IF_BOLD = "bold";
    this.IF_ITALIC = "italic";
    this.IF_UNDERLINE = "underline";
    this.IF_SPECIALCHAR = "specialchar";
    this.IF_JAPANESE = "japanese";
    this.IF_HYPERLINK = "hyperlink";
    this.IF_INSERTIMAGE = "insertimage";
    this.IF_TABLE = "table";
    this.IF_REPLACE = "replace";
    this.IF_WORDCOUNT = "wordcount";
    this.IF_SELECTALL = "selectall";
    this.IF_PRINT = "print";
    this.IF_LISTORDERED = "listordered";
    this.IF_LISTUNORDERED = "listunordered";
    this.IF_OUTDENT = "outdent";
    this.IF_INDENT = "indent";
    this.IF_TEXTCOLOR = "textcolor";
    this.IF_BGCOLOR = "bgcolor";
    this.IF_HR = "hr";
    this.IF_STRIKETHROUGH = "strikethrough";
    this.IF_HIDDEN = "hiddentext";
    this.IF_SUPERSCRIPT = "superscript";
    this.IF_SUBSCRIPT = "subscript";
    this.IF_UNFORMAT = "unformat";
    this.IF_SPELLCHECK = "spellcheck";
    this.IF_QUOTE = "quote";


    // Pointers
    this.InsertChar;
    this.InsertTable;
    this.InsertLink;
    this.InsertImg;
    this.dlgReplace;
    this.dlgPasteText;
    this.dlgPasteWord;

    // Initialize variables & attributes
    this.rng;
    this.rngEndOffset;
    this.currentRTE;
    this.allRTEs = "";
    this.obj_width;
    this.obj_height;
    this.imagesPath;
    this.includesPath;
    this.cssFile;
    this.generateXHTML = true;
    this.isRichText = false;

    this.userThemeID = '';
    this.viewingSRC = false;
    this.blogmode = false;
    this.allowSRC = true;
    this.enableDesignModeTryCount = 0;
    this.html = '';

    // check to see if designMode mode is available
    if (document.getElementById && document.designMode) {
    	this.isRichText = true;
    }
    // for testing standard textarea, uncomment the following line
    // this.isRichText = false;

    this.replacements = new Array (
        new RegExp(String.fromCharCode(145),'g'), "'",
        new RegExp(String.fromCharCode(146),'g'), "'",
        new RegExp("'"), "&#39;",
        // convert all types of double quotes
        new RegExp(String.fromCharCode(147),'g'), "\"",
        new RegExp(String.fromCharCode(148),'g'), "\"",
        //new RegExp("\""), "&#34;",
        //replace carriage returns & line feeds
        new RegExp("[\r\n]",'g'), " "
    );

    this.initLangVars();

}

RTEF.prototype.initRTE = function(imgPath, incPath, css, genXHTML, blogmode, allowSRC, userThemeID) {
	//set paths vars
	this.imagesPath = imgPath;
	this.includesPath = incPath;
	this.cssFile = css;
	this.generateXHTML = genXHTML;
	this.blogmode = blogmode;
	this.allowSRC = allowSRC;
	this.userThemeID = userThemeID;
	if (this.isRichText) {
		document.writeln('<style type="text/css">@import "' + this.includesPath + 'rte.css";</style>');
	}
	if (!isIE) {
		this.minWidth = this.minWidth-50;
		this.wrapWidth = this.wrapWidth-106;
	} else if (isIE7) {
		this.minWidth = this.minWidth+2;
		this.wrapWidth = this.wrapWidth+4;
	}
}


RTEF.prototype.rteSafe = function(html) {
	html = this.trim(html);
	for (var i=0; i<this.replacements.length; i = i+2) {
		html = html.replace(this.replacements[i], this.replacements[i+1]);
	}
	return html;
}

RTEF.prototype.writeRichText = function(rte, html, css, width, height,
                                buttons, readOnly, userLoggedIn, topicFHTML, formatSelHTML, submitBtnHTML) {

    var replacements = new Array(
    "&amp;", "&",
    "&quote", '"',
    "&lt;", "<",
    "&gt;", ">"
    );
    if (document.getElementById(html)) {
        html = document.getElementById(html).value;
        for (i=0; i<replacements.length; i = i+2) {
            html = html.replace(replacements[i], replacements[i+1]);
        }
    }

    this.currentRTE = rte;
	if (this.allRTEs.length > 0) this.allRTEs += ";";
	this.allRTEs += rte;
	html = this.replaceIt(html,'&quot;','"');
	// CM 06/04/05 stops single quotes from messing everything up
    if (!isIE) html = this.replaceIt(html,"'","&apos;");

    this.html = html;

	var iconWrapWidth = this.wrapWidth;
	var tablewidth;
	if (readOnly) {
		buttons = false;
	}

	iconWrapWidth = iconWrapWidth-25;
	//adjust minimum table widths
	if (buttons && (width < this.minWidth)) {
		width = this.minWidth;
	}

	if (this.isRichText) {

		var rte_css = "";
		if (css.length > 0) {
			rte_css = css;
		}else{
			rte_css = this.cssFile;
		}

		// preload of the design icon
		document.writeln('<img src="'+this.imagesPath+'design.gif" style="display:none;" />');

        document.writeln('<div class="rteDiv">');
		if (buttons) {

            if (this.blogmode) {

    			this.insertButtonRow( new Array(
                    this.IF_BAR, this.IF_FONTFORMAT, this.IF_FONTFAMILY,
                    this.IF_FONTAPPLY, this.IF_FONTSIZE ),
                rte, "Buttons1_"+rte,this.IF_TOPROW );


                this.insertButtonRow( new Array(
                    this.IF_BAR, this.IF_PRINT, this.IF_SELECTALL,
                    this.IF_CUT, this.IF_COPY, this.IF_PASTE, this.IF_PASTETEXT,
                    this.IF_PASTEWORD, this.IF_SEPARATOR, this.IF_UNDO,
                    this.IF_REDO, this.IF_SEPARATOR, this.IF_BOLD,
                    this.IF_ITALIC, this.IF_UNDERLINE, this.IF_STRIKETHROUGH,
                    this.IF_SEPARATOR, this.IF_JUSTLEFT, this.IF_JUSTCENTER, this.IF_JUSTRIGHT,
                    this.IF_JUSTFULL, this.IF_SEPARATOR, this.IF_LISTORDERED,
                    this.IF_LISTUNORDERED, this.IF_OUTDENT, this.IF_INDENT ),
    			rte,"Buttons2_"+rte );


    			this.insertButtonRow( new Array(
                    this.IF_BAR, this.IF_TEXTCOLOR, this.IF_BGCOLOR,
                    this.IF_SEPARATOR, this.IF_HR, this.IF_SEPARATOR,
                    this.IF_SPECIALCHAR, this.IF_JAPANESE, this.IF_HYPERLINK,
                    this.IF_INSERTIMAGE, this.IF_TABLE, this.IF_SEPARATOR,
                    this.IF_REPLACE, this.IF_WORDCOUNT ),
    			rte,"Buttons3_"+rte );

			}else{

                var showTopicFormatBox = (topicFHTML.length>0 || formatSelHTML.lengtH>0);

                document.writeln('<div id="newPost'+(!userLoggedIn ? 'Not' : '')+'LoggedinBox"'+(!showTopicFormatBox ? ' class="noTopicNFormatBox"' : '')+'>');

                if (!userLoggedIn) {
                    document.writeln('<div id="newPostLoginBox">');
                    document.writeln('<input id="newPostLoginFUser" type="text" name="username" value="Användare" maxlength="50" alt="Användare" tabindex="4" />');
                    document.writeln('<input id="newPostLoginFPass" type="password" name="password" value="Lösenord" maxlength="50" alt="Lösenord" tabindex="5" />');
                    document.writeln('</div><div id="newPostLoginBoxMargin"></div>');
                }

                if (showTopicFormatBox) {
                    document.writeln('<div id="newPostTopicAndFormatBox">');
                    document.writeln(topicFHTML);
                    document.writeln(formatSelHTML);
                    document.writeln('</div>');
                }

    			this.insertButtonRow( new Array(
                    this.IF_BAR, this.IF_UNDO, this.IF_REDO, this.IF_SEPARATOR,
                    this.IF_BOLD, this.IF_ITALIC, this.IF_UNDERLINE,
                    this.IF_SEPARATOR, this.IF_HIDDEN, this.IF_QUOTE, this.IF_SEPARATOR,
                    this.IF_SPECIALCHAR, this.IF_JAPANESE, this.IF_HYPERLINK,
                    this.IF_INSERTIMAGE, this.IF_SEPARATOR,
                    this.IF_REPLACE, this.IF_WORDCOUNT ),
                rte,"Buttons1_"+rte,this.IF_TOPROW,this.IF_BTNROW_LEFTF );

                document.writeln('<div class="clearF"><img src="http://img.gon.se/playing.se/filler.gif" width="1" height="1" alt="" /></div>');
                document.writeln('</div>'); // end div#newpostNotLoggedinBox

			}
		}

        // Main RTE iframe
		document.writeln('<iframe class="rteIframe" tabindex="8" id="'+rte+'" width="' + width + '" height="' + height + '" frameborder="0" src="' + this.includesPath + 'blank.htm" onfocus="'+RTEFObjectName+'.dlgCleanUp();"></iframe>');

        // bottom button row
		if (!readOnly) {
			document.writeln('<div id="vs'+rte+'" name="vs'+rte+'" class="rteBk">');
			if (!this.blogmode) document.writeln(submitBtnHTML);
			this.insertElement(this.IF_BAR,rte);
			document.writeln('<img class="rtePreviewBtn" id="rtefPreviewBtn" src="'+this.imagesPath+'preview.gif" alt="" />');
            if (this.allowSRC) document.writeln('<img class="rteModeBtn" id="imgSrc'+rte+'" src="'+this.imagesPath+'code.gif" alt="" title="" alt="'+this.lblModeHTML+'" onclick="'+RTEFObjectName+'.toggleHTMLSrc(\''+rte+'\', ' + buttons + ');" />');
            //document.writeln('<span id="_xtSrc'+rte+'" style="font-family:tahoma,sans-serif;font-size:12px;color:#d43875;CURSOR: default;display:none;">'+this.lblModeHTML+'</span>');
			document.writeln('</div>');
		}

		// palette iframe
		document.writeln('<iframe width="142" height="98" id="cp'+rte+'" src="' + this.includesPath + 'palette.htm" scrolling="no" frameborder=0 style="margin:0;border:0;visibility:hidden;position:absolute;border:1px solid #cdcdcd;top:-1000px;left:-1000px"></iframe>');

        // hidden data fields
		document.writeln('<input type="hidden" id="hdn'+rte+'" name="'+rte+'" value="" style="position: absolute;left:-1000px;top:-1000px;">');
		document.writeln('<input type="hidden" id="size'+rte+'" name="size'+rte+'" value="'+height+'" style="position: absolute;left:-1000px;top:-1000px;">');

		document.writeln('</div>'); // end div#rteDiv


		document.getElementById('hdn'+rte).value = html; // set initial contents

		this.enableDesignMode(rte, rte_css, readOnly); // enable browser design mode

	}else{

		buttons = false;
		// CM non-designMode() UI
		html = this.parseBreaks(html);
		document.writeln('<div style="font:12px Verdana, Arial, Helvetica, sans-serif;width: ' + width + 'px;padding:15px;">');
		if (!readOnly) {
			document.writeln('<div style="color:gray">'+this.lblnon_designMode+'</div><br />');
			document.writeln('<textarea name="'+rte+'" id="'+rte+'" style="width: ' + width + 'px; height: ' + height + 'px;">' + html + '</textarea>');
		}else{
			document.writeln('<textarea name="'+rte+'" id="'+rte+'" style="width: ' + width + 'px; height: ' + height + 'px;" readonly="readonly">' + html + '</textarea>');
		}
		document.writeln('</div>');

	}

}

RTEF.prototype.insertButtonRow = function(elmsA,rte,id,topRow,leftF) {
    this.insertElement(this.IF_BTNROW,rte,id,topRow,leftF);
    for (var i=0; i<elmsA.length; i++) {
        this.insertElement(elmsA[i],rte);
    }
    this.insertElement(this.IF_BTNROW_END,rte);
}

RTEF.prototype.insertElement = function(elmName,rte) {
    switch (elmName) {

    case this.IF_BTNROW:
        var topRow = (arguments.length>=4 ? (arguments[3]==this.IF_TOPROW ? true : false) : false);
        var leftF = (arguments.length>=4 ? (arguments[3]==this.IF_BTNROW_LEFTF || arguments[4]==this.IF_BTNROW_LEFTF ? true : false) : false);
        document.writeln('<div class="rteRow'+(topRow ? ' rteTopButtonRow' : '')+(leftF ? ' leftF' : ' clearF')+'" id="'+arguments[2]+'">');break;
    case this.IF_BTNROW_END:
        document.writeln('</div>');break;
    case this.IF_IMAGE:
        var name = arguments[2]; var image = arguments[3]; var command = arguments[4]; var id = arguments[5];
        document.writeln('<img'+(id!=null ? ' id="'+id+'"' : '')+' class="rteImg" onmousemove="return false;" src="'+this.imagesPath+image+'" alt="'+name+'" title="'+name+'" onmousedown="'+command+';this.className=\'rteImgDn\';return false;" onmouseover="this.className=\'rteImgUp\'" onmouseout="this.className=\'rteImg\'" onmouseup="this.className=\'rteImgUp\'" />');break;

    case this.IF_BAR:
        document.writeln('<img class="rteBar" src="'+this.imagesPath+'bar.gif" alt="" />');break;
    case this.IF_SEPARATOR:
        document.writeln('<img class="rteSep" src="'+this.imagesPath+'blackdot.gif" alt="" />');break;

    case this.IF_FONTFORMAT:
        if (!isSafari && !isKonqueror) {
            document.writeln('<select class="rteFFormat" id="formatblock_'+rte+'" onchange="'+RTEFObjectName+'.selectFont(\''+rte+'\', this.id)">');
            document.writeln(this.lblFormat);
            document.writeln('</select>');
    	}
    	break;
    case this.IF_FONTFAMILY:
        document.writeln('<select class="rteFFont" id="fontname_'+rte+'" onchange="'+RTEFObjectName+'.selectFont(\''+rte+'\', this.id)">');
    	document.writeln(this.lblFont);
    	document.writeln('</select>');
    	break;
    case this.IF_FONTSIZE:
        if (!isSafari && !isKonqueror) {
            document.writeln('<select class="rteFFontSize" unselectable="on" id="fontsize_'+rte+'" onchange="'+RTEFObjectName+'.selectFont(\''+rte+'\', this.id);return false">');
    	   document.writeln(this.lblSize);
            document.writeln('</select>');
        }
        break;
    case this.IF_FONTAPPLY:
        if (isSafari || isKonqueror)
            this.insertElement(this.IF_IMAGE,rte,this.lblFontApply,"apply.png","'+RTEFObjectName+'.selectFont('"+rte+"', 'fontname_"+rte+"')");
        break;

    case this.IF_CUT:
        if (isIE || isSafari || isKonqueror) this.insertElement(this.IF_IMAGE,rte,this.lblCut,"cut.gif",RTEFObjectName+".rteCommand('"+rte+"','cut')");
        break;
    case this.IF_COPY:
        if (isIE || isSafari || isKonqueror) this.insertElement(this.IF_IMAGE,rte,this.lblCopy,"copy.gif",RTEFObjectName+".rteCommand('"+rte+"','copy')");
        break;
    case this.IF_PASTE:
        if (isIE) this.insertElement(this.IF_IMAGE,rte,this.lblPaste,"paste.gif",RTEFObjectName+".rteCommand('"+rte+"','paste')");
        break;
    case this.IF_PASTETEXT:
        if (!isOpera) this.insertElement(this.IF_IMAGE,rte,this.lblPasteText,"pastetext.gif",RTEFObjectName+".dlgLaunch('"+rte+"','text')");
        break;
    case this.IF_PASTEWORD:
        if (!isOpera) this.insertElement(this.IF_IMAGE,rte,this.lblPasteWord,"pasteword.gif",RTEFObjectName+".dlgLaunch('"+rte+"','word')");
        break;
    case this.IF_UNDO:
        this.insertElement(this.IF_IMAGE,rte,this.lblUndo,"undo.gif",RTEFObjectName+".rteCommand('"+rte+"','undo')");break;
    case this.IF_REDO:
        this.insertElement(this.IF_IMAGE,rte,this.lblRedo,"redo.gif",RTEFObjectName+".rteCommand('"+rte+"','redo')");break;
    case this.IF_JUSTLEFT:
        this.insertElement(this.IF_IMAGE,rte,this.lblAlgnLeft,"left_just.gif",RTEFObjectName+".rteCommand('"+rte+"','justifyleft')");break;
    case this.IF_JUSTCENTER:
        this.insertElement(this.IF_IMAGE,rte,this.lblAlgnCenter,"centre.gif",RTEFObjectName+".rteCommand('"+rte+"','justifycenter')");break;
    case this.IF_JUSTFULL:
        this.insertElement(this.IF_IMAGE,rte,this.lblJustifyFull,"justifyfull.gif",RTEFObjectName+".rteCommand('"+rte+"','justifyfull')");break;
    case this.IF_JUSTRIGHT:
        this.insertElement(this.IF_IMAGE,rte,this.lblAlgnRight,"right_just.gif",RTEFObjectName+".rteCommand('"+rte+"','justifyright')");break;
    case this.IF_BOLD:
        this.insertElement(this.IF_IMAGE,rte,this.lblBold,"bold.gif",RTEFObjectName+".rteCommand('"+rte+"','bold')");break;
    case this.IF_ITALIC:
        this.insertElement(this.IF_IMAGE,rte,this.lblItalic,"italic.gif",RTEFObjectName+".rteCommand('"+rte+"','italic')");break;
    case this.IF_UNDERLINE:
        this.insertElement(this.IF_IMAGE,rte,this.lblUnderline,"underline.gif",RTEFObjectName+".rteCommand('"+rte+"','underline')");break;
    case this.IF_STRIKETHROUGH:
        if (!isSafari && !isKonqueror) {
            this.insertElement(this.IF_IMAGE,rte,this.lblStrikeThrough,"strikethrough.gif",RTEFObjectName+".rteCommand('"+rte+"','strikethrough')");
        }else{
            this.insertElement(this.IF_IMAGE,rte,this.lblStrikeThrough,"strikethrough.gif",RTEFObjectName+".insertHTML('<strike>'+"+RTEFObjectName+".getText('"+rte+"')+'</strike>')");
        }
        break;
    case this.IF_HIDDEN:
        this.insertElement(this.IF_IMAGE,rte,this.lblHidden,"hiddentext.gif",RTEFObjectName+".insertHTML('<span class=\\'viewTspoiler\\'>'+"+RTEFObjectName+".getText('"+rte+"')+'</span>&nbsp;')");break;
    case this.IF_SUPERSCRIPT:
        this.insertElement(this.IF_IMAGE,rte,this.lblSuperscript,"superscript.gif",RTEFObjectName+".rteCommand('"+rte+"','superscript')");break;
    case this.IF_SUBSCRIPT:
        this.insertElement(this.IF_IMAGE,rte,this.lblSubscript,"subscript.gif",RTEFObjectName+".rteCommand('"+rte+"','subscript')");break;
    case this.IF_SPECIALCHAR:
        if (!isOpera) this.insertElement(this.IF_IMAGE,rte,this.lblInsertChar,"special_char.gif",RTEFObjectName+".dlgLaunch('"+rte+"','char')");
        break;
    case this.IF_JAPANESE:
        if (!isOpera) this.insertElement(this.IF_IMAGE,rte,this.lblInsertJapanese,"japanese.gif",RTEFObjectName+".dlgLaunch('"+rte+"','japanese')");
        break;
    case this.IF_HYPERLINK:
        this.insertElement(this.IF_IMAGE,rte,this.lblInsertLink,"hyperlink.gif",RTEFObjectName+".dlgLaunch('"+rte+"','link')");break;
    case this.IF_UNLINK:
        if (!isSafari && !isKonqueror) this.insertElement(this.IF_IMAGE,rte,this.lblUnLink,"unlink.gif",RTEFObjectName+".rteCommand('"+rte+"','Unlink')");
        break;
    case this.IF_INSERTIMAGE:
        this.insertElement(this.IF_IMAGE,rte,this.lblAddImage,"image.gif",RTEFObjectName+".dlgLaunch('"+rte+"','image');");break;
    case this.IF_TABLE:
        if (!isOpera) this.insertElement(this.IF_IMAGE,rte,this.lblInsertTable,"insert_table.gif",RTEFObjectName+".dlgLaunch('"+rte+"','table')");
        break;
    case this.IF_REPLACE:
        if (!isIE5) this.insertElement(this.IF_IMAGE,rte,this.lblSearch,"replace.gif",RTEFObjectName+".dlgLaunch('"+rte+"','replace')");
    break;
    case this.IF_WORDCOUNT:
        this.insertElement(this.IF_IMAGE,rte,this.lblWordCount,"word_count.gif",RTEFObjectName+".countWords('"+rte+"')");break;
    case this.IF_SELECTALL:
        if (!isSafari && !isKonqueror) {
            this.insertElement(this.IF_SEPARATOR,rte);
            this.insertElement(this.IF_IMAGE,rte,this.lblSelectAll,"selectall.gif",RTEFObjectName+".toggleSelection('"+rte+"')");
            this.insertElement(this.IF_SEPARATOR,rte);
        }
        break;
    case this.IF_PRINT:
        this.insertElement(this.IF_IMAGE,rte,this.lblPrint,"print.gif",RTEFObjectName+".rtePrint('"+rte+"')");break;
    case this.IF_LISTORDERED:
        if (!isSafari && !isKonqueror) this.insertElement(this.IF_IMAGE,rte,this.lblOL,"numbered_list.gif",RTEFObjectName+".rteCommand('"+rte+"','insertorderedlist')");
        break;
    case this.IF_LISTUNORDERED:
        if (!isSafari && !isKonqueror) this.insertElement(this.IF_IMAGE,rte,this.lblUL,"list.gif",RTEFObjectName+".rteCommand('"+rte+"','insertunorderedlist')");
        break;
    case this.IF_OUTDENT:
        if (!isSafari && !isKonqueror) this.insertElement(this.IF_IMAGE,rte,this.lblOutdent,"outdent.gif",RTEFObjectName+".rteCommand('"+rte+"','outdent')");
        break;
    case this.IF_INDENT:
        if (!isSafari && !isKonqueror) this.insertElement(this.IF_IMAGE,rte,this.lblIndent,"indent.gif",RTEFObjectName+".rteCommand('"+rte+"','indent')");
        break;
    case this.IF_TEXTCOLOR:
        this.insertElement(this.IF_IMAGE,rte,this.lblTextColor,"textcolor.gif",RTEFObjectName+".dlgColorPalette('"+rte+"','forecolor')","forecolor_"+rte);break;
    case this.IF_BGCOLOR:
        this.insertElement(this.IF_IMAGE,rte,this.lblBgColor,"bgcolor.gif",RTEFObjectName+".dlgColorPalette('"+rte+"','hilitecolor')","hilitecolor_"+rte);break;
    case this.IF_HR:
        if (isSafari) {
            this.insertElement(this.IF_IMAGE,rte,this.lblHR,"hr.gif",RTEFObjectName+".insertHTML('<hr /><br />')");
        }else{
            this.insertElement(this.IF_IMAGE,rte,this.lblHR,"hr.gif",RTEFObjectName+".rteCommand('"+rte+"','inserthorizontalrule')");
        }
        break;
    case this.IF_QUOTE:
        this.insertElement(this.IF_IMAGE,rte,this.lblQuote,"quote.gif","initQuoteInsert()");break;
    case this.IF_UNFORMAT:
        if (isSafari || isKonqueror) {
            this.insertElement(this.IF_IMAGE,rte,this.lblUnformat,"unformat.gif",RTEFObjectName+".insertHTML("+RTEFObjectName+".getText('"+rte+"'))");
        }else{
            this.insertElement(this.IF_IMAGE,rte,this.lblUnformat,"unformat.gif",RTEFObjectName+".rteCommand('"+rte+"','removeformat')");
        }
        break;
    case this.IF_SPELLCHECK:
        if (isIE) this.insertElement(this.IF_IMAGE,rte,this.lblSpellCheck,"spellcheck.gif",RTEFObjectName+".checkspell()");
        break;
    default:
        break;

    }
}

RTEF.prototype.enableDesignMode = function(rte, css, readOnly) {

    if (this.enableDesignModeTryCount>10) return;

	var frameHtml = '<html dir="' + this.lang_direction + '" lang="' + this.lang + '" id="' + rte + '">'+"\n<head>\n";
	frameHtml += '<meta http-equiv="Content-Type" content="text/html; charset=' + this.encoding + '" />'+"\n";
	frameHtml += '<meta http-equiv="Content-Language" content="' + this.lang + '" />'+"\n";

    if (this.userThemeID.length>0) frameHtml += '<link rel="stylesheet" href="/inc_css/themes/theme.css.php?id='+this.userThemeID+'" type="text/css" />'+"\n";
    frameHtml += '<link media="all" type="text/css" href="/inc_css/forumpost.css" rel="stylesheet" />'+"\n";

	if (css.length > 0) {
		frameHtml += '<link media="all" type="text/css" href="' + css + '" rel="stylesheet" />'+"\n";
	}else{
		frameHtml += '<style type="text/css">\n<!--\n@charset "utf-8"; body {font-family:Georgia,Arial,Helvetica;font-size:12px;background:#fff;margin:0px;padding:0px;}'+"\n-->\n</style>\n";
	}
	frameHtml += '</head><body class="rte theme_c_link1"'+(isOpera && this.html.length>0 ? ' contenteditable="true"' : '')+'>'+"\n"+this.html+"\n</body></html>";

    if (!isSafari && !isKonqueror) var oRTE = this.returnRTE(rte).document;
	if (document.all) {
		if (isSafari || isKonqueror) var oRTE = frames[rte].document;
		oRTE.open("text/html","replace");
		oRTE.write(frameHtml);
		oRTE.close();
		if (!readOnly) {
			oRTE.designMode = "On";
		}
	} else {
		try {
			if (!readOnly && !isKonqueror && !isSafari) {
				document.getElementById(rte).onload = function(e) {
                    document.getElementById(eval(RTEFObjectName+'.currentRTE')).onload = null;
                    document.getElementById(eval(RTEFObjectName+'.currentRTE')).contentDocument.designMode = "on";
                }
			} else if (!readOnly) {
				//Safari doen't like the abouve command so we use this instad - Anders Jenbo.
				if (!readOnly) document.getElementById(rte).contentDocument.designMode = "on";
			}
			try {
				if (isSafari || isKonqueror) var oRTE = document.getElementById(rte).contentWindow.document;
				oRTE.open("text/html","replace");
				oRTE.write(frameHtml);
				oRTE.close();
				if (isGecko && !readOnly) {
					//attach a keyboard handler for gecko browsers to make keyboard shortcuts work
					oRTE.addEventListener("keypress", function(e) { eval(RTEFObjectName).geckoKeyPress(e) }, true);
					oRTE.addEventListener("focus", function () { eval(RTEFObjectName).dlgCleanUp(); }, false);
				}
			} catch(e) {
				alert(this.lblErrorPreload);
			}
		} catch(e) {
			// gecko may take some time to enable design mode.
			// Keep looping until able to set.
			if (isGecko) {
				setTimeout(RTEFObjectName+".enableDesignMode('"+rte+"', '"+css+"', "+readOnly+");", 200);
			}else {
				return false;
			}
		}
	}
	setTimeout(RTEFObjectName+'.showGuidelines("'+rte+'")',300);
}

RTEF.prototype.returnRTE = function(rte) {
	var rtn;
	if (document.all || OperaVersion>=9.5) {
		rtn = frames[rte];
	}else{
		rtn = document.getElementById(rte).contentWindow;
	}
	return rtn;
}

RTEF.prototype.updateRTE = function(rte) {
    if (this.isRichText) {
        this.dlgCleanUp();			// Closes Pop-ups
        this.stripGuidelines(rte);	// Removes Table Guidelines
    }
    this.parseRTE(rte);
}

RTEF.prototype.updateRTEs = function() {
	var vRTEs = this.allRTEs.split(";");
	for(var i=0; i<vRTEs.length; i++) {
		this.updateRTE(vRTEs[i]);
	}
}

RTEF.prototype.parseRTE = function(rte) {

    //Sync rte.value with iframe
    if (!this.isRichText) { // we are in the source code editing mode
        this.autoBRoff(rte); // turns off automatic linebreaking
        return false;
    }

	var oRTE = this.returnRTE(rte);
	if(isSafari) oRTE.focus();

	if (this.isRichText) {
		//if viewing source, switch back to design view
		//if (document.getElementById("_xtSrc"+rte).innerHTML == this.lblModeRichText) {
		if (this.viewingSRC) {
			if (document.getElementById("Buttons1_"+rte)) {
				this.toggleHTMLSrc(rte, true);
			}else{
				this.toggleHTMLSrc(rte, false);
			}
			this.stripGuidelines(rte);
		}
		this.setHiddenVal(rte);
	}

}

RTEF.prototype.setHiddenVal = function(rte) {
	//set hidden form field value for current rte
	var oHdnField = document.getElementById('hdn'+rte);
	//convert html output to xhtml (thanks Timothy Bell and Vyacheslav Smolin!)
	if (oHdnField.value==null) {
		oHdnField.value = "";
	}
	var sRTE = this.returnRTE(rte).document.body;
	if (this.generateXHTML) {
		try {
			oHdnField.value = this.getXHTML(sRTE.innerHTML);
		}
		catch(e) {
			oHdnField.value = sRTE.innerHTML;
		}
	}else{
		oHdnField.value = sRTE.innerHTML;
	}
	// fix to replace special characters added here:
	oHdnField.value = this.replaceSpecialChars(oHdnField.value);

	//if there is no content (other than formatting) set value to nothing
	if (this.stripHTML(oHdnField.value.replace("&nbsp;", " ")) == "" &&
	oHdnField.value.toLowerCase().search("<hr") == -1 &&
	oHdnField.value.toLowerCase().search("<img") == -1) {
        oHdnField.value = "";
	}
}

RTEF.prototype.rteCommand = function(rte, command, option) {
	this.dlgCleanUp();
  //function to perform command
	var oRTE = this.returnRTE(rte);
	try {
		oRTE.focus();
		oRTE.document.execCommand(command, false, option);
		oRTE.focus();
	} catch(e) {
//		alert(e);
//		setTimeout("rteCommand('" + rte + "', '" + command + "', '" + option + "');", 10);
	}
}

RTEF.prototype.toggleHTMLSrc = function(rte, buttons) {
	this.dlgCleanUp();
	// contributed by Bob Hutzel (thanks Bob!)
	var cRTE = document.getElementById(rte);
	var hRTE = document.getElementById('hdn'+rte);
	var sRTE = document.getElementById("size"+rte);
	//var tRTE = document.getElementById("_xtSrc"+rte);
	var tRTE = this.viewingSRC;
	var iRTE = document.getElementById("imgSrc"+rte);
	var oRTE = this.returnRTE(rte).document;
	var htmlSrc;
	if (sRTE) {
		obj_height = parseInt(sRTE.value);
	}else{
		this.findSize(rte);
	}
	//if (tRTE.innerHTML == this.lblModeHTML) {
	if (!this.viewingSRC) {
		// we are checking the box
		//tRTE.innerHTML = this.lblModeRichText;
		this.viewingSRC = true;
		this.stripGuidelines(rte);
		if (buttons) {
			this.showHideElement("Buttons1_" + rte, "hide", true);
			if (document.getElementById("Buttons2_" + rte))
                this.showHideElement("Buttons2_" + rte, "hide", true);
			if (document.getElementById("Buttons3_"+rte)) {
				this.showHideElement("Buttons3_" + rte, "hide", true);
				if (this.blogmode) cRTE.style.height = obj_height+84;
			}else{
				if (this.blogmode) cRTE.style.height = obj_height+56;
			}
		}
		this.setHiddenVal(rte); // copy current content to hidden field
		if (document.all) {
			oRTE.body.innerText = hRTE.value;
		}else{
			htmlSrc = oRTE.createTextNode(hRTE.value);
			oRTE.body.innerHTML = "";
			oRTE.body.appendChild(htmlSrc);
		}
		iRTE.setAttribute("src",this.imagesPath+'design.gif');
	}else{
		// we are unchecking the box
		obj_height = parseInt(cRTE.style.height);
		//tRTE.innerHTML = this.lblModeHTML;
		this.viewingSRC = false;
		if (buttons) {
			this.showHideElement("Buttons1_" + rte, "show", true);
			if (document.getElementById("Buttons2_" + rte))
                this.showHideElement("Buttons2_" + rte, "show", true);
			if (document.getElementById("Buttons3_"+rte)) {
				this.showHideElement("Buttons3_" + rte, "show", true);
				if (this.blogmode) cRTE.style.height = obj_height-84;
			}else{
				if (this.blogmode) cRTE.style.height = obj_height-56;
			}
		}
		if (document.all) {
			// fix for IE
			var output = escape(oRTE.body.innerText);
			output = output.replace("%3CP%3E%0D%0A%3CHR%3E", "%3CHR%3E");
			output = output.replace("%3CHR%3E%0D%0A%3C/P%3E", "%3CHR%3E");
			oRTE.body.innerHTML = unescape(output);
			// Disabled due to flaw in the regular expressions, this fix
			// does not work with the revamped's enhanced insert link dialog window.

			// Prevent links from changing to absolute paths
			if (!this.keep_absolute) {
				var tagfix = unescape(output).match(/<a[^>]*href=(['"])([^\1>]*)\1[^>]*>/ig);
				var coll = oRTE.body.all.tags('A');
				for(i=0; i<coll.length; i++) {
					// the 2 alerts below show when we hinder the links from becoming absolute
					// alert(tagfix[i]);
					coll[i].href = tagfix[i].replace(/.*href=(['"])([^\1]*)\1.*/i,"$2");
					// alert(RegExp.$1 + " " + RegExp.$2 + " " + RegExp.$3);
				}
				var imgfix = unescape(output).match(/<img[^>]*src=['"][^'"]*['"][^>]*>/ig);
				var coll2 = oRTE.body.all.tags('IMG');
				for(i=0; i<coll2.length; i++) {
					coll2[i].src = imgfix[i].replace(/.*src=['"]([^'"]*)['"].*/i,"$1");
				}
			}
	  	// end path fix
		}else{
			htmlSrc = oRTE.body.ownerDocument.createRange();
			htmlSrc.selectNodeContents(oRTE.body);
			oRTE.body.innerHTML = htmlSrc.toString();
		}
		oRTE.body.innerHTML = this.replaceSpecialChars(oRTE.body.innerHTML);
		this.showGuidelines(rte);
		// (IE Only)This prevents an undo operation from displaying a pervious HTML mode
		// This resets the undo/redo buffer.
		if (document.all) {
			this.parseRTE(rte);
		}
		iRTE.setAttribute("src",this.imagesPath+'code.gif');
	}
}

RTEF.prototype.toggleSelection = function(rte) {
	var rng = this.setRange(rte);
	var oRTE = this.returnRTE(rte).document;
	var length1;
	var length2;
	if (document.all) {
		length1 = rng.text.length;
		var output = escape(oRTE.body.innerText);
		output = output.replace("%3CP%3E%0D%0A%3CHR%3E", "%3CHR%3E");
		output = output.replace("%3CHR%3E%0D%0A%3C/P%3E", "%3CHR%3E");
		length2 = unescape(output).length;
	}else{
		length1 = rng.toString().length;
		var htmlSrc = oRTE.body.ownerDocument.createRange();
		htmlSrc.selectNodeContents(oRTE.body);
		length2 = htmlSrc.toString().length;
	}
	if (length1 < length2) {
		this.rteCommand(rte,'selectall','');
	}else{
		if (!document.all) {
			oRTE.designMode = "off";
			oRTE.designMode = "on";
		}else{
			this.rteCommand(rte,'unselect','');
		}
	}
}

RTEF.prototype.dlgColorPalette = function(rte, command) {
	// function to display or hide color palettes
	if (!isSafari && !isKonqueror) this.setRange(rte);
	// get dialog position
	var oDialog = document.getElementById('cp' + rte);
	var buttonElement = document.getElementById(command+"_"+rte);
	var iLeftPos = buttonElement.offsetLeft+5;
	var iTopPos = buttonElement.offsetTop+53;
	if (!document.getElementById('Buttons2_'+rte)) {
		iTopPos = iTopPos-28;
	}
	oDialog.style.left = iLeftPos + "px";
	oDialog.style.top = iTopPos + "px";
	if ((command == parent.command) && (rte == this.currentRTE)) {
		// if current command dialog is currently open, close it
		if (oDialog.style.visibility == "hidden") {
			this.showHideElement(oDialog, 'show', false);
		}else{
			this.showHideElement(oDialog, 'hide', false);
		}
	}else{
		// if opening a new dialog, close all others
		var vRTEs = this.allRTEs.split(";");
		for (var i = 0; i<vRTEs.length; i++) {
			this.showHideElement('cp' + vRTEs[i], 'hide', false);
		}
		this.showHideElement(oDialog, 'show', false);
	}
	// save current values
	this.currentRTE = rte;
	parent.command = command;
}

RTEF.prototype.dlgLaunch = function(rte, command) {
	var selectedText = '';
	// save current values
	parent.command = command;
	this.currentRTE = rte;
	switch (command) {
		case "char":
			this.InsertChar = this.popUpWin(this.includesPath+'insert_char.php', 'InsertChar', 50, 50, 'status=yes,');
		break;
		case "japanese":
			this.InsertChar = this.popUpWin(this.includesPath+'insert_japanese.php', 'InsertJapanese', 50, 50, 'status=yes,');
		break;
		case "table":
			this.InsertTable = this.popUpWin(this.includesPath + 'insert_table.htm', 'InsertTable', 50, 50, 'status=yes,');
		break;
		case "image":
			if (!isSafari && !isKonqueror) this.setRange(rte);
			this.parseRTE(rte);
			// sending rte and isOpera starte for Opera
			this.InsertImg = this.popUpWin(this.includesPath + 'insert_img.php?rte='+ rte + '&isOpera=' + isOpera,'AddImage', 50, 50, 'status=yes,');
		break;
		case "link":
			if (!isOpera) selectedText = this.getText(rte);
			// sending rte and isOpera starte for Opera
			this.InsertLink = this.popUpWin(this.includesPath + 'insert_link.htm?rte='+ rte + '&isOpera=' + isOpera, 'InsertLink', 50, 50, 'status=yes,');
			if (!isOpera) this.setFormText("0", selectedText);
		break;
		case "replace":
			if (!isOpera) selectedText = this.getText(rte);
			this.dlgReplace = this.popUpWin(this.includesPath + 'replace.htm', 'dlgReplace', 50, 50, 'status=yes,');
			if (!isOpera) this.setFormText("1", selectedText);
		break;
		case "text":
			this.dlgPasteText = this.popUpWin(this.includesPath + 'paste_text.htm', 'dlgPasteText', 50, 50, 'status=yes,');
		break;
		case "word":
			this.dlgPasteWord = this.popUpWin(this.includesPath + 'paste_word.htm', 'dlgPasteWord', 50, 50, 'status=yes,');
		break;
	}
}

RTEF.prototype.getText = function(rte) {
	// get currently highlighted text and set link text value
    if (isSafari) {
		var oRTE = this.returnRTE(rte);
		var rtn = oRTE.getSelection();
		//This makes it a text string, i dont know any other ways and it seams quick
		rtn = "" + rtn;
		return rtn;
	}else{
		var rng = this.setRange(rte);
		this.rngEndOffset = rng.endOffset;
		var rtn = '';
		if (isIE) {
			if (rng.htmlText!=undefined) rtn = this.stripHTML(rng.htmlText);
		}else{
			rtn = this.stripHTML(rng.toString());
		}
		this.parseRTE(rte);
		/*if (document.all) {
			rtn = rtn.replace("'","\\\\\\'");
		}else{
			rtn = rtn.replace("'","\\'");
		}*/
		return rtn;
	}
}

RTEF.prototype.setFormText = function(popup, content) {
	// set link text value in dialog windows
	if (content != "undefined") {
		try {
			switch(popup) {
				case "0": this.InsertLink.document.getElementById("linkText").value = content; break;
				case "1": this.dlgReplace.document.getElementById("searchText").value = content; break;
			}
		} catch(e) {
			  // may take some time to create dialog window.
			  // Keep looping until able to set.
			setTimeout(RTEFObjectName+".setFormText('"+popup+"','" + content + "');", 10);
		}
	}
}

RTEF.prototype.dlgCleanUp = function() {
	var vRTEs = this.allRTEs.split(";");
	for (var i = 0; i < vRTEs.length; i++) {
		this.showHideElement('cp' + vRTEs[i], 'hide', false);
	}
	if (!isSafari && !isKonqueror && !isOpera && !isIE5) {
		/*if(this.InsertChar != null) {
			this.InsertChar.close();
			this.InsertChar = null;
		}*/
		if (this.InsertTable != null) {
			this.InsertTable.close();
			this.InsertTable = null;
		}
		if (this.InsertLink != null) {
			this.InsertLink.close();
			this.InsertLink = null;
		}
		if (this.InsertImg != null) {
			this.InsertImg.close();
			this.InsertImg = null;
		}
		if (this.dlgReplace != null) {
			this.dlgReplace.close();
			this.dlgReplace = null;
		}
		if (this.dlgPasteText != null) {
			this.dlgPasteText.close();
			this.dlgPasteText = null;
		}
		if (this.dlgPasteWord != null) {
			this.dlgPasteWord.close();
			this.dlgPasteWord = null;
		}
	}
}

RTEF.prototype.popUpWin = function(url, win, width, height, options) {
	this.dlgCleanUp();
	var leftPos = (screen.availWidth - width) / 2;
	var topPos = (screen.availHeight - height) / 2;
	options += 'width=' + width + ',height=' + height + ',left=' + leftPos + ',top=' + topPos;
	return window.open(url, win, options);
}

RTEF.prototype.setColor = function(color) {
	// function to set color
	var rte = this.currentRTE;
	var parentCommand = parent.command;

	if (document.all || isSafari || isKonqueror) {
		if (parentCommand == "hilitecolor") {
			parentCommand = "backcolor";
		}
		// retrieve selected range
		if (!isSafari && !isKonqueror) this.rng.select();
	}

	this.rteCommand(rte, parentCommand, color);
	this.showHideElement('cp'+rte, "hide", false);
}

RTEF.prototype.addImage = function(rte) {
	this.dlgCleanUp();
	// function to add image
	var imagePath = prompt('Enter Image URL:', 'http://');
	if ((imagePath != null) && (imagePath != "")) {
		this.rteCommand(rte, 'InsertImage', imagePath);
	}
}

RTEF.prototype.rtePrint = function(rte) {
	this.dlgCleanUp();
	if (isIE) {
		document.getElementById(rte).contentWindow.document.execCommand('Print');
	} else {
		document.getElementById(rte).contentWindow.print();
	}
}

RTEF.prototype.selectFont = function(rte, selectname) {
	// function to handle font changes
	var idx = document.getElementById(selectname).selectedIndex;
	// First one is always a label
	if (idx != 0) {
		var selected = document.getElementById(selectname).options[idx].value;
		var cmd = selectname.replace('_'+rte, '');
		this.rteCommand(rte, cmd, selected);
		if(!isSafari && !isKonqueror) document.getElementById(selectname).selectedIndex = 0;
	}
}

RTEF.prototype.selectFontByName = function(rte, fontname) {
	// function to handle font changes
	this.rteCommand(rte, 'fontname', fontname);
}

RTEF.prototype.insertHTML = function(html) {
  if (!isSafari && !isKonqueror) {
		//function to add HTML -- thanks dannyuk1982
		var rte = this.currentRTE;
		var oRTE = this.returnRTE(rte);
		if (isIE) oRTE.focus();
		if (document.all && !isOpera) { // IE4
			var oRng = oRTE.document.selection.createRange();
			oRng.pasteHTML(html);
			oRng.collapse(false);
			oRng.select();
		} else {
		  //$('body', oRTE.document).html($('body', oRTE.document).html()+html);
			oRTE.document.execCommand('insertHTML', false, html);
		}
  } else {
		var searchFor = 'SafariHTMLReplaceString';
		var rte = this.currentRTE;
		this.rteCommand(rte,'InsertText', searchFor);
		var oRTE = this.returnRTE(rte);
		var tmpContent = oRTE.document.body.innerHTML.replace("'", "\'").replace('"', '\"');
		var strRegex = "/(?!<[^>]*)(" + searchFor + ")(?![^<]*>)/g";
		var cmpRegex = eval(strRegex);
		var runCount = 0;
		var tmpNext = tmpContent;
		var intFound = tmpNext.search(cmpRegex);
		while (intFound > -1) {
			runCount = runCount+1;
			tmpNext = tmpNext.substr(intFound + searchFor.length);
			intFound = tmpNext.search(cmpRegex);
		}
		if (runCount > 0) {
			tmpContent = tmpContent.replace(cmpRegex,html);
			oRTE.document.body.innerHTML = tmpContent.replace("\'", "'").replace('\"', '"');
			this.updateRTEs();
		}else{
            oRTE.document.body.innerHTML += html;
            this.updateRTEs();
		}
	}
}

RTEF.prototype.replaceHTML = function(tmpContent, searchFor, replaceWith) {
	var runCount = 0;
	var intBefore = 0;
	var intAfter = 0;
	var tmpOutput = "";
	while (tmpContent.toUpperCase().indexOf(searchFor.toUpperCase()) > -1) {
		runCount = runCount+1;
		// Get all content before the match
		intBefore = tmpContent.toUpperCase().indexOf(searchFor.toUpperCase());
		tmpBefore = tmpContent.substring(0, intBefore);
		tmpOutput = tmpOutput + tmpBefore;
		// Get the string to replace
		tmpOutput = tmpOutput + replaceWith;
		// Get the rest of the content after the match until
		// the next match or the end of the content
		intAfter = tmpContent.length - searchFor.length + 1;
		tmpContent = tmpContent.substring(intBefore + searchFor.length);
	}
	return runCount+"|^|"+tmpOutput+tmpContent;
}

RTEF.prototype.replaceSpecialChars = function(html) {
	var specials = new Array("&cent;","&euro;","&pound;","&curren;","&yen;","&copy;","&reg;","&trade;","&divide;","&times;","&plusmn;","&frac14;","&frac12;","&frac34;","&deg;","&sup1;","&sup2;","&sup3;","&micro;","&laquo;","&raquo;","&lsquo;","&rsquo;","&lsaquo;","&rsaquo;","&sbquo;","&bdquo;","&ldquo;","&rdquo;","&iexcl;","&brvbar;","&sect;","&not;","&macr;","&para;","&middot;","&cedil;","&iquest;","&fnof;","&mdash;","&ndash;","&bull;","&hellip;","&permil;","&ordf;","&ordm;","&szlig;","&dagger;","&Dagger;","&eth;","&ETH;","&oslash;","&Oslash;","&thorn;","&THORN;","&oelig;","&OElig;","&scaron;","&Scaron;","&acute;","&circ;","&tilde;","&uml;","&agrave;","&aacute;","&acirc;","&atilde;","&auml;","&aring;","&aelig;","&Agrave;","&Aacute;","&Acirc;","&Atilde;","&Auml;","&Aring;","&AElig;","&ccedil;","&Ccedil;","&egrave;","&eacute;","&ecirc;","&euml;","&Egrave;","&Eacute;","&Ecirc;","&Euml;","&igrave;","&iacute;","&icirc;","&iuml;","&Igrave;","&Iacute;","&Icirc;","&Iuml;","&ntilde;","&Ntilde;","&ograve;","&oacute;","&ocirc;","&otilde;","&ouml;","&Ograve;","&Oacute;","&Ocirc;","&Otilde;","&Ouml;","&ugrave;","&uacute;","&ucirc;","&uuml;","&Ugrave;","&Uacute;","&Ucirc;","&Uuml;","&yacute;","&yuml;","&Yacute;","&Yuml;");
	var unicodes = new Array("\u00a2","\u20ac","\u00a3","\u00a4","\u00a5","\u00a9","\u00ae","\u2122","\u00f7","\u00d7","\u00b1","\u00bc","\u00bd","\u00be","\u00b0","\u00b9","\u00b2","\u00b3","\u00b5","\u00ab","\u00bb","\u2018","\u2019","\u2039","\u203a","\u201a","\u201e","\u201c","\u201d","\u00a1","\u00a6","\u00a7","\u00ac","\u00af","\u00b6","\u00b7","\u00b8","\u00bf","\u0192","\u2014","\u2013","\u2022","\u2026","\u2030","\u00aa","\u00ba","\u00df","\u2020","\u2021","\u00f0","\u00d0","\u00f8","\u00d8","\u00fe","\u00de","\u0153","\u0152","\u0161","\u0160","\u00b4","\u02c6","\u02dc","\u00a8","\u00e0","\u00e1","\u00e2","\u00e3","\u00e4","\u00e5","\u00e6","\u00c0","\u00c1","\u00c2","\u00c3","\u00c4","\u00c5","\u00c6","\u00e7","\u00c7","\u00e8","\u00e9","\u00ea","\u00eb","\u00c8","\u00c9","\u00ca","\u00cb","\u00ec","\u00ed","\u00ee","\u00ef","\u00cc","\u00cd","\u00ce","\u00cf","\u00f1","\u00d1","\u00f2","\u00f3","\u00f4","\u00f5","\u00f6","\u00d2","\u00d3","\u00d4","\u00d5","\u00d6","\u00f9","\u00fa","\u00fb","\u00fc","\u00d9","\u00da","\u00db","\u00dc","\u00fd","\u00ff","\u00dd","\u0178");
	for (var i=0; i<specials.length; i++) {
		html = this.replaceIt(html,unicodes[i],specials[i]);
	}
	return html;
}

RTEF.prototype.SearchAndReplace = function(searchFor, replaceWith, matchCase, wholeWord) {
	var cfrmMsg = this.lblSearchConfirm.replace("SF",searchFor).replace("RW",replaceWith);
	var rte = this.currentRTE;
	this.stripGuidelines(rte);
	var oRTE = this.returnRTE(rte);
	var tmpContent = oRTE.document.body.innerHTML.replace("'", "\'").replace('"', '\"');
	var strRegex;
	if (matchCase && wholeWord) {
		strRegex = "/(?!<[^>]*)(\\b(" + searchFor + ")\\b)(?![^<]*>)/g";
	} else if (matchCase) {
		strRegex = "/(?!<[^>]*)(" + searchFor + ")(?![^<]*>)/g";
	} else if (wholeWord) {
		strRegex = "/(?!<[^>]*)(\\b(" + searchFor + ")\\b)(?![^<]*>)/gi";
	} else {
		strRegex = "/(?!<[^>]*)(" + searchFor + ")(?![^<]*>)/gi";
	}
	var cmpRegex = eval(strRegex);
	var runCount = 0;
	var tmpNext = tmpContent;
	var intFound = tmpNext.search(cmpRegex);
	while (intFound > -1) {
		runCount = runCount+1;
		tmpNext = tmpNext.substr(intFound + searchFor.length);
		intFound = tmpNext.search(cmpRegex);
	}
	if (runCount > 0) {
		cfrmMsg = cfrmMsg.replace("[RUNCOUNT]",runCount);
		if (confirm(cfrmMsg)) {
			tmpContent = tmpContent.replace(cmpRegex,replaceWith);
			oRTE.document.body.innerHTML = tmpContent.replace("\'", "'").replace('\"', '"');
		} else {
			alert(this.lblSearchAbort);
		}
		this.showGuidelines(rte);
	} else {
		this.showGuidelines(rte);
		alert("["+searchFor+"] "+this.lblSearchNotFound);
	}
	if (isSafari || isKonqueror) this.updateRTEs();
}

RTEF.prototype.showHideElement = function(element, showHide, rePosition) {
	// function to show or hide elements
	// element variable can be string or object
	if (document.getElementById(element)) {
		element = document.getElementById(element);
	}
	if (showHide == "show") {
		element.style.visibility = "visible";
		if (rePosition) {
			element.style.position = "relative";
			element.style.left = "auto";
			element.style.top = "auto";
		}
	} else if (showHide == "hide") {
		element.style.visibility = "hidden";
		if (rePosition) {
			element.style.position = "absolute";
			element.style.left = "-1000px";
			element.style.top = "-1000px";
		}
	}
}

RTEF.prototype.setRange = function(rte) {
	// function to store range of current selection
	var oRTE = this.returnRTE(rte);
	var selection;
	if (document.all && !isOpera) {
		selection = oRTE.document.selection;
		if (selection != null) {
			this.rng = selection.createRange();
		}
	} else {
		selection = oRTE.getSelection();
		this.rng = selection.getRangeAt(selection.rangeCount - 1).cloneRange();
	}
	return this.rng;
}

RTEF.prototype.stripHTML = function(strU) {
	// strip all html
	var strN = strU.replace(/(<([^>]+)>)/ig,"");
	// replace carriage returns and line feeds
	strN = strN.replace(/\r\n/g," ");
	strN = strN.replace(/\n/g," ");
	strN = strN.replace(/\r/g," ");
	strN = this.trim(strN);
	return strN;
}

RTEF.prototype.trim = function(inputString) {
	if (typeof inputString != "string") {
		return inputString;
	}
	inputString = inputString.replace(/^\s+|\s+$/g, "").replace(/\s{2,}/g, "");
	return inputString;
}

RTEF.prototype.showGuidelines = function(rte) {
	if (rte.length == 0) rte = this.currentRTE;
	var oRTE = this.returnRTE(rte);
	var tables = oRTE.document.getElementsByTagName("table");
	var sty = "dashed 1px "+this.zeroBorder;
	for(var i=0; i<tables.length; i++) {
		if(tables[i].getAttribute("border") == 0) {
			if(document.all) {
				var trs = tables[i].getElementsByTagName("tr");
				for(var j=0; j<trs.length; j++) {
					var tds = trs[j].getElementsByTagName("td");
					for(var k=0; k<tds.length; k++) {
						if(j == 0 && k == 0) {
							tds[k].style.border = sty;
						} else if(j == 0 && k != 0) {
							tds[k].style.borderBottom = sty;
							tds[k].style.borderTop = sty;
							tds[k].style.borderRight = sty;
						} else if(j != 0 && k == 0) {
							tds[k].style.borderBottom = sty;
							tds[k].style.borderLeft = sty;
							tds[k].style.borderRight = sty;
						} else if(j != 0 && k != 0) {
							tds[k].style.borderBottom = sty;
							tds[k].style.borderRight = sty;
						}
					}
				}
			} else {
				tables[i].removeAttribute("border");
				tables[i].setAttribute("style","border: " + sty);
				tables[i].setAttribute("rules", "all");
			}
		}
	}
}

RTEF.prototype.stripGuidelines = function(rte) {
	var oRTE = this.returnRTE(rte);
	var tbls = oRTE.document.getElementsByTagName("table");
	for (var j=0; j<tbls.length; j++) {
		if (tbls[j].getAttribute("border") == 0 || tbls[j].getAttribute("border") == null) {
			if (document.all) {
				var tds = tbls[j].getElementsByTagName("td");
				for(var k=0; k<tds.length; k++) {
					tds[k].removeAttribute("style");
				}
			} else {
				tbls[j].removeAttribute("style");
				tbls[j].removeAttribute("rules");
				tbls[j].setAttribute("border","0");
			}
		}
	}
}

RTEF.prototype.findSize = function(obj) {
	if (obj.length > 0 && document.all) {
		obj = frames[obj];
	}else if (obj.length > 0 && !document.all) {
		obj = document.getElementById(obj).contentWindow;
	}else{
		obj = this;
	}
	if ( typeof( obj.window.innerWidth ) == 'number' ) {
		// Non-IE
		obj_width = obj.window.innerWidth;
		obj_height = obj.window.innerHeight;
	}else if ( obj.document.documentElement && ( obj.document.documentElement.clientWidth || obj.document.documentElement.clientHeight ) ) {
		// IE 6+ in 'standards compliant mode'
		obj_width = document.documentElement.clientWidth;
		obj_height = document.documentElement.clientHeight;
	}else if ( obj.document.body && ( obj.document.body.clientWidth || obj.document.body.clientHeight ) ) {
		// IE 4 compatible
		obj_width = obj.document.body.clientWidth;
		obj_height = obj.document.body.clientHeight;
	}
}

RTEF.prototype.resizeRTE = function() {
	document.body.style.overflow = "hidden";
	var rte = this.currentRTE;
	var oRTE = document.getElementById(rte);
	var oBut1 = document.getElementById('Buttons1_'+rte);
	var oBut2;
	var oVS = document.getElementById('vs'+rte);
	this.findSize("");
	var width = this.obj_width;
	if (width < this.minWidth) {
		document.body.style.overflow = "auto";
		width = this.minWidth;
	}
	var height = this.obj_height - 83;
	//if (document.getElementById("_xtSrc"+rte).innerHTML == this.lblModeRichText) {
	if (this.viewingSRC) {
		height = this.obj_height-28;
		if (!document.getElementById('Buttons2_'+rte) && width < wrapWidth) {
			document.body.style.overflow = "auto";
			width = this.wrapWidth;
		}
		if (document.getElementById('Buttons2_'+rte)) {
			document.getElementById('Buttons2_'+rte).style.width = width;
		}
	} else {
		if (document.getElementById('Buttons2_'+rte)) {
			document.getElementById('Buttons2_'+rte).style.width = width;
		} else {
			height = this.obj_height - 55;
			if (width < this.wrapWidth) {
				document.body.style.overflow = "auto";
				width = this.wrapWidth;
			}
		}
	}
	if (document.body.style.overflow == "auto" && isIE) {
		height = height-18;
	}
	if(document.body.style.overflow == "auto" && !isIE) {
		height = height-24;
	}
	oBut1.style.width = width;
	oVS.style.width = width;
	oRTE.style.width = width-2;
	oRTE.style.height = height;
	if (!document.all) {
		oRTE.contentDocument.designMode = "on";
	}
}

RTEF.prototype.replaceIt = function(string,text,by) {
	// CM 19/10/04 custom replace function
	var strLength = string.length, _xtLength = text.length;
	if ((strLength == 0) || (_xtLength == 0)) {
		return string;
	}
	var i = string.indexOf(text);
	if ((!i) && (text != string.substring(0,_xtLength))) {
		return string;
	}
	if (i == -1) {
		return string;
	}
	var newstr = string.substring(0,i) + by;
	if (i+_xtLength < strLength) {
		newstr += this.replaceIt(string.substring(i+_xtLength,strLength),text,by);
	}
	return newstr;
}

RTEF.prototype.countWords = function(rte) {
	this.parseRTE(rte);
	var words = document.getElementById("hdn"+rte).value;
	var str = this.stripHTML(words);
	var chars = this.trim(words);
	str = str+" a "; // word added to avoid error
	str = this.trim(str.replace(/&nbsp;/gi,' ').replace(/([\n\r\t])/g,' ').replace(/&(.{1,6});/g,'_'));
	var totalChars = str.length;
	var charsLeft = this.maxchar - totalChars;
	var count = str.split(" ").length - 1;
	var alarm = "";
	if (chars<0) {
		alarm = "\n\n"+this.lblCountCharWarn;
	}
	alert(this.lblCountTotal+": "+count+ "\n"+this.lblCountCharTotal+": "+totalChars+"\n"+this.lblCountChar+": "+charsLeft+alarm);
}






/* --------------------------------
      Non-designMode() Functions
-------------------------------- */

RTEF.prototype.autoBRon = function(rte) {
	// CM 19/10/04 used for non RTE browsers to deal with auto <BR> (and clean up other muck)
	var oRTE = document.forms[0].elements[rte];
	oRTE.value = this.parseBreaks(oRTE.value);
	oRTE.value = this.replaceIt(oRTE.value,'&apos;','\'');
}

RTEF.prototype.autoBRoff = function(rte) {
	// CM 19/10/04 used for non RTE browsers to deal with auto <BR> (auto carried out when the form is submitted)
	var oRTE = document.forms[0].elements[rte];
	oRTE.value = this.replaceIt(oRTE.value,'\n','<br />');
	oRTE.value = this.replaceIt(oRTE.value,'\'','&apos;');
}

RTEF.prototype.parseBreaks = function(argIn) {
	// CM 19/10/04 used for non RTE browsers to deal with auto <BR> (and clean up other muck)
	argIn = this.replaceIt(argIn,'<br>','\n');
	argIn = this.replaceIt(argIn,'<BR>','\n');
	argIn = this.replaceIt(argIn,'<br/>','\n');
	argIn = this.replaceIt(argIn,'<br />','\n');
	argIn = this.replaceIt(argIn,'\t',' ');
	argIn = this.replaceIt(argIn,'\n ','\n');
	argIn = this.replaceIt(argIn,' <p>','<p>');
	argIn = this.replaceIt(argIn,'</p><p>','\n\n');
	argIn = this.replaceIt(argIn,'&apos;','\'');
	argIn = this.trim(argIn);
	return argIn;
}






/* ---------------------------
      Gecko-Only Functions
--------------------------- */

RTEF.prototype.geckoKeyPress = function(evt) {
	// function to add bold, italic, and underline shortcut commands to gecko RTEs
	// contributed by Anti Veeranna (thanks Anti!)
	var rte = evt.target.id;
	if (evt.ctrlKey) {
		var key = String.fromCharCode(evt.charCode).toLowerCase();
		var cmd = '';
		switch (key) {
			case 'b': cmd = "bold"; break;
			case 'i': cmd = "italic"; break;
			case 'u': cmd = "underline"; break;
		}
		if (cmd) {
			this.rteCommand(rte, cmd, null);
			// stop the event bubble
			evt.preventDefault();
			evt.stopPropagation();
		}
	}
}






/* -------------------------
       IE-Only Functions
-------------------------- */

RTEF.prototype.checkspell = function() {
	this.dlgCleanUp();
	//function to perform spell check
	try {
		var tmpis = new ActiveXObject("ieSpell.ieSpellExtension");
		tmpis.CheckAllLinkedDocuments(document);
	} catch(exception) {
		if (exception.number==-2146827859) {
			if (confirm("ieSpell not detected. Click Ok to go to download page.")) {
				window.open("http://www.iespell.com/download.php","DownLoad");
			}
		} else {
			alert("Error Loading ieSpell: Exception " + exception.number);
		}
	}
}







/* ---------------------
      New functions
--------------------- */

function fitImages(rteObj,maxWidth) {
    var elms = rteObj.returnRTE(rteObj.currentRTE).document.getElementsByTagName('img');
    for (var i=0;i<elms.length;i++) {
        elms[i].onload = function(e) {
            if (this.width>maxWidth) this.style.width = maxWidth+'px';
        }
    }

    var elms = rteObj.returnRTE(rteObj.currentRTE).document.getElementsByTagName('img');
    for (var i=0;i<elms.length;i++) {
        if (elms[i].width>maxWidth) elms[i].style.width = maxWidth+'px';
    }
}



