/******************************************************************************
* 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 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 imageProviderUrl;
var linkDialogUrl;

function initRichTextControls(css, textColor1, textColor2, textColor3, textColor4, albumUrl, providerUrl, linkUrl) 
{
	textColors[1] = textColor1;
	textColors[2] = textColor2;
	textColors[3] = textColor3;
	textColors[4] = textColor4;
	albumDialogUrl = albumUrl;
	imageProviderUrl = providerUrl;
	linkDialogUrl = linkUrl;

	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)); 
	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 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 LinkEditor(control)
{
	this._control = control;
	var rng = control.setRange();
	this._linkElement = null;
	if(rng != null) {
		if (isIE) {
			this._content = rng.htmlText;
			this._linkElement = this._findFirstA(rng.parentElement(), rng);
		} else {
			this._content = rng.toString();
			this._linkElement = this._findFirstA(rng.commonAncestorContainer);
		}
	}
	if(this._linkElement != null) {
		this._url = this._linkElement.href;
		this._title = this._linkElement.title;
		this._onClickOptions = this._linkElement.onclick;
		this._mode = "edit";
	} else {
		this._url = "";
		this._title = "";
		this._onClickOptions = null;
		this._mode = "create";
	}
}

LinkEditor.prototype._findFirstA = function(node, range)
{
	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) return node;
	}
	var children = node.childNodes;
	for(var i=0;i<children.length;i++) {
		var child = children.item(i);
		var link = this._findFirstA(child, range);
		if(link != null) return 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._linkElement) {
		if(this._url == null) { // remove link
			this._control.executeCommand("Unlink")
		} else {
			this._linkElement.href = this._url;
			this._linkElement.title = this._title;
			if(this._onClickOptions == null) {
				this._linkElement.target = null;
				this._linkElement.onclick = null;
			} else {
				var target = this._linkElement.target;
				if(target == null || target == "") {
					target = this._linkElement.target = "w" + new Date().getTime();
				}
				this._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 + '\', \'' + target + '\');" target="' + target + '">';
		}
		html += ">";
		html += this._content;
		html += "</a>";
		this._control.insertHTML(html);
	}
}


function ImageEditor(control, providerUrl, fromAttributePanel)
{
	this._fromAttributePanel = fromAttributePanel;
	this._control = control;
	this._providerUrl = providerUrl;
	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);
		}
	}
	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";
	}
	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;
	} else {
		this._oid = null		
	}
}

ImageEditor.prototype.setInput = function(input)
{
	this._input = input;
}


ImageEditor.prototype._findFirstIMG = 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;
	}
}

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 url = (this._oid != null) ? this._providerUrl + "?oid=" + this._oid : this._url;
	if(this._input != null) {
		this._input.value = url;
	} else {
		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;
		} else {
			var html = '<img 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 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;
	
	className = el.className;
	if (className == 'rteImage' || className == 'rteImageLowered') {
		el.className = 'rteImageRaised';
	}
}

function normalButton(e) {
	var el = window.event.srcElement;
	
	className = el.className;
	if (className == 'rteImageRaised' || className == 'rteImageLowered') {
		el.className = 'rteImage';
	}
}

function lowerButton(e) {
	var el = window.event.srcElement;
	
	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 RichTextControl(id, name, width, height, html, debug)
{
	this._id = id;
	this._name = name;
	this._width =  width;
	this._height =  height;
	this._debug = debug == true;
	this.writeRichText(html);
}

RichTextControl.prototype.getId = function() 
{
	return this._id;
}

RichTextControl.prototype.writeRichText = function(html) 
{
	var width = this._width;
	var height = this._height;
	var name = this._name;
	var id = this._id;
	if (isRichText) {
		allRTEs[allRTEs.length] = this;		
		//adjust minimum table widths
		if (width < 380) width = 380;
		if (isIE) {
			var tablewidth = width;
		} else {
			var tablewidth = width + 4;
		}
		document.writeln('<div id="div_' + id + '" class="rteDiv">');
		document.writeln('<table class="rteBack" cellpadding="2" cellspacing="0" id="Buttons1_' + id + '" width="' + tablewidth + '">');
		document.writeln('	<tr>');
		document.writeln('		<td>');
		document.writeln('			<select style="width:120px" id="formatblock_' + id + '" onchange="rt' + id + '.selectFont(this.id);">');
		document.writeln('				<option value="">[Style]</option>');
		document.writeln('				<option value="<p>">Paragraphe &lt;p&gt;</option>');
		document.writeln('				<option value="<pre>">Formaté &lt;pre&gt;</option>');
		document.writeln('				<option value="<h1>">Titre 1 &lt;h1&gt;</option>');
		document.writeln('				<option value="<h2>">Titre 2 &lt;h2&gt;</option>');
		document.writeln('				<option value="<h3>">Titre 3 &lt;h3&gt;</option>');
		document.writeln('				<option value="<h4>">Titre 4 &lt;h4&gt;</option>');
		document.writeln('				<option value="<h5>">Titre 5 &lt;h5&gt;</option>');
		document.writeln('				<option value="<h6>">Titre 6 &lt;h6&gt;</option>');
		document.writeln('			</select>');
		document.writeln('		</td>');
		document.writeln('		<td>');
		document.writeln('		</td>');
		document.writeln('		<td>');
		document.writeln('		</td>');
		document.writeln('		<td width="100%">');
		document.writeln('		</td>');
		document.writeln('	</tr>');
		document.writeln('</table>');
		document.writeln('<table class="rteBack" cellpadding="0" cellspacing="0" id="Buttons2_' + id + '" width="' + tablewidth + '">');
		document.writeln('	<tr>');
		document.writeln('		<td><img id="bold" class="rteImage" src="' + imagesPath + 'bold.gif" width="25" height="24" alt="Gras" title="Gras" onClick="rt' + id + '.executeCommand( \'bold\', \'\')"/></td>');
		document.writeln('		<td><img class="rteImage" src="' + imagesPath + 'italic.gif" width="25" height="24" alt="Italique" title="Italique" onClick="rt' + id + '.executeCommand( \'italic\', \'\')"/></td>');
		document.writeln('		<td><img class="rteImage" src="' + imagesPath + 'underline.gif" width="25" height="24" alt="Souligné" title="Souligné" onClick="rt' + id + '.executeCommand( \'underline\', \'\')"/></td>');
		document.writeln('		<td><img id="forecolor_' + id + '" class="rteImage" src="' + imagesPath + 'textcolor.gif" width="25" height="24" alt="Couleur du texte" title="Couleur du texte" onClick="rt' + id + '.showColorMenu()"/></td>');
		document.writeln('		<td><img class="rteVertSep" src="' + imagesPath + 'blackdot.gif" width="1" height="20" border="0" alt=""/></td>');
		document.writeln('		<td><img class="rteImage" src="' + imagesPath + 'left_just.gif" width="25" height="24" alt="Aligner à gauche" title="Aligner à gauche" onClick="rt' + id + '.executeCommand( \'justifyleft\', \'\')"/></td>');
		document.writeln('		<td><img class="rteImage" src="' + imagesPath + 'centre.gif" width="25" height="24" alt="Centrer" title="Centrer" onClick="rt' + id + '.executeCommand( \'justifycenter\', \'\')"/></td>');
		document.writeln('		<td><img class="rteImage" src="' + imagesPath + 'right_just.gif" width="25" height="24" alt="Aligner à droite" title="Aligner à droite" onClick="rt' + id + '.executeCommand( \'justifyright\', \'\')"/></td>');
		document.writeln('		<td><img class="rteImage" src="' + imagesPath + 'justifyfull.gif" width="25" height="24" alt="Justifier" title="Justifier" onclick="rt' + id + '.executeCommand( \'justifyfull\', \'\')"/></td>');
		document.writeln('		<td><img class="rteVertSep" src="' + imagesPath + 'blackdot.gif" width="1" height="20" border="0" alt=""/></td>');
		document.writeln('		<td><img class="rteImage" src="' + imagesPath + 'numbered_list.gif" width="25" height="24" alt="Liste ordonnée" title="Liste ordonnée" onClick="rt' + id + '.executeCommand( \'insertorderedlist\', \'\')"/></td>');
		document.writeln('		<td><img class="rteImage" src="' + imagesPath + 'list.gif" width="25" height="24" alt="Liste à puces" title="Liste à puces" onClick="rt' + id + '.executeCommand( \'insertunorderedlist\', \'\')"/></td>');
		document.writeln('		<td><img class="rteVertSep" src="' + imagesPath + 'blackdot.gif" width="1" height="20" border="0" alt=""/></td>');
		document.writeln('		<td><img class="rteImage" src="' + imagesPath + 'outdent.gif" width="25" height="24" alt="Diminuer le retrait" title="Diminuer le retrait" onClick="rt' + id + '.executeCommand( \'outdent\', \'\')"/></td>');
		document.writeln('		<td><img class="rteImage" src="' + imagesPath + 'indent.gif" width="25" height="24" alt="Augmenter le retrait" title="Augmenter le retrait" onClick="rt' + id + '.executeCommand( \'indent\', \'\')"/></td>');
		document.writeln('		<td><img class="rteVertSep" src="' + imagesPath + 'blackdot.gif" width="1" height="20" border="0" alt=""/></td>');
		document.writeln('		<td><img class="rteImage" src="' + imagesPath + 'hyperlink.gif" width="25" height="24" alt="Lier" title="Lier" onClick="rt' + id + '.showLinkEditorDialog()"/></td>');
		document.writeln('		<td><img class="rteImage" src="' + imagesPath + 'image.gif" width="25" height="24" alt="Ajouter une image" title="Ajouter une image" onClick="rt' + id + '.showImageEditorDialog()"/></td>');
		//document.writeln('		<td><div id="table_' + id + '"><img class="rteImage" src="' + imagesPath + 'insert_table.gif" width="25" height="24" alt="Insert Table" title="Insert Table" onClick="rt' + id + '.dlgInsertTable(\'table\', \'\')"/></div></td>');
		document.writeln('		<td><img class="rteImage" src="' + imagesPath + 'enlarge.gif" width="25" height="24" alt="Agrandir la zone d\'édition" title="Agrandir la zone d\'édition" onClick="rt' + id + '.enlargeArea()"/></td>');
		if(this._debug) document.writeln('		<td><div id="table_' + id + '"><img class="rteImage" src="' + imagesPath + 'debug.gif" width="25" height="24" alt="Voir le Source" title="Voir le Source" onClick="rt' + id + '.showXml()"/></div></td>');
		document.writeln('		<td width="100%"></td>');
		document.writeln('	</tr>');
		document.writeln('</table>');
		var colorMenu = '<div id="colorMenu_' + id + '" class="hiddenRichTextMenu">\n';
		for(var i=0;i<=4;i++) {
			colorMenu += '<a href="#" onclick="return rt' + id + '.changeColor(' + i + ');" class="colorMenuEntry colorMenuEntry' + i + '"></a>\n';
		}
		colorMenu += '</div>';
		document.writeln(colorMenu);
		document.writeln('<iframe id="' + id + '" name="' + id + '" width="' + width + 'px" height="' + height + 'px" h="' + height + '" src="blank.htm"></iframe>');
		//document.writeln('<iframe width="154" height="104" id="cp' + id + '" src="palette.htm" marginwidth="0" marginheight="0" scrolling="no" style="visibility:hidden; position: absolute;"></iframe>');
		document.writeln('<input type="hidden" id="hdn' + id + '" name="' + name + '" value=""/>');
		document.writeln('<div id="menu_' + id + '" class="hiddenRichTextMenu"></div>');
		document.writeln('<div id="hidden_' + id + '" class="hiddenRichTextMenu"></div>');
		document.writeln('<div id="panel_' + id + '" class="hiddenRichTextPanel"></div>');
		document.writeln('</div>');
		this.loadXHTML(html);
	} else {
		document.writeln('<textarea name="' + id + '" id="' + id + '" style="width: ' + width + 'px; height: ' + height + 'px;">' + html + '</textarea>');
	}
}

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 height = parseInt(document.body.offsetHeight, 10);
		var width = parseInt(document.body.offsetWidth, 10);
		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) {
		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);});		
	} else {
		setTimeout("rt" + id + ".attachEvents()", 1);
	}
}

RichTextControl.prototype.enableDesignMode = function(html) 
{
	var id = this._id;
	var 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) {
		frameHtml += "<link media=\"all\" type=\"text/css\" href=\"" + cssFile + "\" 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 += "<!-- #include virtual="/WebConstantesGlobales/footerIsotools.asp" -->
</body>\n";
	frameHtml += "</html>";
	if (document.all) {
		var oRTE = frames[id].document;
		oRTE.open();
		oRTE.write(frameHtml);
		oRTE.close();
		oRTE.designMode = "On";
		this.attachEvents();
	} else {
		try {
			document.getElementById(id).contentDocument.designMode = "on";
			try {
				var oRTE = document.getElementById(id).contentWindow.document;
				oRTE.open();
				oRTE.write(frameHtml);
				oRTE.close();
				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('" + html + "');", 10);
			} else {
				return false;
			}
		}
	}
}

RichTextControl.prototype.updateControl = function() 
{
	var id = this._id;
	if (!isRichText) return;
	
	//check for readOnly mode
	var readOnly = false;
	if (document.all) {
		if (frames[id].document.designMode != "On") readOnly = true;
	} else {
		if (document.getElementById(id).contentDocument.designMode != "on") 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;
	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" + 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,"&#160;");
	} else {
		text = text.replace(/[ \240]/g,"&#160;");
	}
	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.getOffsetTop(img);
	var left = this.getOffsetLeft(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.hideColorMenu = function() 
{
	var div = document.getElementById('colorMenu_' + this._id);
	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.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) {
		var oRng = oRTE.document.selection.createRange();
		oRng.pasteHTML(html);
		oRng.collapse(false);
		oRng.select();
	} 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;
}

RichTextControl.prototype.dlgInsertTable = function(command)
{
	//function to open/close insert table dialog
	//save current values
	parent.command = command;
	currentRichTextControl = this;
	InsertTable = this.popUpWin('insert_table.htm', 'InsertTable', 360, 180, '');
}

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(url, win, options);
}

RichTextControl.prototype.showLinkEditorDialog = function() 
{
	//function to open/close insert table dialog
	//save current values
	parent.command = "link";
	window.linkDialogClient = new LinkEditor(this);

	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()
{
	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
	currentRichTextControl = this;
	window.albumDialogClient = new ImageEditor(this, imageProviderUrl, false);
	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();
	*/
}

 
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 oRTE;
	if (document.all) {
		oRTE = frames[id];
		return oRTE.document.body.createTextRange(); 
	}
}

RichTextControl.prototype.getReason = function()
{
	return this._reason;
}

RichTextControl.prototype.getName = function()
{
	return this._name;
}

RichTextControl.prototype.getStringValue = function()
{
	var input = document.getElementById(this._id);
	if(input == null) {
		return;
	}
	return input.value;
}

RichTextControl.prototype.isChecked = function()
{
}

RichTextControl.prototype.isDisabled = function()
{
}

RichTextControl.prototype.isReadOnly = function()
{
}

RichTextControl.prototype.checkValue = function()
{
	var input = document.getElementById('hdn' + this._id);
	if(input == null) return true;
	if(input.value != "") {
		return true;
	}
	return false;
}

RichTextControl.prototype.onSubmit = function()
{
	this.updateControl();
	var failurePara = document.getElementById(this._id + "_failure");
	var failureContent = document.getElementById(this._id + "_failure_content");
	if(failurePara == null) return true;
	var message = failureContent.innerHTML;
	if(this.checkValue()) {
		failurePara.style.display = "none";
		return true;
	}
	this._reason = message;
	failurePara.style.display = "block";
	return false;
}

RichTextControl.prototype.paste = function(evt)
{
	var html = this.GetClipboardHTML();
	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()
{
	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);
	}
	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);
	}
	//alert(div.innerHTML + "\n" + html);
	div.innerHTML = '';
	this.enableDesignMode(html);
}

RichTextControl.prototype.getDistanceBetweenColors = function(c1, c2)
{
	var delta = 0;
	for(var i=0;i<3;i++) {
		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)
{
	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;
		case "p":
		case "pre":
		case "ul":
		case "ol":
		case "li":
		case "h1":
		case "h2":
		case "h3":
		case "h4":
		case "h5":
		case "h6":
			needAlign = true;
			break;
		case "strong":
		case "em":
		case "u":
			break;
		case "br":
			needEndTag = false;
			break;
		case "div":
		case "td":	
			tagName = "p"; 
			needAlign = true; 
			break;
		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;
				needEndTag = false;
				break;
			}
			break;
		default:
			tagName = null;
			needEndTag = false;
		}
		var html = "";
		if(tagName != null) {
			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");
			}
		}
		return html + endTag;
		break;
	case 3:
		return this.convertToXHTMLtext(node.nodeValue, isInPre);
	default:
		return "";
	}
}

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 "p":
		case "pre":
		case "ul":
		case "ol":
		case "li":
		case "h1":
		case "h2":
		case "h3":
		case "h4":
		case "h5":
		case "h6":
			needAlign = true;
			break;
		case "strong":
		case "em":
			break;
		case "u":
			tagName = "span";
			classAttribute = "underline";
			break;
		case "img":
			needEndTag = false;
			genericAttributes = new Array("src", "align", "border", "width", "height", "title", "alt", "longdesc", "longDesc");
			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];
				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 "td":	
		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;
		default:
			tagName = null;
			needEndTag = false;
		}
		var html = "";
		if(tagName != null) {
			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);
						}
					}
					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;
			} else {
				attributeString += " href=\"" + href.replace(/"/g, "&quot;") + "\"";				
			}
			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;
		default:
			className = node.className;
		}
		var html = "";
		if(tagName != null) {
			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);
						}
						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) {
					attributeString += " align=\"left\"";
				} else if(className.indexOf("paracenter") >= 0) {
					attributeString += " align=\"center\"";
				} else if(className.indexOf("pararight") >= 0) {
					attributeString += " align=\"right\"";
				} else if(className.indexOf("parajustify") >= 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");
			}
		}
		return html + endTag;
		break;
	case 3:
		return this.convertToXHTMLtext(node.nodeValue, isInPre);
	default:
		return "";
	}
}

function HtmlElementEditor(name, icon, label, attributes)
{
	this.name = name;
	this.label = label;
	this.icon = icon;
	this.attributes = attributes;
}

function HtmlElementLinkEditor(name, icon, label, attributes)
{
	this.name = name;
	this.label = label;
	this.icon = icon;
	this.attributes = attributes;
}

HtmlElementLinkEditor.prototype.showDialog = function(control)
{
	control.showLinkEditorDialog();
}
function RichTextAttributeEditor()
{
}

RichTextAttributeEditor.prototype._model = {
A:new HtmlElementLinkEditor("A", "link.gif", "Lien",{
	href:{l:"Url",t:"t"},
	title:{l:"Info-bulle",t:"t"}}),
IMG:new HtmlElementEditor("IMG", "image.gif",  "Image", {
	src:{l:"Image",t:"i"},
	title:{l:"Info-bulle",t:"t"},
	alt:{l:"Text alternatif",t:"t"},
	longDesc:{l:"Description longue",t:"T"},
	width:{l:"Largeur",t:"t"},
	height:{l:"Hauteur",t:"t"},
	border:{l:"Bord",t:"t"},
	align:{l:"Alignement",t:"s", v:{left:"Gauche",right:"Droite",top:"Haut",middle:"Milieu",bottom:"Bas"}}}),
P:new HtmlElementEditor("P", "para.gif", "Paragraphe", {
	title:{l:"Info-bulle",t:"t"},
	align:{l:"Horizontal",t:"s",v:{left:"Gauche",center:"Centré",right:"Droite"}}}),
DIV:new HtmlElementEditor("DIV", "para.gif", "Paragraphe", {
	title:{l:"Info-bulle",t:"t"},
	align:{l:"Horizontal",t:"s",v:{left:"Gauche",center:"Centré",right:"Droite"}}}),
PRE:new HtmlElementEditor("PRE", "para.gif", "Paragraphe\240formaté", {
	title:{l:"Info-bulle",t:"t"},
	align:{l:"Horizontal",t:"s",v:{left:"Gauche",center:"Centré",right:"Droite"}}}),
LI:new HtmlElementEditor("LI", "item.gif", "Elément\240de\240liste", {
	title:{l:"Info-bulle",t:"t"}}),
TABLE:new HtmlElementEditor("TABLE", "table.gif", "Tableau", {
	className:{l:"Style",t:"s",v:{standard:"normal",oddEven:"pair/impair"}},
	width:{l:"Largeur",t:"t"}}),
TD:new HtmlElementEditor("TD", "tablecell.gif", "Cellule", {
	align:{l:"Horizontal",t:"s",v:{left:"Gauche",center:"Centré",right:"Droite"}},
	vAlign:{l:"Vertical",t:"s",v:{top:"Haut",middle:"Milieu",bottom:"Bas"}},
	className:{l:"Cellule d'en-tête",t:"b",v:{"false":"","true":"titleCell"}}
	})
}
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._menuElements = new Array();
}

RichTextAttributeEditor.prototype.commitAttributes = function()
{
	this._control.hidePanel();
	var element = this._element;
	if(element == null) return;
	this.removeEvent(this._titleElement, "mousedown", this._dragStart);
	var model = this._model[element.tagName];
	if(model != null) {
		for(var name in model.attributes) {
			var attribute = model.attributes[name];
			var inputName = "rte_" + name + "_" + this._control;
			var input = document.getElementById(inputName);
			if(input == null) {
				continue;
			}
			switch(attribute.t) {
			case "s":
				var value = input.options[input.selectedIndex].value;
				break;
			case "b":
				var checked = input.checked;
				if(attribute.v != null) {
					value = attribute.v["" + checked];
				} else {
					value = "" + checked;
				}
				break;
			case "i":
			case "t":
			case "T":
				var value = input.value;
				break;
			}
			if(value != null) {
				if(name == "width" || name == "height") {
					if(value == "") value = "auto";
					element.style[name] = value;
				} else {
					element[name] = value;
				}
			}
		}
	}
	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;
	var imageEditor = window.albumDialogClient = new ImageEditor(this._control, imageProviderUrl, true);
	imageEditor.setInput(input);
	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>\n";
		html += "<select keep='true' name='" + inputName + "'>\n";
		for(var k in attribute.v) {
			var v = attribute.v[k];
			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>\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;
		html += "<td class='attributeLabel'>" + attribute.l + "</td><td>\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>\n";
		html += "<textarea class='text' name='" + inputName + "'>" + value.replace(/</g, "&lt;") + "</textarea>";
		break;
	}
	html += "</td></tr>";
	return html;
}

RichTextAttributeEditor.prototype.showAttributes = function(rank)
{
	var id = this._control.getId();
	var element = this._menuElements[rank];
	if(element == null) return;
	this._element = element;
	var model = this._model[element.tagName];
	if(model == null) return;
	if(model.showDialog != null) return model.showDialog(this._control);
	this._control.hideMenu();
	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'>";
	for(var name in model.attributes) {
		var attribute = model.attributes[name];
		html += this.showAttribute(name, attribute, element);
	}
	html += "</table>";
	html += "<div align='center' style='padding:2px'><input class='richTextOkButton' type='button' value='ok' onclick='richTextAttributeEditor.commitAttributes()'></div>";
	panel.innerHTML = html;
	this._titleElement = panel.firstChild;
	this.addEvent(this._titleElement, "mousedown", this._dragStart);
	var posX;
	var posY;
	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";
	panel.className = "richTextPanel";
	this.hideShowCovered();
	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 count = 0;
	for(;element != null && element.nodeType == 1;element = element.parentNode) {
		var model = this._model[element.tagName];
		if(model == null) continue;
		this._menuElements[this._menuElements.length] = element;
		var icon = "";
		if(model.icon != null) {
			icon = "<img align='absbottom' border='0' width='16' height='16' src='iso_icons/odf_button_element_" + model.icon + "'>\240\240"; 
		}
		html += "<div><a onclick='richTextAttributeEditor.showAttributes(" + count + ");return false;' href='#'>" + icon + model.label + "</a></div>";
		count++;
	}
	menu.innerHTML = html;
	var posX;
	var posY;
	var frameDocument = frames[id].document;
	var frameElement = document.getElementById(id);
	if (document.all != null) {
		posY = ev.clientY  + this.getOffsetTop(frameElement);// + document.body.scrollTop;
		posX = ev.clientX  + this.getOffsetLeft(frameElement);// + document.body.scrollLeft;
	} else {
		posX = ev.pageX + this.getOffsetLeft(frameElement);
		posY = ev.pageY + this.getOffsetTop(frameElement);
	}
	this._posX = posX;
	this._posY = posY;
	var st = menu.style;
	st.left = (posX + 5) + "px";
	st.top = (posY - 10) + "px";
	if(count) {
		menu.className = "richTextMenu";
	} else {
		menu.className = "hiddenRichTextMenu";
	}
	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;
	}
}

var richTextAttributeEditor = new RichTextAttributeEditor();
