/******************************************************************************
* 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.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 += '<div id="div_' + id + '" class="richTextControl" style="width:' + (tablewidth) + 'px">';
			if(this._xhtmlMarkup) {
				h += "<div class='richTextButtonBar' style='width:" + (tablewidth) + "px'><h2>Boutons de commandes</h2><ul>";
			} else {
				h += '<table class="rteBack" cellpadding="0" cellspacing="0" id="Buttons2_' + id + '" width="' + tablewidth + '">';
				h += '	<tr>';
			}
			var needSep = false;
			if(this._hiddenFeatures.style == null) {
				h += this.addButtonCell("bold", "bold.gif", "odf237", "rt" + id + ".executeCommand('bold', '')");
				h += this.addButtonCell("italic", "italic.gif", "odf238", "rt" + id + ".executeCommand('italic', '')");
				h += this.addButtonCell("underline", "underline.gif", "odf21", "rt" + id + ".executeCommand('underline', '')");
				h += this.addButtonCell("forecolor_" + id, "textcolor.gif", "odf239", "rt" + id + ".showColorMenu()", "textcolor");
				if(this._xhtmlMarkup) {
				} else {
					h += "<td>";
				}
				h += '<select style="width:120px" id="formatblock_' + id + '" onchange="rt' + id + '.selectFont(this.id);">\n';
				h += '<option value="">'+objThesaurus.translate("odf240")+'</option>\n';
				h += '<option value="<p>">'+objThesaurus.translate("odf241")+' &lt;p&gt;</option>\n';
				h += '<option value="<pre>">'+objThesaurus.translate("odf22")+' &lt;pre&gt;</option>\n';
				h += '<option value="<h1>">'+objThesaurus.translate("odf242")+' &lt;h1&gt;</option>\n';
				h += '<option value="<h2>">'+objThesaurus.translate("odf243")+' &lt;h2&gt;</option>\n';
				h += '<option value="<h3>">'+objThesaurus.translate("odf244")+' &lt;h3&gt;</option>\n';
				h += '<option value="<h4>">'+objThesaurus.translate("odf245")+' &lt;h4&gt;</option>\n';
				h += '<option value="<h5>">'+objThesaurus.translate("odf246")+' &lt;h5&gt;</option>\n';
				h += '<option value="<h6>">'+objThesaurus.translate("odf247")+' &lt;h6&gt;</option>\n';
				h += '</select>\n';
				if(this._xhtmlMarkup) {
				} else {
					h += "</td>";
				}
				needSep = true;
			}
			if(this._hiddenFeatures.align == null) {
				if(needSep) {
					needSep = false;
					h += this.addSepCell();
				}
				h += this.addButtonCell("left_just", "left_just.gif", "odf23", "rt" + id + ".executeCommand('justifyleft', '')");
				h += this.addButtonCell("centre", "centre.gif", "odf28", "rt" + id + ".executeCommand('justifycenter', '')");
				h += this.addButtonCell("right_just", "right_just.gif", "odf24", "rt" + id + ".executeCommand('justifyright', '')");
				h += this.addButtonCell("justifyfull", "justifyfull.gif", "odf248", "rt" + id + ".executeCommand('justifyfull', '')");
				needSep = true;
			}			
			if(this._hiddenFeatures.list == null) {
				if(needSep) {
					needSep = false;
					h += this.addSepCell();
				}
				h += this.addButtonCell("numbered_list", "numbered_list.gif", "odf25", "rt" + id + ".executeCommand('insertorderedlist', '')");
				h += this.addButtonCell("list", "list.gif", "odf26", "rt" + id + ".executeCommand('insertunorderedlist', '')");
				needSep = true;
			}
			if(this._hiddenFeatures.indent == null) {
				if(needSep) {
					needSep = false;
					h += this.addSepCell();
				}
				h += this.addButtonCell("outdent", "outdent.gif", "odf249", "rt" + id + ".executeCommand('outdent', '')");
				h += this.addButtonCell("indent", "indent.gif", "odf250", "rt" + id + ".executeCommand('indent', '')");
				needSep = true;
			}
			if(this._hiddenFeatures.link == null) {
				if(needSep) {
					needSep = false;
					h += this.addSepCell();
				}
				h += this.addButtonCell("hyperlink", "hyperlink.gif", "odf251", "rt" + id + ".showLinkEditorDialog()");
			}
			if(this._hiddenFeatures.image == null) {
				if(needSep) {
					needSep = false;
					h += this.addSepCell();
				}
				h += this.addButtonCell("image", "image.gif", "odf252", "rt" + id + ".showImageEditorDialog()");
			}
			if(this._hiddenFeatures.table == null) {
				if(needSep) {
					needSep = false;
					h += this.addSepCell();
				}
				h += this.addButtonCell("insert_table", "insert_table.gif", "odf279", "rt" + id + ".dlgInsertTable()");
			}
			if(this._debug) h += this.addButtonCell("debug", "debug.gif", "odf27", "rt" + id + ".showXml()");
			if(this._xhtmlMarkup) {
				h +=  '</ul><br class="clear"/></div>';
			} else {
				h +=  '<td width="100%"></td>';
				h +=  '	</tr>';
				h +=  '</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 += '<a href="#" onclick="return rt' + id + '.changeColor(' + i + ');" class="colorMenuEntry" style="background-color:'+color+';"></a>\n';
			}
			colorMenu += '</div>';
			h +=  colorMenu;
		}
		h +=  '<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>';
		h +=  '<input type="hidden" id="hdn' + id + '" name="' + name + '" value=""/>';
		h +=  '<div id="menu_' + id + '" class="hiddenRichTextMenu"></div>';
		h +=  '<div id="hidden_' + id + '" class="hiddenRichTextMenu"></div>';
		h +=  '<div id="panel_' + id + '" class="hiddenRichTextPanel"></div>';
		h +=  '</div>';
		document.write(h);
		this.loadXHTML(html);
	} else {
		document.writeln('<textarea name="' + id + '" id="' + id + '" style="width: ' + width + 'px; height: ' + height + 'px;">' + html + '</textarea>');
	}
}

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(); 
	}
}


RichTextControl.prototype.paste = function(evt)
{
	var html = this.GetClipboardHTML(this.selectionIsInsideATable());
	this.insertHTML(html);
	return this.stopEvent(evt);
}

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 = "";
	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";
		div.style.width	= 1;
		div.style.height = 1;
		div.style.visibility = "hidden";
		div.style.overflow = "hidden";
		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 + "";
					if(aname == "src") {
						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 == avalue.substr(0,base.length)) {
							avalue = "./" + avalue.substr(base.length);
						}
					}
					var pos = avalue.indexOf("?");
					if(node.tagName.toLowerCase() == "img" && pos > 0) {
						var search = avalue.substr(pos);
						search = search.replace(/&ew=[0-9]+/, "").replace(/&eh=[0-9]+/, "")
						var w = parseInt(node.width, 10);
						var h = parseInt(node.height, 10);
						if(!isNaN(w)) search += "&ew=" + w;
						if(!isNaN(h)) search += "&eh=" + h;
						avalue = avalue.substr(0, pos) + search;
					}
					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:
		return this.convertToXHTMLtext(node.nodeValue, isInPre);
	default:
		return "";
	}
}

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;
			genericAttributes = new Array("src", "align", "border", "width", "height", "title", "alt", "longdesc", "longDesc");
			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 + "";
					switch(aname) {
					case "src":
						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 == avalue.substr(0,base.length)) {
							avalue = "./" + avalue.substr(base.length);
						}
						pos = avalue.indexOf("?");
						if(node.tagName.toLowerCase() == "img") {
							if(pos > 0) {
								//using image provider
								var search = avalue.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)); 
								}
								if(params.oid != null) {
									node.id = "image:" + params.oid;
								} else if(params.image != null) {
									node.id = "image:" + params.image;
								} else {
									node.id = "private_image:" + params.private_image;
								}
								search = search.replace(/&ew=[0-9]+/, "").replace(/&eh=[0-9]+/, "")
								avalue = avalue.substr(0, pos) + "?" + search;
							}
						}
						break;
					case "height":
					case "width":
						if(outerHTML == null) outerHTML = node.outerHTML;
						var regexp = new RegExp(aname + "=(\\d*)","i");
						var array = regexp.exec(outerHTML);
						if(array == null) continue;
						avalue = array[1];
					}
					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.init = function()
{
	if(this._input) this._url = this._input.value;
	if(this._imageElement && this._imageElement.id != "") {
		var pair = this._imageElement.id.split(":");
		this._oid = pair[1]; 
	} 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;
	} else {
		this._oid = null		
	}
}

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;
}

ImageEditor.prototype.getOid = function()
{
	return this._oid;
}

ImageEditor.prototype.setOid = function(oid)
{
	this._oid = oid;
	this._url = null;
	this._title = "";
	this._longdesc = "";
}

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;
}
ImageEditor.prototype.commit = function()
{
	var word = this._isPublic ? "image" : "private_image";
	var url = (this._oid != null) ? this._providerUrl + "?" + word + "=" + this._oid : this._url;
	if(this._input != null) {
		this._input.value = url;
	} else {
		url = fixUrl(url);
		var id = word + ":" + this._oid ;
		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)
{
	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:"Jusitify"
			};
			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 {
		return element.ownerDocument.defaultView.getComputedStyle(element, "")[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;
		}
	}
	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 srcClassName = element.className.toLowerCase();
	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)
{
	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)
{
	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)
{
	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);
	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;
	}
	element.id = id;
}

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)
{
	var input = document.getElementById(inputName);
	var value = input.value;
	this.setValue(element, value);
}

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(/:/, "=");
		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)
{
	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(!isNaN(w)) search += "&ew=" + w;
		if(!isNaN(h)) search += "&eh=" + h;
		value = value.substr(0, pos) + search;
	}
	var id = element.id;
	if(id != "") {
		var pair = id.split(":");
		element.src = value;
		var pos = uploadUrl.substr(7).indexOf("/") + 7;
		value = uploadUrl.substr(pos) + "/" + pair[1] + "/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)
{
	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;
	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")};
	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)
{
	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);
	}
	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"));
				}

			}
		}
	} 
}
