/******************************************************************************
* odfRichText.js
*******************************************************************************
Cross-Browser Rich Text Editor
http://www.kevinroth.com/rte/demo.htm
Written by Kevin Roth (kevin@NOSPAMkevinroth.com - remove NOSPAM)
Visit the support forums at http://www.kevinroth.com/forums/index.php?c=2
This code is public domain. Redistribution and use of this code, 
with or without modification, is permitted.
******************************************************************************/
//init variables
var isRichText = false;
var rng;
var currentRichTextControl;
var allRTEs = new Array();

var isIE;
var isIE6;
var isGecko;
var isSafari;
var isKonqueror;

var imagesPath;
var cssFile;

var lang = "en";
var encoding = "iso-8859-1";

var isRichTextReset = false;
var textColors = new Array();

var albumDialogUrl;
var albumPrivateDialogUrl;
var imageProviderUrl;
var linkDialogUrl;
var tableDialogUrl;
var isXHTMLEditor = true;
var uploadUrl = null;


function initRichTextControls(css, textColor1, textColor2, textColor3, textColor4, albumUrl, albumPrivateUrl, providerUrl, linkUrl, tableUrl) 
{
	textColors[1] = textColor1;
	textColors[2] = textColor2;
	textColors[3] = textColor3;
	textColors[4] = textColor4;
	albumDialogUrl = albumUrl;
	albumPrivateDialogUrl = albumPrivateUrl;
	imageProviderUrl = providerUrl;
	linkDialogUrl = linkUrl;
	tableDialogUrl = tableUrl;
	
	var imgPath = "iso_icons/"; 
	if(isRichTextReset) return;
	isRichTextReset = true;
	//set browser vars
	var ua = navigator.userAgent.toLowerCase();
	isIE = ((ua.indexOf("msie") != -1) && (ua.indexOf("opera") == -1) && (ua.indexOf("webtv") == -1)); 
	isIE6 = ((ua.indexOf("msie 6") != -1) && (ua.indexOf("opera") == -1) && (ua.indexOf("webtv") == -1)); 
	isGecko = (ua.indexOf("gecko") != -1);
	isSafari = (ua.indexOf("safari") != -1);
	isKonqueror = (ua.indexOf("konqueror") != -1);
	
	//check to see if designMode mode is available
	//Safari/Konqueror think they are designMode capable even though they are not
	if (document.getElementById && document.designMode && !isSafari && !isKonqueror) {
		isRichText = true;
	}
	
	if (isIE) {
		document.onmouseover = raiseButton;
		document.onmouseout  = normalButton;
		document.onmousedown = lowerButton;
		document.onmouseup   = raiseButton;
	}
	
	//set paths vars
	imagesPath = imgPath + "odf_button_";
	cssFile = css;
	
	//if (isRichText) document.writeln('<style type="text/css">@import "rte.css";</style>');
	
	//for testing standard textarea, uncomment the following line
	//isRichText = false;
}

function RichTextControl(id, formManager, name, map)
{
	initRichText();
	this._debug = false;
	GenericControl.call(this, id, formManager, name, map);
	this._width =  parseInt(this._props.width, 10);
	this._height =  parseInt(this._props.height, 10);
	this._readonly = this._props.readonly == "true";
	this._hiddenFeatures = {};
	var hiddenFeatures = map.hiddenfeatures;
	uploadUrl = map.uploadUrl;
	if(hiddenFeatures != null) {
		hiddenFeatures = hiddenFeatures.split(" ");
		for(var i=0;i<hiddenFeatures.length;i++) {
			var hiddenFeature = hiddenFeatures[i];
			if(hiddenFeature == "") continue;
			this._hiddenFeatures[hiddenFeature] = 1;
		}
	}
	this.writeRichText(this._props.html);
	currentRichTextControl = this;
	eval("rt" + id  + " = currentRichTextControl");
}

RichTextControl.prototype = new GenericControl();

RichTextControl.prototype.needThumbnail = function(oid, w, h, isPrivate) {
    var input = document.getElementById("hdnThumbnails" + this._id);
    var key = [oid, w, h, isPrivate].join("|");
    var value = [key];
    var previous = input.value;
    if (previous != "")
        value.push(previous);
    input.value = value.join(",");
    input.disabled = false;
}

RichTextControl.prototype.getMainInput = function()
{
	return document.getElementById('hdn' + this._id);
}

RichTextControl.prototype.isReadOnly = function()
{
	return this._readonly;
}

RichTextControl.prototype.isDisabled = function()
{
	return this._readonly;
}

RichTextControl.prototype.disable = function(flag)
{
}

RichTextControl.prototype.onSubmit = function(formManager)
{
	this.updateControl();
	return GenericControl.prototype.onSubmit.call(this, formManager);
}

/*
<DIV class="admActionBar"><UL><LI><A class="modify" href="http://localhost:8080/38/dev/unic/mySql/ocsCatalog00010024.asp?mode=modify&card=628">Modifier la fiche </A></LI>
*/
RichTextControl.prototype.addButtonCell = function(identifier, image, titleId, onclick, className)
{
	var id = this._id;
	var title = objThesaurus.translate(titleId);
	if(this._xhtmlMarkup) {
		if(className == null) className = identifier;
		var html = '<li><a class="' + className + '" title="'+ title +'" id="' + identifier + '" href="#" onclick="' + onclick.replace(/"/g, "&quot;") + ';return false;"><span class="richTextButtonText">' + identifier + '</span></a></li>';
	} else {
		var html = '<td><a href="#" onclick="' + onclick.replace(/"/g, "&quot;") + ';return false;"><img';
		if(identifier != null) html += ' id="' + identifier + '"';
		html += ' class="rteImage" src="' + imagesPath + image + '" width="25" height="24" alt="' + objThesaurus.translate(titleId)+'" title="'+ title +'"/></a></td>\n';
	}
	return html;
}

RichTextControl.prototype.addSepCell = function()
{
	if(this._xhtmlMarkup) {
		return "<li><span class='sep'></span></li>";
		return '<span class="richTextButtonBarSep"><img class="rteVertSep" src="' + imagesPath + 'blackdot.gif" width="1" height="20" border="0" alt=""/></span>';
	} else {
		return '<td><img class="rteVertSep" src="' + imagesPath + 'blackdot.gif" width="1" height="20" border="0" alt=""/></td>';
	}
}

RichTextControl.prototype.writeRichText = function(html) 
{
	var width = this._width;
	var height = this._height;
	var name = this._name;
	var id = this._id;
	this._xhtmlMarkup = true;;
	if (isRichText) {
		allRTEs[allRTEs.length] = this;		
		//adjust minimum table widths
		if (width < 200) width = 200;
		var tablewidth = width;
		if (isIE6) {
			tablewidth += 2;
		} 
		var h = [];
		if(!this._readonly) {
			h = h.concat(['<div id="div_',id,'" class="richTextControl" style="width:',tablewidth,'px">']);
			if(this._xhtmlMarkup) {
				h = h.concat(["<div class='richTextButtonBar' style='width:",tablewidth,"px'><h2>Boutons de commandes</h2><ul>"]);
			} else {
				h = h.concat(['<table class="rteBack" cellpadding="0" cellspacing="0" id="Buttons2_',id,'" width="',tablewidth,'"><tr>']);
			}
			var needSep = false;
			if (this._hiddenFeatures.style == null) {
				h = h.concat([
					this.addButtonCell("bold", "bold.gif", "odf237", ["rt",id,".executeCommand('bold', '')"].join("")),
					this.addButtonCell("italic", "italic.gif", "odf238", ["rt",id,".executeCommand('italic', '')"].join("")),
					this.addButtonCell("underline", "underline.gif", "odf21", ["rt",id,".executeCommand('underline', '')"].join("")),
					this.addButtonCell("forecolor_"+id, "textcolor.gif", "odf239", ["rt",id,".showColorMenu()"].join(""),"textcolor")]);
				if (this._xhtmlMarkup) {
				} else {
					h.push("<td>");
				}
				h = h.concat([
					'<select style="width:120px" id="formatblock_',id,'" onchange="rt',id,'.selectFont(this.id);">\n',
					'<option value="">',objThesaurus.translate("odf240"),'</option>\n',
					'<option value="<p>">',objThesaurus.translate("odf241"),' &lt;p&gt;</option>\n',
					'<option value="<pre>">',objThesaurus.translate("odf22"),' &lt;pre&gt;</option>\n',
					'<option value="<h1>">',objThesaurus.translate("odf242"),' &lt;h1&gt;</option>\n',
					'<option value="<h2>">',objThesaurus.translate("odf243"),' &lt;h2&gt;</option>\n',
					'<option value="<h3>">',objThesaurus.translate("odf244"),' &lt;h3&gt;</option>\n',
					'<option value="<h4>">',objThesaurus.translate("odf245"),' &lt;h4&gt;</option>\n',
					'<option value="<h5>">',objThesaurus.translate("odf246"),' &lt;h5&gt;</option>\n',
					'<option value="<h6>">',objThesaurus.translate("odf247"),' &lt;h6&gt;</option>\n',
					'</select>\n']);
				if(this._xhtmlMarkup) {
				} else {
					h.push("</td>");
				}
				needSep = true;
			}
			if(this._hiddenFeatures.align == null) {
				if(needSep) {
					needSep = false;
					h.push(this.addSepCell());
				}
				h = h.concat([
					this.addButtonCell("left_just", "left_just.gif", "odf23", ["rt",id,".executeCommand('justifyleft', '')"].join("")),
					this.addButtonCell("centre", "centre.gif", "odf28", ["rt",id,".executeCommand('justifycenter', '')"].join("")),
					this.addButtonCell("right_just", "right_just.gif", "odf24", ["rt",id,".executeCommand('justifyright', '')"].join("")),
					this.addButtonCell("justifyfull", "justifyfull.gif", "odf248", ["rt",id,".executeCommand('justifyfull', '')"].join(""))]);
				needSep = true;
			}			
			if(this._hiddenFeatures.list == null) {
				if(needSep) {
					needSep = false;
					h.push(this.addSepCell());
				}
				h = h.concat([
					this.addButtonCell("numbered_list", "numbered_list.gif", "odf25", ["rt",id,".executeCommand('insertorderedlist', '')"].join("")),
					this.addButtonCell("list", "list.gif", "odf26", ["rt",id,".executeCommand('insertunorderedlist', '')"].join(""))]);
				needSep = true;
			}
			if(this._hiddenFeatures.indent == null) {
				if(needSep) {
					needSep = false;
					h.push(this.addSepCell());
				}
				h = h.concat([
					this.addButtonCell("outdent", "outdent.gif", "odf249", ["rt",id,".executeCommand('outdent', '')"].join("")),
					this.addButtonCell("indent", "indent.gif", "odf250", ["rt",id,".executeCommand('indent', '')"].join(""))]);
				needSep = true;
			}
			if(this._hiddenFeatures.link == null) {
				if(needSep) {
					needSep = false;
					h.push(this.addSepCell());
				}
				h.push(this.addButtonCell("hyperlink", "hyperlink.gif", "odf251", ["rt",id,".showLinkEditorDialog()"].join("")));
			}
			if(this._hiddenFeatures.image == null) {
				if(needSep) {
					needSep = false;
					h.push(this.addSepCell());
				}
				h.push(this.addButtonCell("image", "image.gif", "odf252", ["rt",id,".showImageEditorDialog()"].join("")));
			}
			if(this._hiddenFeatures.table == null) {
				if(needSep) {
					needSep = false;
					h.push(this.addSepCell());
				}
				h.push(this.addButtonCell("insert_table", "insert_table.gif", "odf279", ["rt",id,".dlgInsertTable()"].join("")));
			}
			if(this._debug) h.push(this.addButtonCell("debug", "debug.gif", "odf27", ["rt",id,".showXml()"].join("")));
			if(this._xhtmlMarkup) {
				h.push('</ul><br class="clear"/></div>');
			} else {
				h.push('<td width="100%"></td></tr></table>');
			}
			var colorMenu = ['<div id="colorMenu_',id,'" class="hiddenRichTextMenu">\n'];
			for(var i=0;i<=4;i++)
			{
				var color = i==0?"black":textColors[i];
				colorMenu = colorMenu.concat(['<a href="#" onclick="return rt',id,'.changeColor(',i,');" class="colorMenuEntry" style="background-color:',color,';"></a>\n']);
			}
			colorMenu.push('</div>');
			h = h.concat(colorMenu);
		}
		h = h.concat([
			'<iframe frameborder="0" id="',id,'" name="',id,'" width="',width,'px" height="',height,'px" h="',height,'" w="',width,'" src="blank.htm" onfocus="rt',id,'.focus()"></iframe>',
			'<input type="hidden" id="hdn',id,'" name="',name,'" value=""/>',
			'<input type="hidden" disabled="disabled" id="hdnThumbnails',id,'" name="albRequiredThumbnails" value=""/>',
			'<div id="menu_',id,'" class="hiddenRichTextMenu"></div>',
			'<div id="hidden_',id,'" class="hiddenRichTextMenu"></div>',
			'<div id="panel_',id,'" class="hiddenRichTextPanel"></div>',
			'</div>']);
		document.write(h.join(""));
		this.loadXHTML(html);
	} else {
		document.writeln(['<textarea name="',id,'" id="',id,'" style="width: ',width,'px; height: ',height,'px;">',html,'</textarea>'].join(""));
	}
}

RichTextControl.prototype.focus = function()
{
	var id = this._id;	
	var oRTE;
	if (document.all) {
		oRTE = frames[id];
	} else {
		oRTE = document.getElementById(id).contentWindow;
	}
	if(document.all) {
		var body = oRTE.document.body;
		var selection = oRTE.document.selection;
		if(selection.type == "None") {
			var tr = body.createTextRange();
			tr.collapse(false);
			tr.select();
		} else {
			body.focus();
		}
	}
}
RichTextControl.prototype.enlargeArea = function()
{
	var id = this._id;
	var iframe = document.getElementById(id);
	var div = document.getElementById("div_" + id);
	var initialHeight = parseInt(iframe.getAttribute("h"), 10);
	var initialWidth = parseInt(iframe.getAttribute("w"), 10);
	if(isNaN(initialHeight)) initialHeight = 100;
	if(isNaN(initialWidth)) initialWidth = 400;
	if(initialHeight == iframe.height) {
		var bodyClientSize = getBodyClientSize();
		var height = bodyClientSize.height;
		var width = bodyClientSize.width;
		height -= 80;
		width -= 30;
		iframe.height = height;
		iframe.width = width;
		var position = richTextAttributeEditor.getAbsolutePos(div);
		document.body.scrollLeft = position.x;
		document.body.scrollTop = position.y;
	} else {
		iframe.height = initialHeight;
		iframe.width = initialWidth;
	}
}

RichTextControl.prototype.attachEvents = function() 
{
	var id = this._id;
	if(frames[id].document.body != null) {
		if(!document.all) {
			this.addEvent(frames[id].document.body, "paste", function evt_ie_paste(event) {iePaste(event, id);}); 
			this.addEvent(frames[id].document, "keypress", function evt_ie_keypress(event) {ieKeyPress(event, id);});
			this.addEvent(frames[id].document, "mousedown", function evt_ie_click(event) {ieClick(event, id);});
			//this.addEvent(frames[id].document, "contextmenu", function (event) {evt_oncontextmenu(event, id);});		
		} else {
			frames[id].document.body.attachEvent("onpaste", function evt_ie_paste(event) {iePaste(event, id);});
			frames[id].document.attachEvent("onkeypress", function evt_ie_keypress(event) {ieKeyPress(event, id);});
			frames[id].document.attachEvent("onmousedown", function evt_ie_click(event) {ieClick(event, id);});
			frames[id].document.attachEvent("oncontextmenu", function (event) {evt_oncontextmenu(event, id);});		
			frames[id].document.body.attachEvent("ondrop", function (event) {evt_ondrop(event, id);});		
		}
	} else {
		setTimeout("rt" + id + ".attachEvents()", 1);
	}
}

RichTextControl.prototype.attachPanelEvents = function()
{
	if(this.iePanelKeyPress != null) return;
	var id = this._id;
	if(frames[id].document.body != null) {
		//frames[id].document.attachEvent("onkeypress", this.iePanelKeyPress = function evt_ie_menu_keypress(event) {iePanelKeyPress(event, id);});
		this.addEvent(frames[id].document.body, "onkeypress", this.iePanelKeyPress = function evt_ie_menu_keypress(event) {iePanelKeyPress(event, id);});
	}
}
RichTextControl.prototype.detachPanelEvents = function()
{
	if(this.iePanelKeyPress == null) return;
	var id = this._id;
	if(frames[id].document.body != null) {
		//frames[id].document.detachEvent("onkeypress", this.iePanelKeyPress);
		this.removeEvent(frames[id].document.body, "onkeypress", this.iePanelKeyPress = function evt_ie_menu_keypress(event) {iePanelKeyPress(event, id);});
		this.iePanelKeyPress = null;
	}
}

RichTextControl.prototype.addEvent = function(el, evname, func) 
{
	if (el.attachEvent) { // IE
		el.attachEvent("on" + evname, func);
	} else if (el.addEventListener) { // Gecko / W3C
		el.addEventListener(evname, func, true);
	} else {
		el["on" + evname] = func;
	}
}

RichTextControl.prototype.removeEvent = function(el, evname, func) 
{
	if (el.detachEvent) { // IE
		el.detachEvent("on" + evname, func);
	} else if (el.removeEventListener) { // Gecko / W3C
		el.removeEventListener(evname, func, true);
	} else {
		el["on" + evname] = null;
	}
}
RichTextControl.prototype.enableDesignMode = function()
{
    var html = this._newHTML;
	var id = this._id;
    var frameHtml = "";
    if (isXHTMLEditor) {
        frameHtml += '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n';
    }
    frameHtml += "<html id=\"" + id + "\">\n";
    frameHtml += "<head>\n";
    //to reference your stylesheet, set href property below to your stylesheet path and uncomment
    if (cssFile.length > 0) {
        var cssFiles = cssFile.split(" ");
        for (var i = 0; i < cssFiles.length; i++)
            frameHtml += "<link media=\"all\" type=\"text/css\" href=\"" + cssFiles[i] + "\" rel=\"stylesheet\">\n";
    } else {
        frameHtml += "<style>\n";
        frameHtml += "body {\n";
        frameHtml += "	background: #FFFFFF;\n";
        frameHtml += "	margin: 0px;\n";
        frameHtml += "	padding: 0px;\n";
        frameHtml += "}\n";
        frameHtml += "</style>\n";
    }
    frameHtml += "</head>\n";
    frameHtml += "<body class='directHtml' id='body_" + id + "'>\n";
    frameHtml += html + "\n";
    frameHtml += "</body>\n";
    frameHtml += "</html>";
    if (document.all) {
        var oRTE = frames[id].document;
        oRTE.open();
        oRTE.write(frameHtml);
        oRTE.close();
        oRTE.designMode = this._readonly ? "Off" : "On";
        this.attachEvents();
    } else {
        try {
            document.getElementById(id).contentDocument.designMode = this._readonly ? "off" : "on";
            try {
                var oRTE = document.getElementById(id).contentWindow.document;
                oRTE.open();
                oRTE.write(frameHtml);
                oRTE.close();
                this.attachEvents();
                if (isGecko) {
                    //attach a keyboard handler for gecko browsers to make keyboard shortcuts work
                    oRTE.addEventListener("keypress", geckoKeyPress, true);
                    oRTE.addEventListener("contextmenu", geckoContextMenu, true);
                }

            } catch (e) {
                alert("Error preloading content.");
            }
        } catch (e) {
            //gecko may take some time to enable design mode.
            //Keep looping until able to set.
            if (isGecko) {
                setTimeout("rt" + id + ".enableDesignMode();", 10);
                return;
            } else {
                return false;
            }
        }
    }
    this._newHTML = null;
}

RichTextControl.prototype.updateControl = function() 
{
	var id = this._id;
	if (!isRichText) return;
	
	//check for readOnly mode
	var readOnly = this._readonly;
	if (document.all) {
		if (frames[id].document.designMode != "On") readOnly = readOnly && true;
	} else {
		if (document.getElementById(id).contentDocument.designMode != "on") readOnly = readOnly && true;
	}
	
	if (isRichText && !readOnly) {
		//if viewing source, switch back to design view
		//if (document.getElementById("chkSrc" + id).checked) document.getElementById("chkSrc" + id).click();
		this.setHiddenVal();
	}
}

RichTextControl.prototype.setHiddenVal = function() 
{
	var id = this._id;
	//set hidden form field value for current rte
	var oHdnField = document.getElementById('hdn' + id);
	
	if (oHdnField.value == null) oHdnField.value = "";
	if (document.all) {
		oHdnField.value = this.convertToXHTML(frames[id].document.body, false);
	} else {
		oHdnField.value = this.convertToXHTML(document.getElementById(id).contentWindow.document.body, false);
	}	
	//if there is no content (other than formatting) set value to nothing
	if (stripHTML(oHdnField.value.replace("&nbsp;", " ")) == "" &&
		oHdnField.value.toLowerCase().search("<hr") == -1 &&
		oHdnField.value.toLowerCase().search("<img") == -1) oHdnField.value = "";
}




RichTextControl.prototype.showXml = function()
{
	var id = this._id;
	var xml = "";
	if (document.all) {
		xml = this.convertToXHTML(frames[id].document.body, lang, encoding);
	} else {
		xml = this.convertToXHTML(document.getElementById(id).contentWindow.document.body, lang, encoding);
	}
	alert(frames[id].document.body.innerHTML + "\n\n" + xml);
}



RichTextControl.prototype.needNewLine = {div:1, p:1, table:1, tbody:1, tr:1, td:1, th:1, title:1, head:1, body:1, script:1, comment:1, li:1, meta:1, h1:1, h2:1, h3:1, h4:1, h5:1, h6:1, hr:1, ul:1, ol:1, option:1};
RichTextControl.prototype.hyphenRegExp = /-$/;
RichTextControl.prototype.commentRegExp = /^<!--(.*)-->$/;

RichTextControl.prototype.convertToXHTMLtext = function (text, isInPre) 
{
	text = text + "";
	text = text.replace(/\&/g, "&amp;");
	if(!isInPre) {
		if(text == "\n") return "";
		text = text.replace(/\n{2,}/g, "\n").replace(/\240/g,"&nbsp;");
	} else {
		text = text.replace(/[ \240]/g,"&nbsp;");
	}
	var regexp = /([^ -\377])/;
	var array = regexp.exec(text);
	var res = "";
	var lastPos = 0;
	while(array != null && array.index >= 0) {
		if(array.index > 0) res += text.substr(0, array.index);
		text = text.substr(array.index + array[0].length);
		res += "&#" + array[1].charCodeAt(0) + ";";
		array = regexp.exec(text);
		//break;
	}
	res += text;
	return res.replace(/</g, "&lt;").replace(/>/g, "&gt;");
}

RichTextControl.prototype.convertToXHTMLattribute = function (text) 
{
	text = text + "";
	return text.replace(/\&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/\"/g, "&quot;");
}

RichTextControl.prototype.showColorMenu = function()
{
	var div = document.getElementById('colorMenu_' + this._id);
	div.className = "richTextColorMenu";
	var img = document.getElementById('forecolor_' + this._id);
	var top = this.getPositionTop(img);
	var left = this.getPositionLeft(img);
	div.style.top = (top + 24) + "px";
	div.style.left = left + "px";
}
RichTextControl.prototype.getOffsetLeft = function(elm)
{
	var mOffsetLeft = elm.offsetLeft;
	var mOffsetParent = elm.offsetParent;
	
	while(mOffsetParent!=null) {
		mOffsetLeft += mOffsetParent.offsetLeft;
		mOffsetParent = mOffsetParent.offsetParent;
	}	
	return mOffsetLeft;
}
RichTextControl.prototype.getOffsetTop = function(elm)
{
	var mOffsetTop = elm.offsetTop;
	var mOffsetParent = elm.offsetParent;
	
	while(mOffsetParent!=null) {
		mOffsetTop += mOffsetParent.offsetTop;
		mOffsetParent = mOffsetParent.offsetParent;
	}	
	return mOffsetTop;
}

RichTextControl.prototype.getPositionTop = function(elm)
{
	var mOffsetTop = elm.offsetTop;
	var mOffsetParent = elm.offsetParent;
	
	while(mOffsetParent!=null) {
		if(document.all && mOffsetParent.currentStyle.position == "absolute") break;
		if(!document.all && window.getComputedStyle(mOffsetParent, "").position == "absolute") break;

		mOffsetTop += mOffsetParent.offsetTop;
		mOffsetParent = mOffsetParent.offsetParent;
	}	
	return mOffsetTop;
}
RichTextControl.prototype.getPositionLeft = function(elm)
{
	var mOffsetLeft = elm.offsetLeft;
	var mOffsetParent = elm.offsetParent;
	
	while(mOffsetParent!=null) {
		if(document.all && mOffsetParent.currentStyle.position == "absolute") break;
		if(!document.all && window.getComputedStyle(mOffsetParent, "").position == "absolute") break;
		mOffsetLeft += mOffsetParent.offsetLeft;
		mOffsetParent = mOffsetParent.offsetParent;
	}	
	return mOffsetLeft;
}
RichTextControl.prototype.hideColorMenu = function() 
{
	var div = document.getElementById('colorMenu_' + this._id);
	if(div == null) return;
	div.className = "hiddenRichTextMenu";
}

RichTextControl.prototype.changeColor = function(i) 
{
	this.hideColorMenu();
	var textColor = textColors[i];
	if(textColor != null) {
		this.executeCommand("ForeColor", textColor);
	} else {
		this.executeCommand("RemoveFormat");
	}
	return false;
}
RichTextControl.prototype.selectionIsInsideATable = function()
{
	var id = this._id;	
	var oRTE;
	if (document.all) {
		oRTE = frames[id];
	} else {
		oRTE = document.getElementById(id).contentWindow;
	}	
	oRTE.focus();
	var parentElement = null;
	if (document.all) {
		if(oRTE.document.selection.type == "Text" || oRTE.document.selection.type == "None") {
			var oRng = oRTE.document.selection.createRange();
			parentElement = oRng.parentElement();
		} else {
			var list = oRTE.document.selection.createRange();
			parentElement = list.item(0);
		}
	} else {
		// to be done;
	}
	var element = parentElement;
	while(element && element.nodeType == 1) {
		if(element.tagName == "TABLE") return true;
		element = element.parentElement;
	}
	return false;
}
RichTextControl.prototype.insertHTML = function(html) 
{
	var id = this._id;	
	var oRTE;
	if (document.all) {
		oRTE = frames[id];
	} else {
		oRTE = document.getElementById(id).contentWindow;
	}	
	oRTE.focus();
	if (document.all) {
		if(oRTE.document.selection.type == "Text" || oRTE.document.selection.type == "None") {
			var oRng = oRTE.document.selection.createRange();
			var parentElement = oRng.parentElement();
			oRng.pasteHTML(html);
			oRng.collapse(false);
			oRng.select();
		} else {
			var list = oRTE.document.selection.createRange();
			var tag = list.item(0);
			var oRng = oRTE.document.body.createTextRange();
			oRng.moveToElementText(tag);
			oRng.pasteHTML(html);
		}
	} else {
		oRTE.document.execCommand('insertHTML', false, html);
	}
}



RichTextControl.prototype.executeCommand = function(command, option) 
{
	var id = this._id;
	//function to perform command
	var oRTE;
	if (document.all) {
		oRTE = frames[id];
	} else {
		oRTE = document.getElementById(id).contentWindow;
	}
	
	try {
		oRTE.focus();
	  	oRTE.document.execCommand(command, false, option);
		oRTE.focus();
	} catch (e) {
//		alert(e);
	}
}

RichTextControl.prototype.selectFont = function(selectname)
{
	var id = this._id;
	//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('_' + id, '');
		this.executeCommand(cmd, selected);
		document.getElementById(selectname).selectedIndex = 0;
	}
}

RichTextControl.prototype.dlgColorPalette = function(command) 
{
	var id = this._id;
	//function to display or hide color palettes
	this.setRange();
	
	//get dialog position
	var oDialog = document.getElementById('cp' + id);
	var buttonElement = document.getElementById(command + '_' + id);
	var iLeftPos = getOffsetLeft(buttonElement);
	var iTopPos = getOffsetTop(buttonElement) + (buttonElement.offsetHeight + 4);
	oDialog.style.left = (iLeftPos) + "px";
	oDialog.style.top = (iTopPos) + "px";
	
	if ((command == parent.command) && (this == currentRichTextControl)) {
		//if current command dialog is currently open, close it
		if (oDialog.style.visibility == "hidden") {
			showHideElement(oDialog, 'show');
		} else {
			showHideElement(oDialog, 'hide');
		}
	} else {
		//if opening a new dialog, close all others
		for (var i = 0; i < allRTEs.length; i++) {
			showHideElement('cp' + allRTEs[i].getId(), 'hide');
		}
		showHideElement(oDialog, 'show');
	}
	
	//save current values
	parent.command = command;
	currentRichTextControl = this;
}

//RichText :ouvrir la fenetre pour insérer un tableau dans le richtext
RichTextControl.prototype.dlgInsertTable = function()
{
	//parent.command = command;
	window.tableDialogClient = new TableEditor(this);
	currentRichTextControl = this;
	var windowOptions = 'history=no,toolbar=0,location=0,directories=0,status=0,menubar=0,scrollbars=no,resizable=no,width=350,height=300';
	window.open(fixUrl(tableDialogUrl), 'InsertTable', windowOptions);
}
RichTextControl.prototype.popUpWin = function(url, win, width, height, options) 
{
	var leftPos = (screen.availWidth - width) / 2;
	var topPos = (screen.availHeight - height) / 2;
	options += 'width=' + width + ',height=' + height + ',left=' + leftPos + ',top=' + topPos;
	return window.open(fixUrl(url), win, options);
}

RichTextControl.prototype.showLinkEditorDialog = function(element) 
{
	//function to open/close insert table dialog
	//save current values
	parent.command = "link";
	window.linkDialogClient = new LinkEditor(this, element);

	var width = "630";
	var height = "500";
	var leftPos = (screen.availWidth - width) / 2;
	var topPos = (screen.availHeight - height) / 2;
	var options = 'width=' + width + ',height=' + height + ',left=' + leftPos + ',top=' + topPos;
	showModalWindow(linkDialogUrl, "linkDialog", width, height, window.linkDialogClient);
	/*
	var win = window.open(linkDialogUrl, "linkDialog", options);
	win.focus();
	*/
}

RichTextControl.prototype.hideMenu = function()
{
	this.detachPanelEvents();
	var menu = document.getElementById("menu_" + this._id);
	if(menu == null) return;
	menu.className = "hiddenRichTextMenu";	
}

RichTextControl.prototype.hidePanels = function()
{
	this.hideMenu();
	this.hidePanel();
	this.hideColorMenu();
}

RichTextControl.prototype.hidePanel = function()
{
	var panel = document.getElementById("panel_" + this._id);
	if(panel == null) return;
	if(panel.className != "hiddenRichTextPanel") {
		panel.className = "hiddenRichTextPanel";
		richTextAttributeEditor.hideShowCovered();
	}
}

RichTextControl.prototype.showImageEditorDialog = function() 
{
	//function to add image
	if(this._props.resourcetype == "private") {
		currentRichTextControl = this;
		window.albumDialogClient = new ImageEditor(this, imageProviderUrl, false, false);
		window.albumDialogClient.init();
		var width = "292"
		var height = "485"
		var leftPos = (screen.availWidth - width) / 2;
		var topPos = (screen.availHeight - height) / 2;
		var options = 'width=' + width + ',height=' + height + ',left=' + leftPos + ',top=' + topPos;
		showModalWindow(albumPrivateDialogUrl, "albumDialog", width, height, window.albumDialogClient);
	} else {
		currentRichTextControl = this;
		window.albumDialogClient = new ImageEditor(this, imageProviderUrl, false, true);
		window.albumDialogClient.init();
		var width = "800";
		var height = "600";
		var leftPos = (screen.availWidth - width) / 2;
		var topPos = (screen.availHeight - height) / 2;
		var options = 'width=' + width + ',height=' + height + ',left=' + leftPos + ',top=' + topPos;
		showModalWindow(albumDialogUrl, "albumDialog", width, height, window.albumDialogClient);
	}

}

 
RichTextControl.prototype.setRange = function() 
{
	var id = this._id;
	//function to store range of current selection
	var oRTE;
	if (document.all) {
		oRTE = frames[id];
		var selection = oRTE.document.selection; 
		if (selection != null) rng = selection.createRange();
	} else {
		oRTE = document.getElementById(id).contentWindow;
		var selection = oRTE.getSelection();
		rng = selection.getRangeAt(selection.rangeCount - 1).cloneRange();
	}
	return rng;
}

RichTextControl.prototype.getTextRange = function() 
{
	var id = this._id;
	var oRTE;
	if (document.all) {
		oRTE = frames[id];
		return oRTE.document.body.createTextRange(); 
	}
}


var delayedPasteControl = null;

function delayedPaste()
{
	if(delayedPasteControl == null) return;
	delayedPasteControl.cleanupDom();
	delayedPasteControl = null;
}

RichTextControl.prototype.cleanupDom = function()
{
	var id = this._id;
	var id = this._id;
	var doc = document.getElementById(id).contentWindow.document;
	var body = doc.body;
	var children = body.childNodes;
	var xhtml = ""; 
	for(var i=0;i<children.length;i++) {
		var child = children[i];
		xhtml += this.convertToXHTML(child,  false);
	}
	this.loadXHTML(xhtml);
}


RichTextControl.prototype.paste = function(evt)
{
	if(document.all) {
		var html = this.GetClipboardHTML(this.selectionIsInsideATable());
		this.insertHTML(html);
		return this.stopEvent(evt);
	} else {
		var id = this._id;
		var doc = document.getElementById(id).contentWindow.document;
		//var innerDiv = this.pastedInnerDiv = doc.createElement("div"); 
		//var selection = document.getElementById(id).contentWindow.getSelection();
		//rng = selection.getRangeAt(0);
		//rng.surroundContents(innerDiv);
		delayedPasteControl = this;
		window.setTimeout("delayedPaste()", 1);
	}
}

RichTextControl.prototype.stopEvent = function(evt) 
{
	evt || (evt = window.event);
	if (document.all != null) {
		evt.cancelBubble = true;
		evt.returnValue = false;
	} else {
		evt.preventDefault();
		evt.stopPropagation();
	}
	return false;
}




RichTextControl.prototype.GetClipboardHTML = function(insideATable)
{
	var div = this.getClipboardDiv();
	div.innerHTML = "";
	if(document.all) {
		var textRange = document.body.createTextRange();
		textRange.moveToElementText(div);
		textRange.execCommand("Paste");
	} 
	var html = ""
	var children = div.childNodes;
	for(var i=0;i<children.length;i++) {
		html += this.normalizeImportedHTML(children[i], false, insideATable);
	}
	div.innerHTML = '';
	return html;
}

RichTextControl.prototype.getHiddenDiv = function()
{
	return document.getElementById("hidden_" + this._id) ;
}

RichTextControl.prototype.getClipboardDiv = function()
{
	var div = document.getElementById("hiddenDiv") ;
	if ( !div ) {
		var div = document.createElement("DIV") ;
		div.id = "hiddenDiv";
		div.style.position = "absolute";
		if(document.all) {
			div.style.visibility = "hidden";
			div.style.overflow = "hidden";
			div.style.width	= 1;
			div.style.height = 1;
		} 
		document.body.appendChild(div) ;
	}
	return div;
}

RichTextControl.prototype.loadXHTML = function(xhtml)
{
	var div = this.getHiddenDiv();
	if(xhtml == "") xhtml = "<p></p>";
	div.innerHTML = xhtml;
	var html = "";
	var children = div.childNodes;
	for(var i=0;i<children.length;i++) {
		html += this.convertToHTML(children[i], false, true, false);
	}
	div.innerHTML = '';
	this._newHTML = html;
	this.enableDesignMode();
}

RichTextControl.prototype.getDistanceBetweenColors = function(c1, c2)
{
	var delta = 0;
	for(var i=0;i<3;i++) {
		var d = c1[0] - c2[0];
		delta += d * d;
	}
	return delta;
}

RichTextControl.prototype.findNearestColor = function(colorString)
{
	if(colorString == null || colorString == "") return;
	var color = this.getColorObject(colorString);
	if(color == null) return;
	var max = 1000000;
	var bestColor = null;
	for(var i=1;i<5;i++) {
		var textColor = textColors[i];
		var refColor = this.getColorObject(textColor);
		var delta = this.getDistanceBetweenColors(color, refColor);
		if(delta < max) {
			max = delta;
			bestColor = textColor;
		}
	}
	return bestColor;
}

RichTextControl.prototype.getColorObject = function(color)
{
	color = color + "";
	var factor = 1;
	var array = /^#([0-9a-z]{2})([0-9a-z]{2})([0-9a-z]{2})$/i.exec(color);
	if(!array) {
		array = /^#([0-9a-z])([0-9a-z])([0-9a-z])$/i.exec(color);
		factor = 16;
	}
	if(!array) return;
	return new Array(parseInt(array[1], 16) * factor, parseInt(array[2], 16) * factor, parseInt(array[3], 16) * factor);
}

RichTextControl.prototype.normalizeImportedHTML = function(node, isInPre, insideATable)
{
	isInPre = isInPre == true;
	switch(node.nodeType) {
	case 1:
		var children = node.childNodes;
		var endTag = "";
		var tagName = node.tagName.toLowerCase();
		var needEndTag = true;
		var needAlign = false;
		var href = null;
		var skipChildren = false;
		var color = null;
		switch(tagName) {
		case "script":
		case "applet":
		case "object":
		case "noscript":
			tagName = null;
			needEndTag = false;
			skipChildren = true;
			break;
		// elements with model
		case "p":
		case "pre":
		case "ul":
		case "ol":
		case "li":
		case "h1":
		case "h2":
		case "h3":
		case "h4":
		case "h5":
		case "h6":
			break;
		case "strong":
		case "em":
		case "u":
			break;
		case "br":
			needEndTag = false;
			break;
		case "div":
		case "td":	
			tagName = "p"; 
			needAlign = true; 
			break;
		case "table":
			return objTableEditor.convertToHTML(node, this, true, insideATable);
		case "b": tagName = "strong"; break;
		case "i": tagName = "em"; break;
		case "font":
			color = this.findNearestColor(node.color);
			if(color == null) {
				tagName = null;
				needEndTag = false;
				break;
			}
			break;
		case "a":
			href = node.href;
			if(href == null || href == "") {
				tagName = null;
				needEndTag = false;
				break;
			}
			var pos = href.indexOf(":");
			if(pos < 0) {
				tagName = null;
				needEndTag = false;
				break;
			}
			var protocol = href.substr(0, href.indexOf(":"));
			switch(protocol) {
			case "http":
			case "mailto":
				break;
			default:
				tagName = null;
				break;
			}
			break;
		default:
			tagName = null;
			needEndTag = false;
		}
		var html = "";
		if(tagName != null) {
			var elementEditor = richTextAttributeEditor.getElementEditor(tagName);
			if(elementEditor != null) {
				return elementEditor.convertToHTML(node, this, isInPre, true);
			}
			html += "<" + tagName;
			var align = node.align;
			for(var i=0;i<this.genericAttributes.length;i++) {
				var aname = this.genericAttributes[i];
				var avalue = node[aname];
				if(avalue != null && avalue != "") {
					avalue = avalue + "";
					html += " " + aname + "=\"" + avalue.replace(/"/g, "&quot;") + "\"";
				}
			}
			if(needAlign && align != null && align != "") {
				html += " align=\"" + align + "\"";
			}
			if(href != null) {
				html += " href=\"" + href.replace(/"/g, "&quot;") + "\"";
			}
			if(color != null) {
				html += " color=\"" + color.replace(/"/g, "&quot;") + "\"";
			}
			if(needEndTag) {
				html += ">";
				endTag = "</" + tagName + ">";
			} else {
				html += "/>";
			}
		}
		if(!skipChildren) {
			for(var i=0;i<children.length;i++) {
				html += this.normalizeImportedHTML(children[i], isInPre || tagName == "pre", insideATable);
			}
		}
		return html + endTag;
		break;
	case 3:
		return this.convertToXHTMLtext(node.nodeValue, isInPre);
	default:
		return "";
	}
}
RichTextControl.prototype._hexChar = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"];
RichTextControl.prototype.dumpHex = function(n)
{
	var h = (n >> 4) & 0xf;
	var u = n & 0xf;
	return this._hexChar[h] + this._hexChar[u];
}
RichTextControl.prototype.convertToXHTML = function(node, isInPre)
{
    isInPre = isInPre == true;
    var genericAttributes = this.genericAttributes;
    switch (node.nodeType) {
        case 1:
            var children = node.childNodes;
            var endTag = "";
            var tagName = node.tagName.toLowerCase();
            var needEndTag = true;
            var needAlign = false;
            var href = null;
            var skipChildren = false;
            var classAttribute = null;
            switch (tagName) {
                case "script":
                case "applet":
                case "object":
                case "noscript":
                    tagName = null;
                    needEndTag = false;
                    skipChildren = true;
                    break;
                case "table":
                    return objTableEditor.convertToXHTML(node, this);
                    // elements with model
                case "p":
                case "pre":
                case "ul":
                case "ol":
                case "li":
                case "h1":
                case "h2":
                case "h3":
                case "h4":
                case "h5":
                case "h6":
                    var elementEditor = richTextAttributeEditor.getElementEditor(tagName);
                    if (elementEditor != null) {
                        return elementEditor.convertToXHTML(node, this, isInPre);
                    }
                    break;
                case "strong":
                case "em":
                    break;
                case "u":
                    tagName = "span";
                    classAttribute = "underline";
                    break;
                case "img":
                    needEndTag = false;
                    break;
                case "font":
                    var color = node.getAttribute("color");
                    if (color == null || color == "") {
                        tagName = null;
                        needEndTag = false;
                        break;
                    }
                    color = color.toUpperCase();
                    var ok = false;
                    for (var j = 1; j < textColors.length; j++) {
                        var c = textColors[j].toUpperCase();
                        if (c == color) {
                            tagName = "span";
                            classAttribute = "textColor" + j;
                            ok = true;
                            break;
                        }
                    }
                    if (ok) break;
                    tagName = null;
                    needEndTag = false;
                    break;
                case "br":
                    needEndTag = false;
                    break;
                case "div":
                    tagName = "p";
                    needAlign = true;
                    break;
                case "b": tagName = "strong"; break;
                case "i": tagName = "em"; break;
                case "a":
                    href = node.href;
                    if (href == null || href == "") {
                        tagName = null;
                        needEndTag = false;
                        break;
                    }
                    var pos = href.indexOf(":");
                    if (pos < 0) {
                        tagName = null;
                        needEndTag = false;
                        break;
                    }
                    break;
                case "span":
                    if (node.style.fontWeight == "bold") {
                        tagName = "strong"; break;
                    }
                    if (node.style.fontStyle == "italic") {
                        tagName = "em"; break;
                    }
                    if (node.style.textDecoration == "underline") {
                        tagName = "span";
                        classAttribute = "underline";
                        break;
                    }
                    var color = node.style.color;
                    var colorRegex = /^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/;
                    var array = colorRegex.exec(color);
                    if (array) {
                        color = "#" + this.dumpHex(parseInt(array[1], 10)) + this.dumpHex(parseInt(array[2], 10)) + this.dumpHex(parseInt(array[3], 10));
                        alert(color);
                        var ok = false;
                        for (var j = 1; j < textColors.length; j++) {
                            var c = textColors[j].toUpperCase();
                            if (c == color) {
                                tagName = "span";
                                classAttribute = "textColor" + j;
                                ok = true;
                                break;
                            }
                        }
                    }
                    if (ok) break;
                default:
                    tagName = null;
                    needEndTag = false;
            }
            var html = "";
            if (tagName != null) {
                var elementEditor = richTextAttributeEditor.getElementEditor(tagName);
                if (elementEditor != null) {
                    return elementEditor.convertToXHTML(node, this, isInPre);
                }
                html += "<" + tagName;
                for (var i = 0; i < genericAttributes.length; i++) {
                    var aname = genericAttributes[i];
                    var avalue = node[aname];
                    aname = aname.toLowerCase();

                    if (avalue != null && avalue != "") {
                        avalue = avalue + "";
                        html += " " + aname + "=\"" + avalue.replace(/"/g, "&quot;") + "\"";
                    }
                }
                var align = node.align;
                if (needAlign && align != null && align != "") {
                    if (classAttribute != null) classAttribute += " para" + align;
                    else classAttribute = "para" + align;
                }
                if (href != null) {
                    html += " href=\"" + href.replace(/"/g, "&quot;") + "\"";
                }
                if (classAttribute != null) {
                    html += " class=\"" + classAttribute + "\"";
                }
                if (needEndTag) {
                    html += ">";
                    endTag = "</" + tagName + ">";
                } else {
                    html += "/>";
                }
            }
            if (!skipChildren) {
                for (var i = 0; i < children.length; i++) {
                    html += this.convertToXHTML(children[i], isInPre || tagName == "pre");
                }
            }
            return html + endTag;
            break;
        case 3:
            var text = node.nodeValue;
            if (text.indexOf("<!--") >= 0) text = this.removeComments(text);
            return this.convertToXHTMLtext(text, isInPre);
        default:
            return "";
    }
}
RichTextControl.prototype.removeComments = function(text)
{
	var res = "";
	var pos1 = text.indexOf("<!--");
	var pos2 = text.indexOf("-->");
	while(pos1 >= 0 && pos2 >= pos1 + 4) {
		if(pos1 > 0) res += text.substr(0, pos1);
		text = text.substr(pos2 + 3);
		pos1 = text.indexOf("<!--");
		pos2 = text.indexOf("-->");
	}
	return res + text;
}
RichTextControl.prototype.classToElement = { 
underline:"u",
textColor1:"font",
textColor2:"font",
textColor3:"font",
textColor4:"font"
}

RichTextControl.prototype.emptyElements = {br:1}; 
RichTextControl.prototype.genericAttributes = new Array("title", "onclick");

RichTextControl.prototype.convertToHTML = function(node, isInPre)
{
    isInPre = isInPre == true;
    var genericAttributes = this.genericAttributes;
    switch (node.nodeType) {
        case 1:
            var children = node.childNodes;
            var endTag = "";
            var tagName = node.tagName.toLowerCase();
            var needEndTag = true;
            var skipChildren = false;
            var href = null;
            var colorAttribute = null;
            var className = null;
            var attributeString = "";
            switch (tagName) {
                case "script":
                case "applet":
                case "object":
                case "noscript":
                    tagName = null;
                    skipChildren = true;
                    break;
                case "br":
                    needEndTag = false;
                    break;
                case "img":
                    needEndTag = false;
                    break;
                case "a":
                    href = node.href;
                    if (href == null || href == "") {
                        tagName = null;
                    }
                    break;
                case "span":
                    var className = node.className;
                    tagName = this.classToElement[className];
                    if (tagName == null) {
                        tagName = null;
                        needEndTag = false;
                        skipChildren = true;
                        break;
                    }
                    if (tagName == "font") {
                        var colorNumber = parseInt(className.substr(className.length - 1), 10);
                        colorAttribute = textColors[colorNumber];
                        if (colorAttribute == null) {
                            tagName = null;
                            needEndTag = false;
                            skipChildren = true;
                            break;
                        }
                        attributeString += " color=\"" + colorAttribute + "\"";
                    }
                    break;
                case "table":
                    return objTableEditor.convertToHTML(node, this, false);
                default:
                    className = node.className;
            }
            var html = "";
            if (tagName != null) {
                var elementEditor = richTextAttributeEditor.getElementEditor(tagName);
                if (elementEditor != null) {
                    return elementEditor.convertToHTML(node, this, isInPre, false);
                }
                var outerHTML = null;
                for (var i = 0; i < genericAttributes.length; i++) {
                    var aname = genericAttributes[i];
                    var avalue = node[aname];
                    aname = aname.toLowerCase();
                    if (avalue != null) {
                        avalue = avalue + "";
                        attributeString += " " + aname + "=\"" + avalue.replace(/"/g, "&quot;") + "\"";
                    }
                }
                if (className != null) {
                    if (className.indexOf("paraleft") >= 0 || className.indexOf("bsParaleft") >= 0) {
                        attributeString += " align=\"left\"";
                    } else if (className.indexOf("paracenter") >= 0 || className.indexOf("bsParacenter") >= 0) {
                        attributeString += " align=\"center\"";
                    } else if (className.indexOf("pararight") >= 0 || className.indexOf("bsPararight") >= 0) {
                        attributeString += " align=\"right\"";
                    } else if (className.indexOf("parajustify") >= 0 || className.indexOf("bsParajustify") >= 0) {
                        attributeString += " align=\"justify\"";
                    }
                }
                html += "<" + tagName + attributeString;
                if (needEndTag) {
                    html += ">";
                    endTag = "</" + tagName + ">";
                } else {
                    html += "/>";
                }
            }
            if (!skipChildren) {
                for (var i = 0; i < children.length; i++) {
                    html += this.convertToHTML(children[i], isInPre || tagName == "pre", false);
                }
            }
            return html + endTag;
            break;
        case 3:
            return this.convertToXHTMLtext(node.nodeValue, isInPre);
        default:
            return "";
    }
}

function LinkEditor(control, linkElement)
{
	this._control = control;
	var rng = this._rng = control.setRange();
	this._linkElements = new Array();
	if(linkElement != null) {
		this._linkElements[this._linkElements.length] = linkElement;
	} else {
		if(rng != null) {
			try {
				var parentElement = document.all ? rng.parentElement() : rng.commonAncestorContainer;
				if(!document.all && parentElement.nodeType == 3) parentElement = parentElement.parentNode;
				this._findA(parentElement, rng, this._linkElements);
				this._rng = rng;
			} catch(e) {
				var tag = rng.item(0);
				var ancestor = tag;
				while(ancestor != null) {
					if(ancestor.tagName.toLowerCase() == "a") {
						this._linkElements[this._linkElements.length] = ancestor;
						break;
					}
					ancestor = ancestor.parentNode;
				}
				this._content = tag.outerHTML;


			}
		}
	}
	if(this._linkElements.length > 0) {
		var linkElement = this._linkElements[0];
		this._url = linkElement.href;
		this._title = linkElement.title;
		this._onClickOptions = linkElement.onclick;
		this._mode = "edit";
	} else {
		this._url = "";
		this._title = "";
		this._onClickOptions = null;
		this._mode = "create";
	}
}

LinkEditor.prototype._findA = document.all ? function(node, range, results)
{
	if(node.nodeType != 1) return;
	if(node.tagName == "A") {
		var r = range.duplicate();
		r.moveToElementText(node);
		if(r.compareEndPoints("StartToEnd", range) == -1 && r.compareEndPoints("EndToStart", range) == 1) {
			results[results.length] = node;
			return;
		}
	}
	var children = node.childNodes;
	for(var i=0;i<children.length;i++) {
		var child = children.item(i);
		var link = this._findA(child, range, results);
		if(link != null) {
			results[results.length] = link;
		}
	}
} 
: 
function(node, range, results)
{
	if(node.nodeType != 1) return;
	if(node.tagName == "A") {
		var r = range.cloneRange();
		r.selectNodeContents(node);
		if(r.compareBoundaryPoints(Range.START_TO_END, range) == 1 && r.compareBoundaryPoints(Range.END_TO_START, range) == -1) {
			results[results.length] = node;
			return;
		}
	}
	var children = node.childNodes;
	for(var i=0;i<children.length;i++) {
		var child = children.item(i);
		var link = this._findA(child, range, results);
		if(link != null) {
			results[results.length] = link;
		}
	}
}

LinkEditor.prototype.getMode = function()
{
	return this._mode;
}

LinkEditor.prototype.getUrl = function()
{
	return this._url;
}

LinkEditor.prototype.setUrl = function(url)
{
	this._url = url;
}

LinkEditor.prototype.getTitle = function()
{
	return this._title;
}

LinkEditor.prototype.setTitle = function(title)
{
	this._title = title;
}

LinkEditor.prototype.getOnClickOptions = function()
{
	return this._onClickOptions;
}

LinkEditor.prototype.setOnClickOptions = function(onClickOptions)
{
	this._onClickOptions = onClickOptions;
}

LinkEditor.prototype.commit = function()
{
	if(this._linkElements.length > 0) {
		if(this._url == null) { // remove link
			this._control.executeCommand("Unlink")
		} else {
			for(var i=0;i<this._linkElements.length;i++) {
				var linkElement = this._linkElements[i];
				linkElement.href = this._url;
				linkElement.title = this._title;
				if(this._onClickOptions == null) {
					linkElement.target = "_self";
					linkElement.onclick = null;
				} else {
					var target = linkElement.target;
					target = linkElement.target = "_blank";
					linkElement.onclick = 'return opennewwindow(this, "' + this._onClickOptions + '", "' + target + '")';
				}

			}
		}
	} else {
		/*
		var html = '<a href="' + this._url.replace(/"/g, "&quot;") + '" title="' + this._title.replace(/"/g, "&quot;") + '"';
		if(this._onClickOptions != null) {
			var target = "w" + new Date().getTime();
			html += ' onclick="return opennewwindow(this,\'' + this._onClickOptions + '\', \'_blank\');" target="_blank"';
		}
		html += ">";
		html += this._content;
		html += "</a>";
		this._control.insertHTML(html);
		*/
		if(document.all) {
			this._rng.execCommand("createLink", false, this._url);
		} else {
			var doc = this._rng.commonAncestorContainer.ownerDocument;
			var a = doc.createElement("a");
			a.href = this._url;
			this._rng.surroundContents(a);
		}
		//this._rng = control.setRange();
		this._linkElements = new Array();
		if(typeof(this._rng.length) == "number") {
			var done = {};
			for(var i=0;i<this._rng.length;i++) {
				var a = this._rng.item(i).parentNode;
				while(a && a.nodeType == 1 && a.tagName != "A") a = a.parentNode;
				if(done[a.sourceIndex]) continue;
				done[a.sourceIndex] = 1;
				this._linkElements[this._linkElements.length] = a;
			}
		} else {
			var parentElement = document.all ? this._rng.parentElement() : this._rng.commonAncestorContainer;
			if(!document.all) if(parentElement.nodeType == 3) parentElement = parentElement.parentNode;
			this._findA(parentElement, this._rng, this._linkElements);
		}
		for(var i=0;i<this._linkElements.length;i++) {
			var linkElement = this._linkElements[i];
			linkElement.href = this._url;
			linkElement.title = this._title;
			if(this._onClickOptions == null) {
				linkElement.target = null;
				linkElement.onclick = null;
			} else {
				var target = linkElement.target;
				if(target == null || target == "") {
					target = linkElement.target = "_blank";
				}
				linkElement.onclick = 'return opennewwindow(this, "' + this._onClickOptions + '", "' + target + '")';
			}
		}
	}
}

function ImageEditor(control, providerUrl, fromAttributePanel, isPublic)
{
	this._fromAttributePanel = fromAttributePanel;
	this._control = control;
	this._providerUrl = providerUrl;
	this._isPublic = isPublic;
	var rng = control.setRange();
	this._imageElement = null;
	this._url = "";
	if(rng != null) {
		if (isIE) {
			this._content = rng.htmlText;
			var parent = null;
			if(typeof(rng.length) == "number") {
				this._imageElement = rng.item(0);
			} else {
				this._imageElement = this._findFirstIMG(rng.parentElement(), rng);
			}
		} else {
			this._content = rng.toString();
			this._imageElement = this._findFirstIMG(rng.commonAncestorContainer, rng);
		}
	}
	if(this._imageElement != null) {
		this._url = this._imageElement.src;
		this._title = this._imageElement.title;
		this._width = this._imageElement.width;
		this._height = this._imageElement.height;
		this._align = this._imageElement.align;
		this._mode = "edit";
	} else {
		this._url = "";
		this._title = "";
		this._width = "";
		this._height = "";
		this._align = "";
		this._onClickOptions = null;
		this._mode = "create";
	}
}

ImageEditor.prototype._splitId = function(id) {
    var map = {};
    var params = id.split(",");
    for (var i = 0; i < params.length; i++) {
        var pair = params[i].split(":");
        map[pair[0]] = pair[1];
    }
    map.oid = map.oid || map.image || map.private_image;
    return map;
}

ImageEditor.prototype.init = function()
{
    if (this._input) this._url = this._input.value;
    if (this._imageElement && this._imageElement.id != "")
	{
        var map = this._splitId(this._imageElement.id);
        this._oid = map.oid;
        this._filename = map.f;
        this._hasFrames = map.f != null;
    }
	else if (this._providerUrl != null && this._url != "")
	{
        var pos = this._url.indexOf("?");
        var str = this._url.substr(pos + 1);
        var pairs = str.split("&");
        var map = new Object();
        for (var i = 0; i < pairs.length; i++)
		{
            var pair = pairs[i];
            var pos = pair.indexOf("=");
            var name = pair.substr(0, pos);
            var value = unescape(pair.substr(pos + 1));
            map[name] = value;
        }
        this._oid = map.oid || map.image || map.private_image;
        this._filename = map.f;
        this._hasFrames = map.f != null;
    }
	else
	{
        this._oid = null;
        this._filename = null;
        this._hasFrames = false;
	}
}

ImageEditor.prototype.setInput = function(input)
{
	this._input = input;
}

ImageEditor.prototype._findFirstIMG = document.all ? 
function(node, range)
{
	if(node.nodeType != 1) return;
	if(node.tagName == "IMG") {
		var r = range.duplicate();
		r.moveToElementText(node);
		if(r.compareEndPoints("StartToEnd", range) == -1 && r.compareEndPoints("EndToStart", range) == 1) return node;
	}
	var children = node.childNodes;
	for(var i=0;i<children.length;i++) {
		var child = children.item(i);
		var img = this._findFirstIMG(child, range);
		if(img != null) return img;
	}
}
:
function(node, range)
{
	if(node.nodeType != 1) return;
	if(node.tagName == "IMG") {
		var r = range.cloneRange();
		r.selectNodeContents(node);
		if(r.compareBoundaryPoints(Range.START_TO_END, range) == 1 && r.compareBoundaryPoints(Range.END_TO_START, range) == -1) return node;
	}
	var children = node.childNodes;
	for(var i=0;i<children.length;i++) {
		var child = children.item(i);
		var img = this._findFirstIMG(child, range);
		if(img != null) return img;
	}
}

ImageEditor.prototype.isCalledFromAttributePanel = function()
{
	return this._fromAttributePanel;
}

ImageEditor.prototype.getMode = function()
{
	return this._mode;
}

ImageEditor.prototype.getUrl = function()
{
	return this._url;
}

ImageEditor.prototype.setUrl = function(url) {
    this._url = url;
    this._oid = null;
    this._filename = null;
    this._hasFrames = false;
}

ImageEditor.prototype.getOid = function()
{
	return this._oid;
}

ImageEditor.prototype.setOid = function(oid)
{
    this._oid = oid;
    this._url = null;
    this._title = "";
    this._longdesc = "";
    this._filename = null;
    this._hasFrames = false;
}

ImageEditor.prototype.getTitle = function()
{
	return this._title;
}

ImageEditor.prototype.setTitle = function(title)
{
	this._title = title;
}

ImageEditor.prototype.getWidth = function()
{
	return this._width;
}

ImageEditor.prototype.setWidth = function(width)
{
	this._width = width;
}

ImageEditor.prototype.getHeight = function()
{
	return this._height;
}

ImageEditor.prototype.setHeight = function(height)
{
	this._height = height;
}

ImageEditor.prototype.getLongdesc = function()
{
	return this._longdesc;
}

ImageEditor.prototype.setLongdesc = function(longdesc)
{
	this._longdesc = longdesc;
}

ImageEditor.prototype.setDescription = function(descr)
{
    this._oid = descr.oid;
    this._title = descr.label;
    this._width = descr.width;
    this._height = descr.height;
    this._longdesc = descr.longdesc;
    this._filename = descr.filename+descr.extension;
    var frames = parseInt(descr.frames, 10);
    if (isNaN(frames)) frames = 1;
    if (frames < 1) frames = 1;
    this._hasFrames = frames > 1;
}

ImageEditor.prototype.commit = function()
{
    var word = this._isPublic ? "image" : "private_image";
    var url = (this._oid != null) ? this._providerUrl + "?" + word + "=" + this._oid +
        (this._hasFrames ? "&f=" + this._filename : "") : this._url;
    if (this._input != null)
	{
        this._input.value = url;
    }
	else
	{
        url = fixUrl(url);
        var id = word + ":" + this._oid;
        if (this._hasFrames) id += ",f:" + this._filename;
        if (this._imageElement)
		{
            this._imageElement.src = url;
            this._imageElement.alt = this._imageElement.title = this._title;
            if (this._height != "") {
                this._imageElement.height = this._height;
            }
            if (this._width != "") {
                this._imageElement.width = this._width;
            }
            this._imageElement.longdesc = this._longdesc;
            this._imageElement.id = id;
        }
		else
		{
            var html = '<img id="' + id + '" src="' + url.replace(/"/g, "&quot;") + '" title="' + this._title.replace(/"/g, "&quot;") + '"';
            if (this._height != "") {
                html += ' height="' + this._height + '"';
            }
            if (this._width != "") {
                html += ' width="' + this._width + '"';
            }
            html += " align='left'";
            html += " alt=\"" + this._title.replace(/"/g, "&quot;") + "\"";
            html += " title=\"" + this._title.replace(/"/g, "&quot;") + "\"";
            html += " longdesc=\"" + this._longdesc.replace(/"/g, "&quot;") + "\"";
            html += "/>";
            this._control.insertHTML(html);
        }
    }
}

function processSelectedImageForRichText(descr)
{
	var imagePath = imageProviderUrl + "?oid=" + descr.oid;
	currentRichTextControl.executeCommand('InsertImage', imagePath);
}

function insertHTML(html) 
{
	currentRichTextControl.insertHTML(html);
}

function showHideElement(element, showHide) {
	//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";
	} else if (showHide == "hide") {
		element.style.visibility = "hidden";
	}
}

function stripHTML(oldString) {
	//function to strip all html
	var newString = oldString.replace(/(<([^>]+)>)/ig,"");
	
	//replace carriage returns and line feeds
   newString = newString.replace(/\r\n/g," ");
   newString = newString.replace(/\n/g," ");
   newString = newString.replace(/\r/g," ");
	
	//trim string
	newString = trim(newString);
	
	return newString;
}

function trim(inputString) {
   // Removes leading and trailing spaces from the passed string. Also removes
   // consecutive spaces and replaces it with one space. If something besides
   // a string is passed in (null, custom object, etc.) then return the input.
   if (typeof inputString != "string") return inputString;
   var retValue = inputString;
   var ch = retValue.substring(0, 1);
	
   while (ch == " ") { // Check for spaces at the beginning of the string
      retValue = retValue.substring(1, retValue.length);
      ch = retValue.substring(0, 1);
   }
   ch = retValue.substring(retValue.length - 1, retValue.length);
	
   while (ch == " ") { // Check for spaces at the end of the string
      retValue = retValue.substring(0, retValue.length - 1);
      ch = retValue.substring(retValue.length - 1, retValue.length);
   }
	
	// Note that there are two spaces in the string - look for multiple spaces within the string
   while (retValue.indexOf("  ") != -1) {
		// Again, there are two spaces in each of the strings
      retValue = retValue.substring(0, retValue.indexOf("  ")) + retValue.substring(retValue.indexOf("  ") + 1, retValue.length);
   }
   return retValue; // Return the trimmed string back to the user
}

//********************
//Gecko-Only Functions
//********************
function geckoKeyPress(evt) {
	//function to add bold, italic, and underline shortcut commands to gecko RTEs
	//contributed by Anti Veeranna (thanks Anti!)
	var id = 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) {
			rteCommand(id, cmd, null);
			
			// stop the event bubble
			evt.preventDefault();
			evt.stopPropagation();
		}
 	}
}

function geckoContextMenu(ev) 
{
	var element = ev.target;
	var parent = element.parentNode;
	while(parent != null && parent.nodeType == 1 && parent.tagName != "BODY") {
		parent = parent.parentNode;
	}
	if(parent == null || parent.tagName != "BODY") return;
	var id = parent.id.replace("body_","");
	richTextStopEvent(ev);
	var control = getRichTextControl(id);
	richTextAttributeEditor.showMenu(element, control, ev);
}


function geckoClick(evt) 
{

}
//*****************
//IE-Only Functions
//*****************
function ieKeyPress(evt, id) {
	var key = (evt.which || evt.charCode || evt.keyCode);
	var stringKey = String.fromCharCode(key).toLowerCase();
//the following breaks list and indentation functionality in IE (don't use)
//	switch (key) {
//		case 13:
//			//insert <br> tag instead of <p>
//			//change the key pressed to null
//			evt.keyCode = 0;
//			
//			//insert <br> tag
//			currentRichTextControl = id;
//			insertHTML('<br>');
//			break;
//	};
}
function iePanelKeyPress(evt, id) 
{
	alert("iePanelKeyPress");
	// hide on ESC
	if(evt.keyCode != 27) return;
	var control = getRichTextControl(id);
	control.hideMenu();
	control.hideColorMenu();
	control.hidePanel();
}
function ieClick(evt, id)
{
	var control = getRichTextControl(id);
	control.hideMenu();
	control.hideColorMenu();
	control.hidePanel();
}

function iePaste(evt, id) 
{
	var control = getRichTextControl(id);
	control.paste(evt);
}
function raiseButton(e) {
	var el = window.event.srcElement;
	if(el == null) return;
	var className = el.className;
	if (className == 'rteImage' || className == 'rteImageLowered') {
		el.className = 'rteImageRaised';
	}
}

function normalButton(e) {
	var el = window.event.srcElement;
	if(el == null) return;
	var className = el.className;
	if (className == 'rteImageRaised' || className == 'rteImageLowered') {
		el.className = 'rteImage';
	}
}

function lowerButton(e) {
	var el = window.event.srcElement;
	if(el == null) return;
	
	var className = el.className;
	if (className == 'rteImage' || className == 'rteImageRaised') {
		el.className = 'rteImageLowered';
	}
}

function richTextStopEvent (ev) 
{
	ev || (ev = window.event);
	if (document.all != null) {
		ev.cancelBubble = true;
		ev.returnValue = false;
	} else {
		ev.preventDefault();
		ev.stopPropagation();
	}
	return false;
};

function richTextGetElement(ev) 
{
	if (document.all != null) {
		return ev.srcElement;
	} else {
		return ev.currentTarget;
	}
}

function evt_oncontextmenu(ev, id)
{
	ev || (ev = frames[id].document.window.event);
	var element = richTextGetElement(ev);
	richTextStopEvent(ev);
	var control = getRichTextControl(id);
	richTextAttributeEditor.showMenu(element, control, ev);
}

function evt_ondrop(ev, id)
{
	ev || (ev = frames[id].document.window.event);
	var element = richTextGetElement(ev);
	var ancestor = element;
	var inPara = false;
	while(ancestor != null && ancestor.nodeType == 1) {
		switch(ancestor.tagName) {
		case "P":
		case "DIV":
			inPara = true;
			break;
		case "TABLE":
			var text = ev.dataTransfer.getData("text");
			var control = getRichTextControl(id)
			if(!inPara) text = "<p>" + control.convertToXHTMLtext(text, false) + "<p>";
			control.insertHTML(text);
			richTextStopEvent(ev);
			return;

		}
		ancestor = ancestor.parentElement;
	}
}


function updateRTEs() {
	for (var i = 0; i < allRTEs.length; i++) {
		allRTEs[i].updateControl();
	}
}

function getRichTextControl(id)
{
	return eval("rt" + id);
}

function rteCommand(id, command, option)
{
	var control = getRichTextControl(id);
	if(control != null) control.executeCommand(command, option);
}



function RichTextAttributeEditor()
{
}


function DimensionAttributeEditor(name, label, required)
{
	this._name = name;
	this._styleName = name;
	this._label = objThesaurus.translate(label).replace(/ /g, "\240");
	this._required = required;
}

DimensionAttributeEditor.prototype.getName = function()
{
	return this._name;
}

DimensionAttributeEditor.prototype.getValue = function(element)
{
	var value = element[this._name];
	if(value == 0 && document.all) {
		value = element.currentStyle[this._name];
	}
	return value;
}

DimensionAttributeEditor.prototype.setValue = function(element, value)
{
	if(value == null) value = "";
	else value = value + "";
	if(value == "auto") value = "";
	if(value == "" && this._required) {
		element.removeAttribute(this._name, true);
		element.style[this._name] = "";
		return;
	}
	var regExp = /^(\d+)(%|px|pc|pt|mm|cm|in|em|pc|ex)?/;
	var array = regExp.exec(value);
	var unit = "";
	var n;
	if(array != null) {
		n = parseInt(array[1], 10);
		value = n;
		var unit = array[2];
		if(unit == "") unit = "px";
		value += unit;
	} else {
		value = "";
	}
	if(this._required) {
		if(!isNaN(n)) {
			element[this._name] = n;
		} else {
			element.removeAttribute(this._name, true);
		}
		element.style[this._name] = "";
	} else {
		element[this._name] = value;
		element.style[this._name] = "";
	}
}

DimensionAttributeEditor.prototype._units = new Array("%", "px", "pc", "pt", "mm", "cm", "in", "em", "pc", "ex");

DimensionAttributeEditor.prototype.getControlMarkup = function(element, inputName)
{
	var value = this.getValue(element);
	var isSet = false;
	var n = "";
	var unit = "auto";
	var regExp = /^(\d+)(%|px|pc|pt|mm|cm|in|em|pc|ex)?/;
	var array = regExp.exec(value);
	if(array != null) {
		n = array[1];
		unit = array[2];
		if(unit == "") unit = "px";
		value += unit;
		isSet = false;
	} else {
		n = "";
	}
	var html = "<td class='attributeLabel'><label for='" + inputName + "'>" + this._label + "</label></td><td class='attributeControlCell'>\n";
	html += "<input type='input' name='" + inputName + "' id='" + inputName + "' value='" + n + "' style='width:30px'/>\n";
	if(!this._required) {
		html += "<select keep='true' name='" + inputName + "_u' id='" + inputName + "_u'>\n";
		for(var i=0;i<this._units.length;i++) {
			var u = this._units[i];
			html += "<option value='" + u + "'" + ((u == unit)?" selected":"") + ">" + this._units[i] + "</option>\n";
		}
		html += "</select>\n";
	} else {
		html += "px";
	}
	html += "</td>";
	return html;
}

DimensionAttributeEditor.prototype.commit = function(element, inputName)
{
	var input = document.getElementById(inputName);
	var n = parseInt(input.value);
	if(!isNaN(n)) {
		var value = n
		if(!this._required) {
			var select = document.getElementById(inputName + "_u");
			var unit = select.value;
			if(unit != "auto") {
				value += unit;
			} else {
				value = unit;				
			}
		} else {
			value += "px";
		}
		this.setValue(element, value);
	} else if(this._required) {
		this.setValue(element, "");
	}
}

DimensionAttributeEditor.prototype.getHTMLMarkup = function(element, elementEditor, needNormalize)
{
	var html = "";
	var value = this.getValue(element);
	//elementEditor.addStyle(this._styleName, value);
	html += elementEditor.formatAttribute(this._name, value);
	return html;
}

DimensionAttributeEditor.prototype.getXHTMLMarkup = function(element, elementEditor, control)
{
	var html = "";
	var value = this.getValue(element);
	//elementEditor.addStyle(this._styleName, value);
	html += elementEditor.formatAttribute(this._name, value);
	return html;
}

function AlignAttributeEditor(name, label, mode)
{
	this._name = name;
	this._styleName = name;
	this._cssName = name;
	this._label = objThesaurus.translate(label).replace(/ /g, "\240");
	this._mode = mode;
	switch(name) {
	case "vAlign":
		this._styleName = "verticalAlign";
		this._cssName = "vertical-align";
		this._items = {
			top:objThesaurus.translate("odf267"), 
			middle:objThesaurus.translate("odf268"), 
			bottom:objThesaurus.translate("odf269")
		};
		this._default = "middle";
		break;
	case "align":
	default:
		this._styleName = "textAlign";
		this._cssName = "text-align";
		this._default = "left";
		switch(mode) {
		case "caption":
			this._items = {
				top:objThesaurus.translate("odf267"), 
				bottom:objThesaurus.translate("odf269")
			};
			this._default = "top";
			break;
		case "para":
			this._items = {
				left:objThesaurus.translate("odf265"), 
				center:objThesaurus.translate("odf28"), 
				right:objThesaurus.translate("odf266"), 
				justify:objThesaurus.translate("odf248")
			};
			break;
		case "img":
			this._items = {
				left:objThesaurus.translate("odf265"),
				right:objThesaurus.translate("odf266"),
				top:objThesaurus.translate("odf267"),
				middle:objThesaurus.translate("odf268"),
				bottom:objThesaurus.translate("odf269")
			}
			break;
		case "cell":
		case "table":
		default:
			this._items = {
				left:objThesaurus.translate("odf265"), 
				center:objThesaurus.translate("odf28"), 
				right:objThesaurus.translate("odf266") 
			};
			break;
		}
		break;
	}
}
AlignAttributeEditor.prototype.getCurrentStyle = function(element)
{
	if(document.all) return element.currentStyle[this._styleName];
	else {
		var style = element.ownerDocument.defaultView.getComputedStyle(element, "");
		if(style == null) return null;
		return style[this._styleName];
	}
}


AlignAttributeEditor.prototype.getName = function()
{
	return this._name;
}

AlignAttributeEditor.prototype.getValue = function(element)
{
	var align;
	if(this._mode == "img") {
		align = element[this._name];
		if(align != "" && align != null) {
			return align;
		}
	}
	var srcClassName = element.className.toLowerCase();
	if(this._mode == "para") {
		var found = false;
		for(var item in this._items) {
			if(srcClassName.indexOf(item) >= 0) {
				align = item;
				found = true;
				break;
			}
		}
		if(found) return align;		
	}
	align = this.getCurrentStyle(element);
	if(align != "" && align != null) {
		return align;
	}
	align = element.style[this._styleName];
	if(align != "" && align != null) {
		return align;
	}
	align = element[this._name];
	if(align != "" && align != null) {
		return align;
	}
	align = this._default;
	var align = this._default;
	var found = false;
	for(var item in this._items) {
		if(srcClassName.indexOf(item) >= 0) {
			align = item;
			found = true;
			break;
		}
	}
	if(!found) alert(this._name + " using default " + align);
	return align;
}

AlignAttributeEditor.prototype.setValue = function(element, value)
{
	if(value == null) value = "";
	else value = value + "";
	value = value.toLowerCase();
	var align = "";
	var item = this._items[value];
	if(item != null) align = value;
	if(isXHTMLEditor) {
		switch(this._mode) {
		case "table":
			element[this._name] = align;
			switch(align) {
			case "left":
				element.style.styleFloat= align;
				element.style.marginRight = "5px";
				element.style.marginLeft = "0px";
				break;
			case "right":
				element.style.styleFloat= align;
				element.style.marginLeft = "5px";
				element.style.marginRight = "0px";
				break;
			default:
				element.style.styleFloat = "none";
				element.style.marginRight = "0px";
				element.style.marginLeft = "0px";
			}
			break;
		case "caption":
		case "para":
		case "img":
			element[this._name] = align;
			break;
		default:
			element.style[this._styleName] = align;
		}
	} else {
		element[this._name] = align;
	}
}

AlignAttributeEditor.prototype.getControlMarkup = function(element, inputName)
{
	var value = this.getValue(element);
	var html = "<td class='attributeLabel'><label for='" + inputName + "'>" + this._label + "</label></td><td class='attributeControlCell'>\n";
	html += "<select keep='true' id='" + inputName + "'>\n";
	for(var k in this._items) {
		var v = this._items[k];
		var selected = (k == value) ? " selected" : "";
		html += "<option value='" + k + "'" + selected + ">" + v + "</option>\n";
	}
	html += "</select>\n";
	html += "</td>";
	return html;
}

AlignAttributeEditor.prototype.commit = function(element, inputName)
{
	var select = document.getElementById(inputName);
	var value = select.value;
	this.setValue(element, value);
}

AlignAttributeEditor.prototype.getHTMLMarkup = function(element, elementEditor, needNormalize)
{
	var html = "";
	var value = this.getValue(element);
	if(isXHTMLEditor) {
		switch(this._mode) {
		case "table":
		case "para":
		case "img":
		case "caption":
			html += elementEditor.formatAttribute(this._name, value);
			break;
		default:
			elementEditor.addStyle(this._cssName, value);
		}
	} else {
		html += elementEditor.formatAttribute(this._name, value);
	}
	return html;
}

AlignAttributeEditor.prototype.getXHTMLMarkup = function(element, elementEditor, control)
{
	var html = "";
	var value = this.getValue(element);
	switch(this._mode) {
	case "table":
	case "img":
		html += elementEditor.formatAttribute(this._name, value);
		break;
	default:
		elementEditor.addClassName("para" + value);
	}
	return html;
}

function TextAttributeEditor(name, label)
{
	this._name = name;
	this._label = objThesaurus.translate(label).replace(/ /g, "\240");
}

TextAttributeEditor.prototype.getName = function()
{
	return this._name;
}

TextAttributeEditor.prototype.getValue = function(element)
{
	return element[this._name];
}

TextAttributeEditor.prototype.setValue = function(element, value)
{
	element[this._name] = value;
}

TextAttributeEditor.prototype.getControlMarkup = function(element, inputName)
{
	var value = this.getValue(element);
	var html = "<td class='attributeLabel'><label for='" + inputName + "'>" + this._label + "</label></td><td class='attributeControlCell'>\n";
	html += "<input class='text' id='" + inputName + "' value='" + value.replace(/"/g, "&quot;") + "'>";
	html += "</td>";
	return html;
}

TextAttributeEditor.prototype.commit = function(element, inputName)
{
	var input = document.getElementById(inputName);
	var value = input.value;
	this.setValue(element, value);
}

TextAttributeEditor.prototype.getHTMLMarkup = function(element, elementEditor, needNormalize)
{
	var html = "";
	var value = this.getValue(element);
	html += elementEditor.formatAttribute(this._name, value);
	return html;
}

TextAttributeEditor.prototype.getXHTMLMarkup = function(element, elementEditor, control)
{
	var html = "";
	var value = this.getValue(element);
	html += elementEditor.formatAttribute(this._name, value);
	return html;
}

function TextAreaAttributeEditor(name, label)
{
	this._name = name;
	this._label = objThesaurus.translate(label).replace(/ /g, "\240");
}

TextAreaAttributeEditor.prototype.getName = function()
{
	return this._name;
}

TextAreaAttributeEditor.prototype.getValue = function(element, value)
{
	if(this._name == "longDesc") return element.getAttribute("longdesc");
	return element[this._name];
}

TextAreaAttributeEditor.prototype.setValue = function(element, value)
{
	element[this._name] = value;
}

TextAreaAttributeEditor.prototype.getControlMarkup = function(element, inputName)
{
	var value = this.getValue(element);
	var html = "<td class='attributeLabel'><label for='" + inputName + "'>" + this._label + "</label></td><td class='attributeControlCell'>\n";
	html += "<textarea class='text' name='" + inputName + "' id='" + inputName + "'>" + value.replace(/</g, "&lt;") + "</textarea>";
	html += "</td>";
	return html;
}

TextAreaAttributeEditor.prototype.commit = function(element, inputName)
{
	var input = document.getElementById(inputName);
	if(input) {
		var value = input.value;
		this.setValue(element, value);
	} else {
		alert("no input " + inputName);
	}
}

TextAreaAttributeEditor.prototype.getHTMLMarkup = function(element, elementEditor, needNormalize)
{
	var html = "";
	var value = this.getValue(element);
	html += elementEditor.formatAttribute(this._name, value);
	return html;
}

TextAreaAttributeEditor.prototype.getXHTMLMarkup = function(element, elementEditor, control)
{
	var html = "";
	var value = this.getValue(element);
	html += elementEditor.formatAttribute(this._name, value);
	return html;
}
function SrcAttributeEditor(name, label)
{
	this._name = name;
	this._label = objThesaurus.translate(label).replace(/ /g, "\240");
}

SrcAttributeEditor.prototype.getName = function()
{
	return this._name;
}

SrcAttributeEditor.prototype.getValue = function(element, value)
{
	return element[this._name];
}

SrcAttributeEditor.prototype.setValue = function(element, value)
{
    element[this._name] = value;
    var pos = value.indexOf("?");
    var search = value.substr(pos + 1);
    element.id = this._buildId(search);
}

SrcAttributeEditor.prototype._buildId = function(search) {
    var params = search.split("&");
    var id = [];
    for (var j = 0; j < params.length; j++) {
        var pair = params[j].split("=");
        var n = pair[0];
        if (n == "oid")
            n = "image";
        id.push(n + ":" + pair[1]);
    }
    return id.join(",");
}

SrcAttributeEditor.prototype.getControlMarkup = function(element, inputName)
{
	var value = this.getValue(element);
	var html = "<td class='attributeLabel'><label for='" + inputName + "'>" + this._label + "</label></td><td class='attributeControlCell'>\n";
	html += "<input type='hidden' id='" + inputName + "' value='" + value.replace(/"/g, "&quot;") + "'>";
	var url = value.replace(/\?.*$/g,"");
	var filename = url.substr(url.lastIndexOf("/") + 1);
	html += "&nbsp;<input type='button' class='narrowBrowseButton' value='...' onclick='richTextAttributeEditor.selectImage(\"" + inputName + "\")'>";
	return html;
}

SrcAttributeEditor.prototype.commit = function(element, inputName) {
	// ISV4-2053 : il manque un effet de bord qui permet de produire la bonne vignette
	var input = document.getElementById(inputName);
	var value = input.value;
	this.setValue(element, value);
}

SrcAttributeEditor.prototype._splitId = function(id) {
    var map = {};
    var params = id.split(",");
    for (var i = 0; i < params.length; i++) {
        var pair = params[i].split(":");
        map[pair[0]] = pair[1];
    }
    map.oid = map.oid || map.image || map.private_image;
    return map;
}

SrcAttributeEditor.prototype.getHTMLMarkup = function(element, elementEditor, needNormalize) {
    var html = "";
    var value = this.getValue(element);
    // 1) makes the URL relative
    var base = document.location.href;
    var pos = base.indexOf("?");
    if (pos > 0) base = base.substr(0, pos);
    pos = base.lastIndexOf("/");
    base = base.substr(0, pos + 1);
    if (base == value.substr(0, base.length)) {
        if (isDiffusion) {
            value = "./" + value.substr(base.length);
        } else {
            value = context.processor.destination.httpURL + value.substr(base.length);
        }
    }
    // 2) uses the element width and height to enrich the image URL
    var id = element.id;
    var pos = value.indexOf("?");
    if (id != "") {
        value = imageProviderUrl + "?" + id.replace(/,/g, "&").replace(/:/g, "=");
        html += elementEditor.formatAttribute("id", id);
    } else if (pos > 0) {
        //using image provider
        var search = value.substr(pos + 1);
        var pairs = search.split("&");
        var params = {};
        for (var j = 0; j < pairs.length; j++) {
            var pair = pairs[j];
            var p = pair.indexOf("=");
            params[pair.substr(0, p)] = unescape(pair.substr(p + 1));
        }
        var id = "";
        if (params.oid != null) {
            id = "image:" + params.oid;
        } else if (params.image != null) {
            id = "image:" + params.image;
        } else {
            id = "private_image:" + params.private_image;
        }
        html += elementEditor.formatAttribute("id", id);
        search = search.replace(/&ew=[0-9]+/, "").replace(/&eh=[0-9]+/, "")
        value = value.substr(0, pos) + "?" + search;
    }
    html += elementEditor.formatAttribute(this._name, value);
    return html;
}

SrcAttributeEditor.prototype.getXHTMLMarkup = function(element, elementEditor, control) 
{
    var html = "";
    var value = this.getValue(element);
    // 1) makes the URL relative
    var base;
    if (isDiffusion) {
        base = document.location.href;
        var pos = base.indexOf("?");
        if (pos > 0) base = base.substr(0, pos);
        pos = base.lastIndexOf("/");
        base = base.substr(0, pos + 1);
    } else {
        base = context.processor.destination.httpURL;
    }
    if (base == value.substr(0, base.length)) {
        value = "./" + value.substr(base.length);
    }
    // 2) uses the element width and height to enrich the image URL
    var pos = value.indexOf("?");
    if (pos > 0) {
        var search = value.substr(pos);
        search = search.replace(/&ew=[0-9]+/, "").replace(/&eh=[0-9]+/, "")
        var w = parseInt(element.width, 10);
        var h = parseInt(element.height, 10);
        if (w == 0 && document.all) {
            w = parseInt(element.currentStyle.width);
        }
        if (h == 0 && document.all) {
            h = parseInt(element.currentStyle.height);
        }
        if (!isNaN(w)) search += "&ew=" + w;
        if (!isNaN(h)) search += "&eh=" + h;
        value = value.substr(0, pos) + search;
    }
    var id = element.id;
    if (id != "") {
        var map = this._splitId(id);
        var pos = uploadUrl.substr(7).indexOf("/") + 7;
        var valueBase = uploadUrl.substr(pos) + "/";
        if (map.f != null) {
            // file specified (animated gif case)
            value = valueBase + map.f;
        }
        else {
			if(!isNaN(w) && !isNaN(h)) {
				control.needThumbnail(map.oid, w, h, value.indexOf("private") >= 0);
			}
            // no file specified : use thumbnail
            //element.src = value;    // force thumbnail
            var pos = uploadUrl.substr(7).indexOf("/") + 7;
            value = valueBase + map.oid + "/t_" + w + "_" + h + ".jpg";
        }
        html += elementEditor.formatAttribute("id", id);
    }
    html += elementEditor.formatAttribute(this._name, value);
    return html;
}
function HrefAttributeEditor(name, label)
{
	this._name = name;
	this._label = objThesaurus.translate(label).replace(/ /g, "\240");
}

HrefAttributeEditor.prototype.getName = function()
{
	return this._name;
}

HrefAttributeEditor.prototype.getValue = function(element)
{
	return element[this._name];
}

HrefAttributeEditor.prototype.setValue = function(element, value)
{
	element[this._name] = value;
}

HrefAttributeEditor.prototype.getControlMarkup = function(element, inputName)
{
	var value = this.getValue(element);
	var html = "<td class='attributeLabel'><label for='" + inputName + "'>" + this._label + "</label></td><td class='attributeControlCell'>\n";
	html += "<input class='text' id='" + inputName + "' value='" + value.replace(/"/g, "&quot;") + "'>";
	html += "</td>";
	return html;
}

HrefAttributeEditor.prototype.commit = function(element, inputName)
{
	var input = document.getElementById(inputName);
	var value = input.value;
	this.setValue(element, value);
}

HrefAttributeEditor.prototype.getHTMLMarkup = function(element, elementEditor, needNormalize)
{
	var html = "";
	var value = this.getValue(element);
	html += elementEditor.formatAttribute(this._name, value);
	return html;
}

HrefAttributeEditor.prototype.getXHTMLMarkup = function(element, elementEditor, control)
{
	var html = "";
	var value = this.getValue(element);
	html += elementEditor.formatAttribute(this._name, value);
	return html;
}

function TableStyleEditor(name, label)
{
	this._name = name;
	this._label = objThesaurus.translate(label).replace(/ /g, "\240");
}

TableStyleEditor.prototype.getName = function()
{
	return this._name;
}

TableStyleEditor.prototype.getValue = function(element, value)
{
	var srcClassName = element.className.toLowerCase();
	var oddEven = srcClassName.indexOf("oddeven") >= 0;
	var transparent = srcClassName.indexOf("transparent") >= 0;
	if(transparent) return "tabTransparentTable";
	return oddEven ? "tabOddEvenTable":"tabStandardTable";
}

TableStyleEditor.prototype.setValue = function(element, value)
{
	element.className = "clear " + value + " tabTable";
}

TableStyleEditor.prototype.getControlMarkup = function(element, inputName)
{
	var items = {tabStandardTable:objThesaurus.translate("odf297"), tabOddEvenTable:objThesaurus.translate("odf298"), tabTransparentTable:objThesaurus.translate("odf757")};
	var value = this.getValue(element);
	var html = "<td class='attributeLabel'><label for='" + inputName + "'>" + this._label + "</label></td><td class='attributeControlCell'>\n";
	html += "<select keep='true' id='" + inputName + "'>";
	for(var v in items) {
		var t = items[v];
		html += "<option value='" + v + "'" + ((v == value)?" selected":"") + ">" + t + "</option>\n";
	}
	html += "</select></td>";
	return html;
}

TableStyleEditor.prototype.commit = function(element, inputName)
{
	var input = document.getElementById(inputName);
	var value = input.value;
	this.setValue(element, value);
}

function ClearEditor(name, label)
{
	this._name = name;
	this._label = objThesaurus.translate(label).replace(/ /g, "\240");
}

ClearEditor.prototype.getName = function()
{
	return this._name;
}

ClearEditor.prototype.normalize = function(value)
{
	return value == "none" ? value : "both";
}

ClearEditor.prototype.getValue = function(element, value)
{
	return this.normalize(element.style.clear);
}

ClearEditor.prototype.setValue = function(element, value)
{
	 element.style.clear = this.normalize(value);
}

ClearEditor.prototype.getControlMarkup = function(element, inputName)
{
	var value = this.getValue(element);
	var html = "<td class='attributeLabel' colspan='2'>\n";
	html += "<input type='checkbox' id='" + inputName + "' value='true'" + (value == "none"? " checked":"") + "/>";
	html += "<label for='" + inputName + "' style='float:none;display:inline;'>" + this._label + "</label>";
	html += "</td>\n";
	return html;
}

ClearEditor.prototype.commit = function(element, inputName)
{
	var input = document.getElementById(inputName);
	var value = input.checked ? "none":"both";
	this.setValue(element, value);
}

ClearEditor.prototype.getHTMLMarkup = function(element, elementEditor, needNormalize)
{
	var value = this.getValue(element);
	if(value != "") elementEditor.addStyle("clear", value);
	return "";
}

ClearEditor.prototype.getXHTMLMarkup = function(element, elementEditor, control)
{
	var html = "";
	var value = this.getValue(element);
	if(value != "") elementEditor.addStyle("clear", value);
	return "";
}

function CellTypeAttributeEditor(name, label)
{
	this._name = name;
	this._label = objThesaurus.translate(label);
}

CellTypeAttributeEditor.prototype.getName = function()
{
	return this._name;
}

CellTypeAttributeEditor.prototype.getValue = function(element, value)
{
	return element.tagName == "TH";
}

CellTypeAttributeEditor.prototype.setValue = function(td, value)
{
	if(value == null) value = "false";
	else value = (value + "") == "true";
	var tagName = td.tagName;
	var targetTagName = value ? "TH": "TD";
	if(tagName == targetTagName) return td;
	var tr = td.parentNode;
	var newTd = tr.ownerDocument.createElement(targetTagName);
	newTd.align = td.align;
	newTd.vAlign = td.vAlign;
	newTd.rowSpan = td.rowSpan;
	newTd.colSpan = td.colSpan;
	newTd.className = value ? "headerCell": "cell";
	tr.insertBefore(newTd, td);
	tr.removeChild(td);
	var child = td.firstChild;
	while(child) {
		td.removeChild(child);
		newTd.appendChild(child);
		child = td.firstChild;
	}
	return newTd;
}

CellTypeAttributeEditor.prototype.getControlMarkup = function(element, inputName)
{
	var value = this.getValue(element);
	var html = "<td class='attributeLabel' colspan='2'>";
	html += "<input type='checkbox' id='" + inputName + "' value='true'" + (value? " checked":"") + "/>";
	html += "<label for='" + inputName + "' style='float:none;display:inline;'>" + this._label + "</label>";
	html += "</td>\n";
	return html;
}

CellTypeAttributeEditor.prototype.commit = function(element, inputName)
{
	var input = document.getElementById(inputName);
	var value = input.checked;
	this.setValue(element, value);
}

RichTextAttributeEditor.prototype._attributeEditors = {
	width:new DimensionAttributeEditor("width", "odf259", false),
	height:new DimensionAttributeEditor("height", "odf260", false),
	imgWidth:new DimensionAttributeEditor("width", "odf259", true),
	imgHeight:new DimensionAttributeEditor("height", "odf260", true),
	tableAlign:new AlignAttributeEditor("align", "odf262", "table"),
	cellAlign:new AlignAttributeEditor("align", "odf262", "cell"),
	cellVAlign:new AlignAttributeEditor("vAlign", "odf270", "cell"),
	captionAlign:new AlignAttributeEditor("align", "odf262", "caption"),
	paraAlign:new AlignAttributeEditor("align", "odf262", "para"),
	imgAlign:new AlignAttributeEditor("align", "odf262", "img"),
	alt:new TextAttributeEditor("alt", "odf257"),
	title:new TextAttributeEditor("title", "odf255"),
	longDesc:new TextAreaAttributeEditor("longDesc", "odf258"),
	src:new SrcAttributeEditor("src", "odf256"),
	href:new HrefAttributeEditor("href", "odf256"),
	onclick:new TextAttributeEditor("onclick", ""),
	tableStyle:new TableStyleEditor("className", "odf296"),
	paraClear:new ClearEditor("style", "odf301"),
	tableClear:new ClearEditor("style", "odf302"),
	cellType:new CellTypeAttributeEditor("tagName", "odf31")
}

RichTextAttributeEditor.prototype.getAttributeEditor = function(name)
{
	return this._attributeEditors[name];
}
RichTextAttributeEditor.prototype.getElementEditor = function(name)
{
	name = name.toUpperCase();
	return this._model[name];
}

var richTextAttributeEditor = new RichTextAttributeEditor();


function HtmlEditorCommand(element,  model)
{
	this.element = element;
	this.model = model;
}
function HtmlElementEditor(name, icon, label, attributeModels)
{
	this.name = name;
	this.isEmpty = name == "IMG";
	this.label = objThesaurus.translate(label).replace(/ /g, "\240");
	this.icon = icon;
	this.attributes = {};
	if(attributeModels != null) {
		for(var i=0;i<attributeModels.length;i++) {
			var name = attributeModels[i];
			var attribute = richTextAttributeEditor._attributeEditors[name];
			if(attribute == null) {
				//alert("missing attribute model " + name);
				continue;
			}
			this.attributes[attribute.getName()] = attribute;
		}
	}
}

HtmlElementEditor.prototype.attributeString = function(str)
{
	str = "" + str;
	return str.replace(/"/g,"&quot;");
}

HtmlElementEditor.prototype.formatAttribute = function(name, value)
{
	if(value == null) return "";
	return " " + name + "=\"" + this.attributeString(value) + "\"";
}

HtmlElementEditor.prototype.formatText = function(str)
{
	if(str == null) return "";
	return str.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
}
HtmlElementEditor.prototype.addStyle = function(name, value)
{
	this.styleValue += name + ":" + value + ";"
}

HtmlElementEditor.prototype.formatStyle = function()
{
	if(this.styleValue == "") return "";
	var html = this.formatAttribute("style", this.styleValue);
	this.styleValue = "";
	return html;
}
HtmlElementEditor.prototype.addClassName = function(className)
{
	if(this.classNameValue != "") this.classNameValue += " ";
	this.classNameValue += className;
}

HtmlElementEditor.prototype.formatClassName = function()
{
	if(this.classNameValue == "") return "";
	var html = this.formatAttribute("class", this.classNameValue);
	this.classNameValue = "";
	return html;
}

HtmlElementEditor.prototype.convertToHTML = function(element, control, isInPre, needNormalize)
{
	var html = "<" + this.name;
	this.styleValue = "";
	this.classNameValue = ""
	for(var aname in this.attributes) {
		var attribute = this.attributes[aname];
		var markup = attribute.getHTMLMarkup(element, this, needNormalize);
		html += markup;
	}
	html +=this.formatStyle();
	html +=this.formatClassName();
	if(this.isEmpty) {
		return html + "/>";
	}
	html += ">";
	var children = element.childNodes;
	var childrenHTML = "";
	for(var i=0;i<children.length;i++) {
		var child = children[i];
		if(needNormalize) {
			childrenHTML += control.normalizeImportedHTML(child, isInPre || this.name == "PRE");
		} else {
			childrenHTML += control.convertToHTML(child,  isInPre || this.name == "PRE", false, false);
		}
	}
	// empty paragraph case (ISV4-1671)
	// => pour recuperer des paragraphes vide sauves en base
	// element.childNodes ne prend pas en compte les textNode : &nbsp;
	if (childrenHTML == "" && this.name.toUpperCase() == "P")
		childrenHTML = "&nbsp;";
	html += childrenHTML;
	html += "</" + this.name + ">";
	return html;
}

HtmlElementEditor.prototype.convertToXHTML = function(element, control, isInPre)
{
	var html = "<" + this.name.toLowerCase();	// ISV4-1217
	this.styleValue = "";
	this.classNameValue = ""
	for(var aname in this.attributes) {
		var attribute = this.attributes[aname];
		html += attribute.getXHTMLMarkup(element, this, control);
	}
	html +=this.formatStyle();
	html +=this.formatClassName();
	if(this.isEmpty) {
		return html + "/>";
	}
	html += ">";
	var children = element.childNodes;
	var childrenHTML = "";
	for(var i=0;i<children.length;i++) {
		var child = children[i];
		childrenHTML += control.convertToXHTML(child,  isInPre || this.name == "PRE");
	}
	// empty paragraph case (ISV4-1671)
	// => pour etre sur de ne pas sauver dans la base des paragraphes vides
	// element.childNodes ne prend pas en compte les textNode : &nbsp;
	if (childrenHTML == "" && this.name.toUpperCase() == "P")
		childrenHTML = "&nbsp;";
	html += childrenHTML;
	html += "</" + this.name.toLowerCase() + ">";	// ISV4-1217
	return html;
}

HtmlElementEditor.prototype.generateMenu = function(richTextAttributeEditor, element)
{
	var html = this.generatePropertyItem(richTextAttributeEditor, element);
	var commands = richTextAttributeEditor.getCommands(element.tagName);
	if(commands != null) {
		for(var i=0;i<commands.length;i++) {
			var command = commands[i];
			html += this.generateCommandItem(richTextAttributeEditor, element, command);
		}
		html += "<div class='odfMenuItemSep'><hr/></div>\n";
	}
	return html;
}

HtmlElementEditor.prototype.generatePropertyItem = function(richTextAttributeEditor, element)
{
	var icon = "";
	if(this.icon != null) {
		icon = "<img align='absbottom' border='0' width='16' height='16' src='iso_icons/odf_button_element_" + this.icon + "'><span style='text-decoration:none'>\240\240</span>"; 
	}
	var code = "richTextAttributeEditor.showAttributes(" + richTextAttributeEditor._menuCommands.length + ");return false;";
	var html = "<div class='odfMenuItem'><a style='text-decoration:none;padding-left: 4px;' onclick='" + code + "' oncontextmenu='" + code + "' href='#'>" + icon + this.label + "</a></div>";
	richTextAttributeEditor._menuCommands[richTextAttributeEditor._menuCommands.length] = new HtmlEditorCommand(element, this);	
	return html;
}

HtmlElementEditor.prototype.generateCommandItem = function(richTextAttributeEditor, element, command)
{
	var icon = command.icon;
	var html = "<div class='odfMenuItem'>";
	var code = "richTextAttributeEditor.showAttributes(" + richTextAttributeEditor._menuCommands.length + ");return false;";
	html += "<a style='text-decoration:none;padding-left: 4px;' href='#' onclick='" + code + "' oncontextmenu='" + code + "'>";
	if(icon) {
		icon = "./iso_icons/odf_button_" + icon + ".gif";
		html += "<img src='" + icon + "' border='0' width='16' height='16'/>";
		if(!command.isFakeElement) html += "<span style='text-decoration:none'>\240\240\240\240\240\240\240\240\240\240</span>";
		else html += "<span style='text-decoration:none'>\240\240</span>";
	}
	html += command.label;
	html += "</a></div>\n";
	richTextAttributeEditor._menuCommands[richTextAttributeEditor._menuCommands.length] = new HtmlEditorCommand(element, command);	
	return html;
}

function HtmlElementLinkEditor(name, icon, label, attributes)
{
	if(name != null) {
		HtmlElementEditor.call(this, name, icon, label, attributes);
	}
}
HtmlElementLinkEditor.prototype = new HtmlElementEditor();
HtmlElementLinkEditor.prototype.showDialog = function(control, element)
{
	control.hideMenu();
	control.showLinkEditorDialog(element);
}

function HtmlTableCommand(name, icon, label, isFakeElement)
{
	this.name = name;
	this.icon = icon;
	this.label = objThesaurus.translate(label).replace(/ /g, "\240");
	this.isFakeElement = isFakeElement == true;
}

HtmlTableCommand.prototype.exec = function(richTextAttributeEditor, control)
{
	objTableEditor.bind(richTextAttributeEditor.elementClick);
	switch(this.name) {
	case "insertRowAfter" :
		objTableEditor.addRow(true);
	    break;
	case "insertRowBefore" :
		objTableEditor.addRow(false);
	    break;
	case "insertColumnAfter" :
		objTableEditor.addColumn(true);
	    break;
	case "insertColumnBefore" :
		objTableEditor.addColumn(false);
	    break;
	case "deleteRow":
		objTableEditor.deleteRow();
		break;
	case "deleteColumn":
		objTableEditor.deleteColumn();
		break;
	case "deleteTable":
		objTableEditor.deleteTable(control);
		break;
	case "incrementColspan":
		objTableEditor.incrementColspan();
		break;
	case "incrementRowspan":
		objTableEditor.incrementRowspan();
		break;
	case "splitCell":
		objTableEditor.splitCell();
		break;
	case "editColumn":
		var column = objTableEditor.getColumnCell();
		if(column == null) return;
		var model = richTextAttributeEditor.getElementEditor(column.tagName);
		if(model == null) return;
		richTextAttributeEditor._currentCommand = new HtmlEditorCommand(column, model);	
		richTextAttributeEditor.showPanel(column, model);
		break;
	default:
		objTableEditor._buildLayout();
		objTableEditor._dropLayout();
		//alert("unknown cmd :" + cmd);		
	}

}

RichTextAttributeEditor.prototype._commands = {
TABLE:[
    new HtmlTableCommand("insertRowBefore", "insert_row_2", "odf280"),
    new HtmlTableCommand("insertRowAfter", "insert_row_1", "odf281"),
    new HtmlTableCommand("insertColumnBefore", "insert_col_1", "odf282"),
    new HtmlTableCommand("insertColumnAfter", "insert_col_2", "odf283"),
    new HtmlTableCommand("deleteRow", "delete_row", "odf284"),
    new HtmlTableCommand("deleteColumn", "delete_col", "odf285"),
    new HtmlTableCommand("deleteTable", "delete_table", "odf286")],
TD:[
	new HtmlTableCommand("incrementColspan", "hjoin", "odf287"),
    new HtmlTableCommand("incrementRowspan", "vjoin", "odf288"),
    new HtmlTableCommand("splitCell", "splitcell", "odf289"),
    new HtmlTableCommand("editColumn", "element_tablecolumn", "odf276", true)],
TH:[
	new HtmlTableCommand("incrementColspan", "hjoin", "odf287"),
    new HtmlTableCommand("incrementRowspan", "vjoin", "odf288"),
    new HtmlTableCommand("splitCell", "splitcell", "odf289"),
    new HtmlTableCommand("editColumn", "element_tablecolumn", "odf276", true)]
}

RichTextAttributeEditor.prototype.getCommands = function(tagName)
{
	return this._commands[tagName];
}


RichTextAttributeEditor.prototype._model = {
	A:new HtmlElementLinkEditor("A", "link.gif", "odf253",["href", "title", "onclick"]),
	IMG:new HtmlElementEditor("IMG", "image.gif", "odf256",["src", "title", "alt", "longDesc", "imgWidth", "imgHeight", "imgAlign"]),
	P:new HtmlElementEditor("P", "para.gif", "odf264", ["title","paraAlign", "paraClear"]),
	DIV:new HtmlElementEditor("DIV", "para.gif", "odf264", ["title", "paraClear"]),
	PRE:new HtmlElementEditor("PRE", "para.gif", "odf29", ["title","paraAlign", "paraClear"]),
	H1:new HtmlElementEditor("H1", "title1.gif", "odf242", ["title", "paraClear"]),
	H2:new HtmlElementEditor("H2", "title1.gif", "odf243", ["title", "paraClear"]),
	H3:new HtmlElementEditor("H3", "title1.gif", "odf244", ["title", "paraClear"]),
	H4:new HtmlElementEditor("H4", "title1.gif", "odf245", ["title", "paraClear"]),
	H5:new HtmlElementEditor("H5", "title1.gif", "odf246", ["title", "paraClear"]),
	H6:new HtmlElementEditor("H6", "title1.gif", "odf247", ["title", "paraClear"]),
	OL:new HtmlElementEditor("OL", "numbered_list.gif", "odf25", ["title"]),
	UL:new HtmlElementEditor("UL", "list.gif", "odf26", ["title"]),
	LI:new HtmlElementEditor("LI", "item.gif", "odf30", ["title"]),
	TABLE:new HtmlElementEditor("TABLE", "table.gif", "odf272", ["width","tableAlign", "tableStyle", "tableClear"]),
	CAPTION:new HtmlElementEditor("CAPTION", "table.gif", "odf290", ["captionAlign"]),
	COL:new HtmlElementEditor("COL", "table.gif", "odf276", ["imgWidth"]),
	TH:new HtmlElementEditor("TH", "tablecell.gif", "odf271", ["cellAlign", "cellVAlign", "cellType"]),
	TD:new HtmlElementEditor("TD", "tablecell.gif", "odf271", ["cellAlign", "cellVAlign", "cellType"])
}

RichTextAttributeEditor.prototype.getOffsetLeft = function(elm)
{
	var mOffsetLeft = elm.offsetLeft;
	var mOffsetParent = elm.offsetParent;
	
	while(mOffsetParent!=null) {
		mOffsetLeft += mOffsetParent.offsetLeft;
		mOffsetParent = mOffsetParent.offsetParent;
	}	
	return mOffsetLeft;
}

RichTextAttributeEditor.prototype.getOffsetTop = function(elm)
{
	var mOffsetTop = elm.offsetTop;
	var mOffsetParent = elm.offsetParent;
	
	while(mOffsetParent!=null) {
		mOffsetTop += mOffsetParent.offsetTop;
		mOffsetParent = mOffsetParent.offsetParent;
	}	
	return mOffsetTop;
}

RichTextAttributeEditor.prototype.resetMenu = function(control)
{
	this._control = control;
	this._menuCommands = new Array();

}


RichTextAttributeEditor.prototype.commitAttributes = function()
{
	this._control.hidePanel();
	var cmd = this._currentCommand;
	var element = cmd.element;
	var model = cmd.model;
	this.removeEvent(this._titleElement, "mousedown", this._dragStart);
	var model = this._model[element.tagName];
	var borderTable=true;
	var tmpFinalCommit='';
	var booladdBorder1=false;
	var tmpValCell='';
	var tmpContenuClick='';
	
	if(model != null) {
		for(var name in model.attributes) {
			var attribute = model.attributes[name];
			var inputName = "rte_" + name + "_" + this._control.getId();;
			attribute.commit(element, inputName);
		}
	}
	this._element = null;
	var panel = document.getElementById("panel_" + this._control);
	if(panel == null) return;
	panel.innerHTML = "";
}

function processSelectedImageForExistingImage(descr)
{
	richTextAttributeEditor.processSelectedImageForExistingImage(descr);
}

RichTextAttributeEditor.prototype.processSelectedImageForExistingImage = function(descr)
{
	var input = document.getElementById(this._inputName);
	var imagePath = imageProviderUrl + "?oid=" + descr.oid;
	input.value = imagePath;
}

RichTextAttributeEditor.prototype.selectImage = function(inputName)
{
	var input = document.getElementById(inputName);
	this._inputName = inputName;
	currentRichTextControl = this._control;
	if(this._control._props.resourcetype == "private") {
		currentRichTextControl = this;
		var imageEditor = window.albumDialogClient = new ImageEditor(this._control, imageProviderUrl, true, false);
		imageEditor.setInput(input);
		imageEditor.init();
		var width = "292"
		var height = "485"
		var leftPos = (screen.availWidth - width) / 2;
		var topPos = (screen.availHeight - height) / 2;
		var options = 'width=' + width + ',height=' + height + ',left=' + leftPos + ',top=' + topPos;
		showModalWindow(albumPrivateDialogUrl, "albumDialog", width, height, window.albumDialogClient);
	} else {
		var imageEditor = window.albumDialogClient = new ImageEditor(this._control, imageProviderUrl, true, true);
		imageEditor.setInput(input);
		imageEditor.init();
		var width = "800";
		var height = "600";
		var leftPos = (screen.availWidth - width) / 2;
		var topPos = (screen.availHeight - height) / 2;
		var options = 'width=' + width + ',height=' + height + ',left=' + leftPos + ',top=' + topPos;
		showModalWindow(albumDialogUrl, "albumDialog", width, height, window.albumDialogClient);
	}
	/*
	var win = window.open(albumDialogUrl, "albumDialog", options);
	win.focus();
	*/

}
RichTextAttributeEditor.prototype.showAttribute = function(name, attribute, element)
{
	var id = this._control;
	var html = "<tr>";
	var value = element[name];
	var inputName = "rte_" + name + "_" + id;
	switch(attribute.t) {
	case "s":
		html += "<td class='attributeLabel'>" + attribute.l + "</td><td class='attributeControlCell'>\n";
		html += "<select keep='true' name='" + inputName + "'>\n";
		for(var k in attribute.v) {
			var v = attribute.v[k];
			if(attribute.l=="Couleur Cadre"){
			var valuePlus= element["className"];
			     if(valuePlus=="cadreComplet")  value = "celement";
			     else value = "police";
			}
			var selected = (k == value) ? " selected" : "";
			html += "<option value='" + k + "'" + selected + ">" + v + "</option>\n";
		}
		html += "</select>\n";
		break;
	case "i":
		html += "<td class='attributeLabel'>" + attribute.l + "</td><td class='attributeControlCell'>\n";
		html += "<input type='hidden' name='" + inputName + "' value='" + value.replace(/"/g, "&quot;") + "'>";
		var url = value.replace(/\?.*$/g,"");
		var filename = url.substr(url.lastIndexOf("/") + 1);
		html += "&nbsp;<input type='button' class='narrowBrowseButton' value='...' onclick='richTextAttributeEditor.selectImage(\"" + inputName + "\")'>";
		break;
	case "b":
		html += "<td colspan='2' class='attributeLabel'>";
		var checked = "";
		if(attribute.v != null) {
			if(attribute.v["true"] == value) {
				checked = " checked";
			}
		} else {
			if(value == "true") checked = " checked";
		}
		html += "<input type='checkbox' name='" + inputName + "'"+ checked +">";
		html += "\240" + attribute.l;
		break;
	case "t":
		if(value == null) value = "";
		else value = "" + value;
		if(value == null) value = "";
		else value = "" + value;		
		if(attribute.l.indexOf("Epaisseur")!=-1) {if(element.style["borderStyle"]){value="0";} } 
		html += "<td class='attributeLabel'>" + attribute.l + "</td><td class='attributeControlCell'>\n";
		html += "<input class='text' name='" + inputName + "' value='" + value.replace(/"/g, "&quot;") + "'>";
		break;
	case "T":
		if(value == null) value = "";
		else value = "" + value;
		html += "<td class='attributeLabel'>" + attribute.l + "</td><td class='attributeControlCell'>\n";
		html += "<textarea class='text' name='" + inputName + "'>" + value.replace(/</g, "&lt;") + "</textarea>";
		break;
	}
	html += "</td></tr>";
	return html;
}

RichTextAttributeEditor.prototype.showAttributes = function(rank)
{
	var cmd = this._currentCommand = this._menuCommands[rank];
	var element = cmd.element;
	var model = cmd.model;
	if(element == null) return;
	if(model == null) return;
	if(model.showDialog != null) return model.showDialog(this._control, element);
	this._control.hideMenu();
	if(model.exec != null) {
		return model.exec(this, this._control);
	}
	this.showPanel(element, model);
}
RichTextAttributeEditor.prototype.showPanel = function(element, model)
{
	var id = this._control.getId();
	var panel = this.panel = document.getElementById("panel_" + id);
	if(panel == null) return;
	var html = "<div class='title'><a onclick='rt" + id + ".hidePanel();return false;' href='#'><img border='0' align='right' src='./iso_icons/dynlib_closewindowbutton.gif'></a>" + model.label + "</div>";
	html += "<table border='0'>";
	var firstInputName = null;
	for(var name in model.attributes) {
		var attribute = model.attributes[name];
		var inputName = "rte_" + name + "_" + id;
		if(firstInputName == null) firstInputName = inputName;
		html += "<tr>";
		html += attribute.getControlMarkup(element, inputName);
		html += this.showAttribute(name, attribute, element);
		html += "</tr>\n";
	}
	html += "</table>";
	html += "<div align='center' style='padding:2px'>"; 
	html += "<input class='richTextOkButton' type='button' value='ok' onclick='richTextAttributeEditor.commitAttributes()'>";
	html += "&nbsp;&nbsp;&nbsp;&nbsp;"
	html += "<input class='richTextCancelButton' type='button' value='Annuler' onclick='rt" + id + ".hidePanel();return false;'>";
	html += "</div>";
	panel.innerHTML = html;
	this._titleElement = panel.firstChild;
	this.addEvent(this._titleElement, "mousedown", this._dragStart);
	var frameDocument = frames[id].document;
	var frameElement = document.getElementById(id);
	var st = panel.style;
	st.left = (this._posX - 36) + "px";
	st.top = (this._posY - 10) + "px";
	this._control.attachPanelEvents();
	panel.className = "richTextPanel";
	this.hideShowCovered();
	if(firstInputName != null) {
		var input = document.getElementById(firstInputName);
		if(input != null) {
			try {
				input.focus();
			} catch(e) {
			}
		}
	}
	return false;
}

RichTextAttributeEditor.prototype.showMenu = function(element, control, ev)
{
	var id = control.getId();
	this.resetMenu(control);
	var menu = document.getElementById("menu_" + id);
	if(menu == null) return alert("no menu");
	var html = "";
	var isTable=false;
	this.elementClick = element;
	for(;element != null && element.nodeType == 1;element = element.parentNode) {
		var model = this._model[element.tagName];
		if(model == null) continue;
		html += model.generateMenu(this, element);
	}
	menu.innerHTML = html;
	var frameDocument = frames[id].document;
	var frameElement = document.getElementById(id);
	var posX = ev.clientX  + control.getPositionLeft(frameElement) + 5;
	var posY = ev.clientY  + control.getPositionTop(frameElement) + 10;
	var absX = ev.clientX  + control.getOffsetLeft(frameElement) + 5;
	var absY = ev.clientY  + control.getOffsetTop(frameElement) + 10;
	var st = menu.style;
	control.attachPanelEvents();
	if(this._menuCommands.length > 0) {
		menu.className = "richTextMenu";
	} else {
		menu.className = "hiddenRichTextMenu";
	}
	var menuWidth = menu.clientWidth;
	var menuHeight = menu.clientHeight;
	try {
		if(absX + menuWidth > window.screen.availWidth - 10 + document.body.parentNode.scrollLeft && posX - menuWidth > 10) {
			posX -= menuWidth + 10;
		}
		if(absY + menuHeight > window.screen.availHeight - 130 + document.body.parentNode.scrollTop) {
			var y = posY -  menuHeight -10;
			if(y > 0) posY = y;
		}
	} catch(e) {
	}
	this._posX = posX;
	this._posY = posY;
	st.left = posX + "px";
	st.top = posY + "px";
	return false;
}

RichTextAttributeEditor.prototype._dragStart = function (ev) 
{
	ev || (ev = window.event);
	var self = richTextAttributeEditor;
	if(self == null) return alert("no self");
	with(self) {
		if (self.dragging) {
			return;
		}
		self.dragging = true;
		var posX;
		var posY;
		if (document.all != null) {
			posY = window.event.clientY + document.body.scrollTop;
			posX = window.event.clientX + document.body.scrollLeft;
		} else {
			posY = ev.clientY + window.scrollY;
			posX = ev.clientX + window.scrollX;
		}
		var st = self.panel.style;
		self.xOffs = posX - parseInt(st.left);
		self.yOffs = posY - parseInt(st.top);
		addEvent(document, "mousemove", calDragIt);
		addEvent(document, "mouseover", stopEvent);
		addEvent(document, "mouseup", calDragEnd);
	}
}

RichTextAttributeEditor.prototype.getAbsolutePos = function(el) {
	var SL = 0, ST = 0;
	var is_div = /^div$/i.test(el.tagName);
	if (is_div && el.scrollLeft)
		SL = el.scrollLeft;
	if (is_div && el.scrollTop)
		ST = el.scrollTop;
	var r = { x: el.offsetLeft - SL, y: el.offsetTop - ST };
	if (el.offsetParent) {
		var tmp = this.getAbsolutePos(el.offsetParent);
		r.x += tmp.x;
		r.y += tmp.y;
	}
	return r;
}

RichTextAttributeEditor.prototype.hideShowCovered = function () 
{
	if(document.all == null) return;
	function getVisib(obj){
		var value = obj.style.visibility;
		if (!value) {
			if (document.defaultView && typeof (document.defaultView.getComputedStyle) == "function") { // Gecko, W3C
				value = document.defaultView.
						getComputedStyle(obj, "").getPropertyValue("visibility");
			} else if (obj.currentStyle) { // IE
				value = obj.currentStyle.visibility;
			} else
				value = '';
		}
		return value;
	};

	var tags = new Array("applet", "iframe1", "select");
	var el = this.panel;

	var p = this.getAbsolutePos(el);
	var EX1 = p.x;
	var EX2 = el.offsetWidth + EX1;
	var EY1 = p.y;
	var EY2 = el.offsetHeight + EY1;

	for (var k = tags.length; k > 0; ) {
		var ar = document.getElementsByTagName(tags[--k]);
		var cc = null;

		for (var i = ar.length; i > 0;) {
			cc = ar[--i];
			if(cc.getAttribute("keep") != null) continue;
			p = this.getAbsolutePos(cc);
			var CX1 = p.x;
			var CX2 = cc.offsetWidth + CX1;
			var CY1 = p.y;
			var CY2 = cc.offsetHeight + CY1;

			if (this.hidden || (CX1 > EX2) || (CX2 < EX1) || (CY1 > EY2) || (CY2 < EY1)) {
				if (!cc.__msh_save_visibility) {
					cc.__msh_save_visibility = getVisib(cc);
				}
				cc.style.visibility = cc.__msh_save_visibility;
			} else {
				if (!cc.__msh_save_visibility) {
					cc.__msh_save_visibility = getVisib(cc);
				}
				cc.style.visibility = "hidden";
			}
		}
	}
}
RichTextAttributeEditor.prototype.calDragIt = function (ev) 
{
	ev || (ev = window.event);
	var self = richTextAttributeEditor;
	if(self == null) return;
	with(self) {
		var posX;
		var posY;
		if (document.all != null) {
			posY = window.event.clientY + document.body.scrollTop;
			posX = window.event.clientX + document.body.scrollLeft;
		} else {
			posX = ev.pageX;
			posY = ev.pageY;
		}
		hideShowCovered();
		var st = panel.style;
		st.left = (posX - self.xOffs) + "px";
		st.top = (posY - self.yOffs) + "px";
		return stopEvent(ev);
	}
}
RichTextAttributeEditor.prototype.calDragEnd = function (ev) {
	ev || (ev = window.event);
	var self = richTextAttributeEditor;
	if(self == null) return;
	with(self) {
		self.dragging = false;

		removeEvent(document, "mousemove", calDragIt);
		removeEvent(document, "mouseover", stopEvent);
		removeEvent(document, "mouseup", calDragEnd);
		self.hideShowCovered();
	}
}

RichTextAttributeEditor.prototype.stopEvent = function(ev) {
	ev || (ev = window.event);
	if (document.all != null) {
		ev.cancelBubble = true;
		ev.returnValue = false;
	} else {
		ev.preventDefault();
		ev.stopPropagation();
	}
	return false;
}

RichTextAttributeEditor.prototype.addEvent = function(el, evname, func) 
{
	if (el.attachEvent) { // IE
		el.attachEvent("on" + evname, func);
	} else if (el.addEventListener) { // Gecko / W3C
		el.addEventListener(evname, func, true);
	} else {
		el["on" + evname] = func;
	}
}

RichTextAttributeEditor.prototype.removeEvent = function(el, evname, func) 
{
	if (el.detachEvent) { // IE
		el.detachEvent("on" + evname, func);
	} else if (el.removeEventListener) { // Gecko / W3C
		el.removeEventListener(evname, func, true);
	} else {
		el["on" + evname] = null;
	}
}

//Objet tableau
function TableEditor(control, providerUrl, fromAttributePanel)
{
    this._fromAttributePanel = fromAttributePanel;
	this._control = control;
	this._providerUrl = providerUrl;
	
}

//Insérer un tableau dans le richtext
TableEditor.prototype.createTable = function(headRows, rows, columns, width, style, align, caption, summary)
{
	var html = objTableEditor.createTable(headRows, rows, columns, width, style, align, caption, summary);
	var oRTE;
	var id = this._control.getId();
	if (document.all) {
		oRTE = frames[id];
	} else {
		oRTE = document.getElementById(id).contentWindow;
	}
	var div = oRTE.document.createElement("DIV");
	div.innerHTML = html;
	var table = div.firstChild;
	div.removeChild(table);
	div = null;
	var selection = document.all ? oRTE.document.selection : oRTE.document.defaultView.getSelection();
	if(true || document.all) {
		if(document.all ? selection.type== "Text" || selection.type== "None" : selection.rangeCount > 0) {
			var oRng = document.all ? selection.createRange() : selection.getRangeAt(0);
			var parentElement = document.all ? oRng.parentElement() : oRng.commonAncestorContainer;;
			var body = oRTE.document.body;
			if(parentElement.tagName == "BODY" || parentElement.ownerDocument != oRTE.document) {
				body.appendChild(table);
				body.appendChild(oRTE.document.createElement("P"));
			} else {
				while(parentElement.parentNode.tagName != "BODY") {
					parentElement = parentElement.parentNode;
				}
				var sibling = parentElement.nextSibling;
				if(sibling != null) {
					parentElement.parentNode.insertBefore(table, sibling);
				} else {
					parentElement.parentNode.appendChild(table);
					parentElement.parentNode.appendChild(oRTE.document.createElement("P"));
				}

			}
		}
	} 
}