/* Copyright 2008 Marc Mongenet */

var w2mlEditionToolbar;
var w2mlActiveEditedIFrame;
w2mlEditWysiwygURI = w2mlEditURI + "wysiwyg/";


var i18n = {
	"align left":
		{ "fr": "aligné à gauche" },
	"align right":
		{ "fr": "aligné à droite" },
	"bigger":
		{ "fr": "grossir" },
	"bold":
		{ "fr": "gras" },
	"bullet list":
		{ "fr": "liste à puces" },
	"cancel":
		{ "fr": "annuler" },
	"center":
		{ "fr": "centré" },
	"close":
		{ "fr": "fermer" },
	"color":
		{ "fr": "couleur" },
	"colorize":
		{ "fr": "colorier" },
	"Destination web address:":
		{ "fr": "Adresse web de destination :" },
	"Edition toolbar":
		{ "fr": "Outils d'édition" },
	"font":
		{ "fr": "fonte" },
	"horizontal rule":
		{ "fr": "barre horizontale" },
	"hyperlink":
		{ "fr": "hyperlien" },
	"Image web address:":
		{ "fr": "Adresse web de l'image :" },
	"indent":
		{ "fr": "indenté" },
	"insert":
		{ "fr": "insérer" },
	"italic":
		{ "fr": "italique" },
	"justify":
		{ "fr": "justifié" },
	"link":
		{ "fr": "lier" },
	"maximize":
		{ "fr": "maximiser" },
	"minimize":
		{ "fr": "réduire" },
	"smaller":
		{ "fr": "réduire" },
	"strike":
		{ "fr": "barré" },
	"subscript":
		{ "fr": "indice" },
	"superscript":
		{ "fr": "exposant" },
	"ok":
		{ "fr": "ok" },
	"open":
		{ "fr": "ouvrir", "de": "öffnen" },
	"outdent":
		{ "fr": "désindenté" },
	"numbered list":
		{ "fr": "liste numérotée" },
	"redo":
		{ "fr": "refaire" },
	"save":
		{ "fr": "sauvegarder", "de": "speichern" },
	"underline":
		{ "fr": "souligné" },
	"undo":
		{ "fr": "annuler" }
};



function w2mlMakeActionButton(fileName, comment)
{
	var img = document.createElement("img");
	img.w2mlEnabled = false;
	img.src = w2mlEditWysiwygURI + fileName;
	img.title = img.alt = comment;
	img.unselectable = "on"; // lots of interesting side effects for MSIE
	img.style.width = "20px";
	img.style.padding = "1px";
	img.style.borderWidth = "1px";
	img.style.borderStyle = "solid";
	img.style.borderColor = "#d4d0c8";
	img.style.verticalAlign = "text-bottom";
	img.w2mlHighlight = function() {
		this.style.backgroundColor = "#f4f0e8";
		this.style.padding = "0px 2px 2px 0px";
		this.style.borderColor = "#f0f0f0 #606060 #404040 #d0d0d0";
	};
	img.w2mlDownlight = function() {
		this.style.backgroundColor = "#b4b0a8";
		this.style.padding = "2px 0px 0px 2px";
		this.style.borderColor = "#666 #FFF #FFF #666";
	};
	img.w2mlOutlight = function() {
		this.style.backgroundColor = "";
		this.style.padding = "1px";
		this.style.borderColor = "rgb(212,208,200)";
	};
	img.w2mlPress = function() {
		if (this.w2mlEnabled) this.w2mlDownlight();
	};
	img.w2mlHover = function() {
		if (this.w2mlEnabled) this.w2mlHighlight();
	};
	img.w2mlShow = function() {
		this.w2mlOutlight();
	};
	img.onmouseover = function() { this.w2mlHover(); };
	img.onmouseout  = function() { this.w2mlShow();  };
	img.onmousedown = function() { this.w2mlPress(); };
	img.setActiveState = function(enabled) {
		this.w2mlEnabled = enabled;
		this.w2mlShow();
	};
	return img;
}


function w2mlMakeActionStateButton(fileName, comment)
{
	var img = w2mlMakeActionButton(fileName, comment);
	img.w2mlShow = function() {
		if (this.w2mlPressed) this.w2mlDownlight();
		else this.w2mlOutlight();
	};
	img.setActiveState = function(enabled, pressed) {
		this.w2mlPressed = pressed;
		this.w2mlEnabled = enabled;
		this.w2mlShow();
	};
	return img;
}


function w2mlTbCommandClick(command, value)
{
	if (typeof value == "undefined") value = null;
	var doc;
	if (!w2mlActiveEditedIFrame) {
		try {
			if (!document.selection.createRange().parentElement().isContentEditable) {
				return;
			}
		}
		catch (e) {
			// exception with picture
		}
		doc = document;
	} else {
		if (!w2mlTbCommandClick.offCSS) {
			w2mlTbCommandClick.offCSS = true;
			w2mlActiveEditedIFrame.contentDocument.execCommand("useCSS", false, value);
		}
		doc = w2mlActiveEditedIFrame.contentDocument;
	}

	doc.execCommand(command, false, value);

	if (w2mlActiveEditedIFrame) {
		w2mlActiveEditedIFrame.height = w2mlActiveEditedIFrame.contentDocument.body.offsetHeight;
		w2mlActiveEditedIFrame.contentWindow.scrollTo(0,0);
	}
}


// Array filled with objects with a command and a buttonElm property.
// The buttonElm property has an setActiveState(Boolean) method.
var w2mlEditCommandStates = new Array();
function w2mlSetEditCommandStates()
{
	for (var c in w2mlEditCommandStates) {
		var command = w2mlEditCommandStates[c].command;
		var active = false;
		var doc = !w2mlActiveEditedIFrame ? document : w2mlActiveEditedIFrame.contentDocument;
		var win = !w2mlActiveEditedIFrame ? window : w2mlActiveEditedIFrame.contentWindow;
		var enabled = doc.queryCommandEnabled(command);
		if (enabled) {
			try {
				if (!w2mlEditCommandStates[c].stateMethod)
					active = doc.queryCommandState(command);
				else
					active = w2mlEditCommandStates[c].stateMethod(win);
			} catch (e) {
				active = false;
			}
		}
		w2mlEditCommandStates[c].buttonElm.setActiveState(enabled, active);
	}
}

var w2mlEditCommandValues = new Array();
function w2mlSetEditCommandValues()
{
	for (var c in w2mlEditCommandValues) {
		var command = w2mlEditCommandValues[c].command;
		var value = "";
		var doc = !w2mlActiveEditedIFrame ? document : w2mlActiveEditedIFrame.contentDocument;
		if (doc.queryCommandEnabled(command)) {
			value = doc.queryCommandValue(command);
			w2mlEditCommandValues[c].valueMethod(w2mlEditCommandValues[c].valueElm, value);
		}
	}
}

// Find the iframe which document was clicked to style it and unstyle others.
function w2mlIFrameSwitch(elm)
{
	if (w2mlActiveEditedIFrame.contentDocument != elm) {
		var iframes = parent.document.getElementsByTagName("iframe");
		for (var i = iframes.length; i--; ) {
			if (iframes[i].contentDocument == elm) {
				w2mlActiveEditedIFrame = iframes[i];
				break;
			}
		}
	}
}

function w2mlEditorMouseDown(event)
{
	if (w2mlActiveEditedIFrame) {
		if (event)
			w2mlIFrameSwitch(this);
		else
			w2mlIFrameSwitch(window.event.srcElement);
	}
}

function w2mlEditorMouseUp()
{
	w2mlSetEditCommandStates();
	w2mlSetEditCommandValues();
}

function w2mlEditorKeyUp()
{
	w2mlSetEditCommandStates();
	w2mlSetEditCommandValues();
	if (w2mlActiveEditedIFrame) {
		w2mlActiveEditedIFrame.height = w2mlActiveEditedIFrame.contentDocument.body.offsetHeight;
		w2mlActiveEditedIFrame.contentWindow.scrollTo(0,0);
	}
}


// Create a button based on the editing command name.
// Set images width to avoid having to wait for image loading.
function w2mlTbMakeTypoButton(command, title) {
	var b = w2mlMakeActionStateButton(command + ".gif", title);
	b.onclick = function(event) {
		w2mlTbCommandClick(command);
		w2mlSetEditCommandStates();
		// note that b.w2mlHover() is not called to show a depressed button
		if (w2mlActiveEditedIFrame) {
			w2mlActiveEditedIFrame.contentWindow.focus();
		}
	};
/* Caused Opera to loose selection
	b.onmousedown = function(event) {
		w2mlStopEvent(event || window.event); // Prevent iframe to lose focus.
	};
*/
	w2mlEditCommandStates[w2mlEditCommandStates.length] = { command: command, buttonElm: b };
	return b;
}

function w2mlTbMakeFormatButton(command, title) {
	var b = w2mlMakeActionButton(command + ".gif", title);
	b.onclick = function() {
		if (b.w2mlEnabled) {
			w2mlTbCommandClick(command);
		}
		w2mlSetEditCommandStates();
		b.w2mlHover(); // action button can't be depressed, immediately show hovered state
	};
	w2mlEditCommandStates[w2mlEditCommandStates.length] = { command: command, buttonElm: b, stateMethod: function(){} };
	return b;
}

// Create a toolbar button separation.
// Set images width to avoid having to wait for image loading.
function w2mlTbMakeButtonSeparator()
{
	var sep = document.createElement("img");
	sep.src = w2mlEditWysiwygURI + "vsep.gif";
	sep.style.width = "2px";
	sep.title = "";
	sep.alt = "|";
	return sep;
}


function w2mlHyperlinkState(win) {
	if (win.getSelection) {
		var sel = win.getSelection();
		var range = sel.getRangeAt(0);
		var ancestor = range.endContainer;
	}
	else {
		var sel = document.selection;
		var range = sel.createRange();
		var ancestor = range.parentElement();
	}
	for (; ancestor; ancestor = ancestor.parentNode)
		if (ancestor.tagName == "A")
			return true;
	return false;
}


function w2mlURLDialogRes(url) {
	if (url != null) {
		w2mlTbCommandClick("unlink"); // preemptively unlink to avoid links fusion
		if (url.length > 0) {
			w2mlTbCommandClick("createlink", url);
			this.w2mlPressed = true;
		}
	}
	document.getElementById("w2mlTbButtonsDiv").style.display = "";
	document.getElementById("w2mlTbURLDiv").style.display = "none";
}

function w2mlTbHyperlinkButton()
{
	var a = w2mlMakeActionStateButton("hyperlink.gif", w2mltr("hyperlink", i18n));
	a.onclick = function () {
		if (!this.w2mlPressed) {
			// Display URL dialog instead of buttons
			document.getElementById("w2mlTbButtonsDiv").style.display = "none";
			document.getElementById("w2mlTbURLDiv").style.display = "";
		} else {
			w2mlTbCommandClick("unlink");
			this.w2mlPressed = false;
		}
	}
	var obj = { command: "createlink", buttonElm: a };
	obj.stateMethod = w2mlHyperlinkState;
	w2mlEditCommandStates[w2mlEditCommandStates.length] = obj;
	return a;
}


function w2mlImgDialogRes(url) {
	if (url != null && url.length > 0) {
		w2mlTbCommandClick("insertimage", url);
	}
	document.getElementById("w2mlTbButtonsDiv").style.display = "";
	document.getElementById("w2mlTbImgDiv").style.display = "none";
}

function w2mlTbImgButton()
{
	var b = w2mlMakeActionButton("insertimage.gif", w2mltr("image", i18n));
	b.onclick = function () {
		// Display IMG URL dialog instead of buttons
		document.getElementById("w2mlTbButtonsDiv").style.display = "none";
		document.getElementById("w2mlTbImgDiv").style.display = "";
	};
	w2mlEditCommandStates[w2mlEditCommandStates.length] = { command: "insertimage", buttonElm: b, stateMethod: function(){} };
	return b;
}


function hex2(num)
{
	var res = num.toString(16);
	if (res.length == 1)
		res = "0" + res;
	return res;
}


function w2mlColorDialogRes(color)
{
	if (color != null && color.length > 0) {
		w2mlTbCommandClick("forecolor", color);
	}
	w2mlSetEditCommandValues();
	document.getElementById("w2mlTbButtonsDiv").style.display = "";
	document.getElementById("w2mlTbColorDiv").style.display = "none";
}

function w2mlSetCurrentFontColor(elm, color)
{
	if (!color) return;
	var input = document.getElementById("w2mlTbColorInput");
	if (typeof color == "number") // IE
		color = "#" + hex2(color & 255) + hex2(color>>8 & 255) + hex2(color>>16 & 255);
	else {
		var re = /rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)/;
		if (color.match(re)) { // Moz
			var r = parseInt(RegExp.$1);
			var g = parseInt(RegExp.$2);
			var b = parseInt(RegExp.$3);
			color = "#" + hex2(r) + hex2(g) + hex2(b);
		}
	}
	input.value = color;
	input.style.color = color;
}

function w2mlTbMakeForeColorButton()
{
	var b = w2mlMakeActionButton("forecolor.gif", w2mltr("color", i18n));
	b.onclick = function () {
		// Display color selection dialog instead of buttons
		document.getElementById("w2mlTbButtonsDiv").style.display = "none";
		document.getElementById("w2mlTbColorDiv").style.display = "";
	};
	w2mlEditCommandStates[w2mlEditCommandStates.length] = { command: "forecolor", buttonElm: b };
	w2mlEditCommandValues[w2mlEditCommandValues.length] = { command: "forecolor", buttonElm: b, valueMethod: w2mlSetCurrentFontColor };
	return b;
}


// Create a combobox listing fonts.
// Update the combobox with fonts found in the edited element.
function w2mlMakeFontOption(fontname)
{
	var option = document.createElement("option");
	option.appendChild(document.createTextNode(fontname));
	option.value = option.style.fontFamily = fontname;
	option.onclick = function() {
		w2mlTbCommandClick("fontname", this.value);
	};
	return option;
}

function w2mlSetCurrentFontName(elm, font)
{
	var found = false;
	for (var option = elm.firstChild; option; option = option.nextSibling) {
		if (option.value == font) {
			option.selected = "selected";
			elm.style.fontFamily = font;		
			found = true;
		} else {
			option.selected = "";
		}
	}
	if (!found) {
		var newOption = w2mlMakeFontOption(font);
		newOption.selected = "selected";
		elm.appendChild(newOption);
		elm.style.fontFamily = font;
	}
}

function w2mlSetCurrentFontSize(elm, size)
{
	for (var option = elm.firstChild; option; option = option.nextSibling) {
		if (option.value == size) {
			option.selected = "selected";
			break;
		}
	}
}


function w2mlTbMakeFontBox()
{
	var box = document.createElement("nobr");
	box.appendChild(document.createTextNode(" "+w2mltr("font", i18n)+" "));
	var selfont = document.createElement("select");
	var fontnames = new Array("Arial", "Helvetica", "Verdana", "Garamond", "Georgia", "Times", "Times New Roman", "Courier", "Courier New", "Coronet", "Comic Sans MS");
	for (var f in fontnames)
		selfont.appendChild(w2mlMakeFontOption(fontnames[f]));
	selfont.onchange = function() {
		w2mlTbCommandClick("fontname", this.options[this.selectedIndex].value);
	};
	box.appendChild(selfont);
	w2mlEditCommandValues[w2mlEditCommandValues.length] = { command: "fontname", valueElm: selfont, valueMethod: w2mlSetCurrentFontName };
	var selsize = document.createElement("select");
	for (var size = 1; size <= 7; ++size) {
		var option = document.createElement("option");
		option.appendChild(document.createTextNode(size.toString()));
		option.value = size;
		selsize.appendChild(option);
		selsize.onchange = function() {
			w2mlTbCommandClick("fontsize", this.options[this.selectedIndex].value);
		};
	}
	box.appendChild(selsize);
	w2mlEditCommandValues[w2mlEditCommandValues.length] = { command: "fontsize", valueElm: selsize, valueMethod: w2mlSetCurrentFontSize };
	return box;
}


// Create an edition toolbar.
// Set images width to avoid having to wait for image loading.
function w2mlNewEditionToolbar(edelm)
{
	this.activeIFrame = null;

	var clientArea = document.createElement("div");
	clientArea.style.backgroundColor = "#d4d0c8";
	clientArea.style.padding = "1px";
	clientArea.unselectable = "on";
	var buttonsDiv = document.createElement("div");
	buttonsDiv.id = "w2mlTbButtonsDiv";
	buttonsDiv.unselectable = "on";

	var save = w2mlMakeActionStateButton("save.gif", w2mltr("save", i18n));
	save.w2mlEnabled = true;
	save.onclick = w2mlSave;
	buttonsDiv.appendChild(save);
	buttonsDiv.appendChild(w2mlTbMakeButtonSeparator());
	buttonsDiv.appendChild(w2mlTbMakeFormatButton("undo", w2mltr("undo", i18n)));
	buttonsDiv.appendChild(w2mlTbMakeFormatButton("redo", w2mltr("redo", i18n)));
	buttonsDiv.appendChild(w2mlTbMakeButtonSeparator());
	buttonsDiv.appendChild(w2mlTbMakeTypoButton("bold", w2mltr("bold", i18n)));
	buttonsDiv.appendChild(w2mlTbMakeTypoButton("italic", w2mltr("italic", i18n)));
	buttonsDiv.appendChild(w2mlTbMakeTypoButton("underline", w2mltr("underline", i18n)));
	buttonsDiv.appendChild(w2mlTbMakeTypoButton("strikethrough", w2mltr("strike", i18n)));
	buttonsDiv.appendChild(w2mlTbMakeTypoButton("subscript", w2mltr("subscript", i18n)));
	buttonsDiv.appendChild(w2mlTbMakeTypoButton("superscript", w2mltr("superscript", i18n)));
	buttonsDiv.appendChild(w2mlTbMakeForeColorButton());
	buttonsDiv.appendChild(w2mlTbHyperlinkButton());
	buttonsDiv.appendChild(w2mlTbMakeButtonSeparator());
	buttonsDiv.appendChild(w2mlTbMakeTypoButton("justifyleft", w2mltr("align left", i18n)));
	buttonsDiv.appendChild(w2mlTbMakeTypoButton("justifyfull", w2mltr("justify", i18n)));
	buttonsDiv.appendChild(w2mlTbMakeTypoButton("justifycenter", w2mltr("center", i18n)));
	buttonsDiv.appendChild(w2mlTbMakeTypoButton("justifyright", w2mltr("align right", i18n)));
	buttonsDiv.appendChild(w2mlTbMakeFormatButton("indent", w2mltr("indent", i18n)));
	buttonsDiv.appendChild(w2mlTbMakeFormatButton("outdent", w2mltr("outdent", i18n)));
	buttonsDiv.appendChild(w2mlTbMakeTypoButton("insertorderedlist", w2mltr("numbered list", i18n)));
	buttonsDiv.appendChild(w2mlTbMakeTypoButton("insertunorderedlist", w2mltr("bullet list", i18n)));
	buttonsDiv.appendChild(w2mlTbMakeButtonSeparator());
	buttonsDiv.appendChild(w2mlTbMakeFormatButton("inserthorizontalrule", w2mltr("horizontal rule", i18n)));
	buttonsDiv.appendChild(w2mlTbImgButton());
	buttonsDiv.appendChild(w2mlTbMakeFontBox());

	clientArea.appendChild(buttonsDiv);

	// Dialog to request URL
	var urlDiv = document.createElement("div");
	urlDiv.style.display = "none";
	urlDiv.id = "w2mlTbURLDiv";
	var urlForm = document.createElement("form");
	urlForm.appendChild(document.createTextNode(w2mltr("Destination web address:", i18n)+" "));
	var urlInput = document.createElement("input");
	urlInput.onmousedown = function() {
		if (document.selection)
			urlInput.w2mlSelection = document.selection.createRange();
	};
	urlForm.appendChild(urlInput);
	var urlOk = document.createElement("input");
	urlOk.type = "submit";
	urlOk.value = w2mltr("link", i18n);
	urlForm.appendChild(urlOk);
	var urlCancel = document.createElement("button");
	urlCancel.setAttribute("type", "button");
	urlCancel.appendChild(document.createTextNode(w2mltr("cancel", i18n)));
	urlCancel.onclick = function() { w2mlURLDialogRes(null); };
	urlForm.appendChild(urlCancel);
	urlForm.onsubmit = function() {
		if (urlInput.w2mlSelection)
			urlInput.w2mlSelection.select();
		w2mlURLDialogRes(urlInput.value);
		return false;
	};
	urlDiv.appendChild(urlForm);
	clientArea.appendChild(urlDiv);

	// Dialog to request IMG URL
	var imgDiv = document.createElement("div");
	imgDiv.style.display = "none";
	imgDiv.id = "w2mlTbImgDiv";
	var imgForm = document.createElement("form");
	imgForm.appendChild(document.createTextNode(w2mltr("Image web address:", i18n)+" "));
	var imgInput = document.createElement("input");
	imgInput.onmousedown = function() {
		if (document.selection)
			imgInput.w2mlSelection = document.selection.createRange();
	};
	imgForm.appendChild(imgInput);
	var imgOk = document.createElement("input");
	imgOk.setAttribute("type", "submit");
	imgOk.value = w2mltr("insert", i18n);
	imgForm.appendChild(imgOk);
	var imgCancel = document.createElement("button");
	imgCancel.setAttribute("type", "button");
	imgCancel.appendChild(document.createTextNode(w2mltr("cancel", i18n)));
	imgCancel.onclick = function() { w2mlImgDialogRes(null); };
	imgForm.appendChild(imgCancel);
	imgForm.onsubmit = function() {
		if (imgInput.w2mlSelection)
			imgInput.w2mlSelection.select();
		w2mlImgDialogRes(imgInput.value);
		return false;
	};
	imgDiv.appendChild(imgForm);
	clientArea.appendChild(imgDiv);

	// Color selection dialog
	var colorDiv = document.createElement("div");
	colorDiv.style.display = "none";
	colorDiv.id = "w2mlTbColorDiv";
	clientArea.appendChild(colorDiv);
	var colorForm = document.createElement("form");
	colorForm.style.marginBottom = 0;
	colorDiv.appendChild(colorForm);
	var colorTable = document.createElement("table");
	colorForm.appendChild(colorTable);
	var colorTBody = document.createElement("tbody");
	colorTable.appendChild(colorTBody);
	var colorTr = document.createElement("tr");
	colorTBody.appendChild(colorTr);
	var colorTd1 = document.createElement("td");
	colorTr.appendChild(colorTd1);
	var colorTd2 = document.createElement("td");
	colorTr.appendChild(colorTd2);
	var colorTd3 = document.createElement("td");
	colorTr.appendChild(colorTd3);
	var colorTd4 = document.createElement("td");
	colorTr.appendChild(colorTd4);
	var colorInput = document.createElement("input");
	colorInput.id = "w2mlTbColorInput";
	colorInput.size = "7";
	colorInput.onmousedown = function() {
		if (document.selection)
			colorInput.w2mlSelection = document.selection.createRange();
	};
	colorTd1.appendChild(document.createTextNode(w2mltr("color", i18n)));
	for (var red = 0; red < 256; red += 85) {
		for (var green = 0; green < 256; green += 85) {
			for (var blue = 0; blue < 256; blue += 85) {
				var colorCode = "#" + hex2(red) + hex2(green) + hex2(blue);
				var acolor = document.createElement("span");
				acolor.style.backgroundColor = acolor.w2mlColor = colorCode;
				acolor.appendChild(document.createTextNode(" "));
				acolor.unselectable = "on";
				acolor.onclick = function(event) {
					colorInput.style.color = colorInput.value = this.w2mlColor;
					w2mlStopEvent(event || window.event);
				};
				colorTd2.appendChild(acolor);
			}
		}
		colorTd2.appendChild(document.createElement("br"));
	}
	colorTd3.appendChild(colorInput);
	var colorOk = document.createElement("input");
	colorOk.setAttribute("type", "submit");
	colorOk.value = w2mltr("colorize", i18n);
	colorTd4.appendChild(colorOk);
	colorTd4.appendChild(document.createTextNode(" "));
	var colorCancel = document.createElement("button");
	colorCancel.setAttribute("type", "button");
	colorCancel.appendChild(document.createTextNode(w2mltr("cancel", i18n)));
	colorCancel.onclick = function() { w2mlColorDialogRes(null); };
	colorTd4.appendChild(colorCancel);
	colorForm.onsubmit = function() {
		if (colorInput.w2mlSelection) {
			colorInput.w2mlSelection.select();
		}
		w2mlColorDialogRes(colorInput.value);
		return false;
	};

	this.window = new W2Bar(w2mltr("Edition toolbar", i18n), clientArea, 3, w2mlUnderElmOnScreen(edelm), 2, 0, w2mlSaveNothing);
}


// w2mlEditedElmToIFrame() creates an iframe to load the edited element in.
// It is a workaround for browser that do not support contentEditable.

function w2mlEditedElmToIFrame(elm)
{
	// Create an iframe, elm content will be copied inside.
	var iframe = elm.parentNode.insertBefore(document.createElement("iframe"), elm)
//	iframe.src = "about:blank";
	elm.w2mlEditedInIFrame = iframe;

	// Try to style the iframe like elm.
	iframe.frameBorder = 0;
	iframe.scrolling = "no";
	if (document.defaultView) {
		var elmStyle = document.defaultView.getComputedStyle(elm, '');
		var iframeStyle = iframe.style;
		iframeStyle.width         = elmStyle.getPropertyValue("width");
		iframeStyle.marginLeft    = elmStyle.getPropertyValue("margin-left");
		iframeStyle.marginRight   = elmStyle.getPropertyValue("margin-right");
		iframeStyle.marginTop     = elmStyle.getPropertyValue("margin-top");
		iframeStyle.marginBottom  = elmStyle.getPropertyValue("margin-bottom");
		iframeStyle.paddingLeft   = elmStyle.getPropertyValue("padding-left");
		iframeStyle.paddingRight  = elmStyle.getPropertyValue("padding-right");
		iframeStyle.paddingTop    = elmStyle.getPropertyValue("padding-top");
		iframeStyle.paddingBottom = elmStyle.getPropertyValue("padding-bottom");
	} else {
		iframe.width = "100%";
	}

	// Iframe loading is asynchronous, even for blank document.
	// The setTimeout hack is used to wait for the iframe content loading.
	w2mlEditedElmToIFrame1Param.push(elm);
	setTimeout("w2mlEditedElmToIFrame1(w2mlEditedElmToIFrame1Param)", 1);
}

var w2mlEditedElmToIFrame1Param = new Array(); // Used to pass param through setTimeout

function w2mlEditedElmToIFrame1(elmArray)
{
	var elm = w2mlEditedElmToIFrame1Param.shift();
	var iframe = elm.w2mlEditedInIFrame;

	// Call w2mlEditedElmToIFrame2 when copied data is loaded in iframe
	// and its content display size can be measured.
	iframe.onload = w2mlEditedElmToIFrame2;

	if (!iframe.contentDocument) {
		iframe.contentDocument = iframe.contentWindow ? iframe.contentWindow.document : iframe.document;
	}
	var idoc = iframe.contentDocument;
	idoc.designMode = "On";
	idoc.open();
	idoc.write("<html><head><title>iframe</title></head><body style='margin:0;padding:0'>"+elm.innerHTML+"</body></html>");
	idoc.close();

	// Copy styles to iframe body.
	if (document.defaultView) {
		var elmStyle = document.defaultView.getComputedStyle(elm, '');
		var iframeStyle = iframe.contentDocument.body.style;
		iframeStyle.fontFamily           = elmStyle.getPropertyValue("font-family");
		iframeStyle.fontStyle            = elmStyle.getPropertyValue("font-style");
		iframeStyle.fontVariant          = elmStyle.getPropertyValue("font-variant");
		iframeStyle.fontWeight           = elmStyle.getPropertyValue("font-weight");
		iframeStyle.fontSize             = elmStyle.getPropertyValue("font-size");
		iframeStyle.color                = elmStyle.getPropertyValue("color");
		iframeStyle.backgroundColor      = elmStyle.getPropertyValue("backgroundColor");
		iframeStyle.backgroundImage      = elmStyle.getPropertyValue("background-image");
		iframeStyle.backgroundRepeat     = elmStyle.getPropertyValue("background-repeat");
		iframeStyle.backgroundAttachment = elmStyle.getPropertyValue("background-attachment");
		iframeStyle.backgroundPosition   = elmStyle.getPropertyValue("backgroundPosition");
		iframeStyle.wordSpacing          = elmStyle.getPropertyValue("word-spacing");
		iframeStyle.letterSpacing        = elmStyle.getPropertyValue("letter-spacing");
		iframeStyle.textDecoration       = elmStyle.getPropertyValue("text-decoration");
		iframeStyle.verticalAlign        = elmStyle.getPropertyValue("vertical-align");
		iframeStyle.textTransform        = elmStyle.getPropertyValue("text-transform");
		iframeStyle.textAlign            = elmStyle.getPropertyValue("text-align");
		iframeStyle.textIndent           = elmStyle.getPropertyValue("text-indent");
		iframeStyle.lineHeight           = elmStyle.getPropertyValue("line-height");
		iframeStyle.whiteSpace           = elmStyle.getPropertyValue("white-space");
		iframeStyle.listStyleType        = elmStyle.getPropertyValue("list-style-type");
		iframeStyle.listStyleImage       = elmStyle.getPropertyValue("list-style-image");
		iframeStyle.listStylePosition    = elmStyle.getPropertyValue("list-style-position");
	}

	// Hide edited element
	elm.w2mlOldDisplay = elm.style.display;
	elm.style.display = "none";
}

// Called when the iframe content is loaded.
function w2mlEditedElmToIFrame2()
{
	var idoc = this.contentDocument;
	this.height = idoc.body.offsetHeight;
	idoc.addEventListener("mousedown", w2mlEditorMouseDown, true);
	idoc.addEventListener("mouseup", w2mlEditorMouseUp, true);
	idoc.addEventListener("keyup", w2mlEditorKeyUp, true);
	this.onload = null;
	if (w2mlActiveEditedIFrame)
		w2mlActiveEditedIFrame.frameBorder = 0;
	w2mlActiveEditedIFrame = this;
}


/* Convert well-formed HTML to XHTML */
function html2xhtml(html)
{
	var state = 0; // 0=text; 1=tag_name; 2=tag_space; 3=attr_name; 4=attr_val; 5=''; 6=""; 7=unquoted
	var xhtml= "";
	for (var i = 0; i < html.length; ++i) {
		switch (state) {
		case 0: // text
			if (html.charAt(i) == "<") {
				state = 1;
			}
			xhtml += html.charAt(i);
			break;
		case 1: // tag name
			if (html.charAt(i) == ">")
				state = 0;
			else if (/\s/.test(html.charAt(i)))
				state = 2;
			xhtml += html.charAt(i).toLowerCase();
			break;
		case 2: // tag space
			if (html.charAt(i) == ">")
				state = 0;
			else if (!(/\s/.test(html.charAt(i))))
				state = 3;
			xhtml += html.charAt(i).toLowerCase();
			break;
		case 3: // attribute name
			if (html.charAt(i) == "=")
				state = 4;
			else if (/\s/.test(html.charAt(i))) {
				// no attribute value
				xhtml += '=""';
				state = 2;
			}
			xhtml += html.charAt(i).toLowerCase();
			break;
		case 4: // attribute value
			if (html.charAt(i) == "'")
				state = 5;
			else if (html.charAt(i) == '"')
				state = 6;
			else {
				xhtml += '"';
				state = 7;
			}
			xhtml += html.charAt(i);
			break;
		case 5: // 'attribute value'
			if (html.charAt(i) == "'")
				state = 2;
			xhtml += html.charAt(i);
			break;
		case 6: // "attribute value"
			if (html.charAt(i) == '"')
				state = 2;
			xhtml += html.charAt(i);
			break;
		case 7: // unquoted attribute value
			if (html.charAt(i) == ">") {
				xhtml += '"';
				state = 0;
			}
			else if (/\s/.test(html.charAt(i))) {
				xhtml += '"';
				state = 2;
			}
			xhtml += html.charAt(i);
			break;
		}
	}
	xhtml = xhtml.replace(/<area([^>]*)>/g, "<area$1/>");
	xhtml = xhtml.replace(/<base([^>]*)>/g, "<base$1/>");
	xhtml = xhtml.replace(/<basefont([^>]*)>/g, "<basefont$1/>");
	xhtml = xhtml.replace(/<br([^>]*)>/g, "<br$1/>");
	xhtml = xhtml.replace(/<col([^>]*)>/g, "<col$1/>");
	xhtml = xhtml.replace(/<frame([^>]*)>/g, "<frame$1/>");
	xhtml = xhtml.replace(/<hr([^>]*)>/g, "<hr$1/>");
	xhtml = xhtml.replace(/<img([^>]*)>/g, "<img$1/>");
	xhtml = xhtml.replace(/<input([^>]*)>/g, "<input$1/>");
	xhtml = xhtml.replace(/<isindex([^>]*)>/g, "<isindex$1/>");
	xhtml = xhtml.replace(/<link([^>]*)>/g, "<link$1/>");
	xhtml = xhtml.replace(/<meta([^>]*)>/g, "<meta$1/>");
	xhtml = xhtml.replace(/<param([^>]*)>/g, "<param$1/>");
	return xhtml;
}


// Make the edited element editable with contentEditable=true or,
// if impossible, by copying it into an iframed with designMode=true.
// Open an edition toolbar if not already done.
function w2mlEditwysiwyg(elm)
{
	if (!w2mlEditionToolbar) {
		if (w2mlSaveUI) {
			w2mlSaveUI.hide();
		}
		// Create edition toolbar
		w2mlEditionToolbar = new w2mlNewEditionToolbar(elm);
		w2mlSaveUI = w2mlEditionToolbar;
	}
	
	// make element editable
	elm.w2mlGetEditionId = function() {
		return elm.getAttribute("w2mledid");
	};
	w2mlRegisterEditedObject(elm);
	if ("contentEditable" in elm) {
		elm.contentEditable = true;
		elm.w2mlSerializeEdition = function() { return html2xhtml(elm.innerHTML); };
		if (elm.attachEvent) {
			elm.attachEvent("onmousedown", w2mlEditorMouseDown);
			elm.attachEvent("onmouseup", w2mlEditorMouseUp);
			elm.attachEvent("onkeyup", w2mlEditorKeyUp);
		}
		else {
			elm.addEventListener("mousedown", w2mlEditorMouseDown, false);
			elm.addEventListener("mouseup", w2mlEditorMouseUp, false);
			elm.addEventListener("keyup", w2mlEditorKeyUp, false);
		}
	} else {
		// make element editable in an iframe instead of contentEditable
		w2mlEditedElmToIFrame(elm);
		elm.w2mlSerializeEdition = function() {
			return html2xhtml(elm.w2mlEditedInIFrame.contentDocument.body.innerHTML);
		};
	}
}


function w2mlRegisterwysiwygEditor(elm)
{
	var edrun = elm.getAttribute("w2mledrun");
	if (edrun == "auto") {
		w2mlEditwysiwyg(elm);
	}
	else {
		w2mlSetMouseHoverImg(elm, w2mlEditURI + "pencil.gif");
		elm.ondblclick = function() {
			w2mlUnsetMouseHoverImg(this);
			elm.ondblclick = null;
			w2mlEditwysiwyg(this);
			return false;
		};
	}
}


// Images pre-loading (from Rhino book 4th edition, p. 238)
(new Image()).src = w2mlEditWysiwygURI + "bold.gif";
(new Image()).src = w2mlEditWysiwygURI + "decreasefontsize.gif";
(new Image()).src = w2mlEditWysiwygURI + "forecolor.gif";
(new Image()).src = w2mlEditWysiwygURI + "hyperlink.gif";
(new Image()).src = w2mlEditWysiwygURI + "increasefontsize.gif";
(new Image()).src = w2mlEditWysiwygURI + "indent.gif";
(new Image()).src = w2mlEditWysiwygURI + "inserthorizontalrule.gif";
(new Image()).src = w2mlEditWysiwygURI + "insertimage.gif";
(new Image()).src = w2mlEditWysiwygURI + "insertorderedlist.gif";
(new Image()).src = w2mlEditWysiwygURI + "insertunorderedlist.gif";
(new Image()).src = w2mlEditWysiwygURI + "italic.gif";
(new Image()).src = w2mlEditWysiwygURI + "justifycenter.gif";
(new Image()).src = w2mlEditWysiwygURI + "justifyfull.gif";
(new Image()).src = w2mlEditWysiwygURI + "justifyleft.gif";
(new Image()).src = w2mlEditWysiwygURI + "justifyright.gif";
(new Image()).src = w2mlEditWysiwygURI + "outdent.gif";
(new Image()).src = w2mlEditWysiwygURI + "preview.gif";
(new Image()).src = w2mlEditWysiwygURI + "redo.gif";
(new Image()).src = w2mlEditWysiwygURI + "save.gif";
(new Image()).src = w2mlEditWysiwygURI + "strikethrough.gif";
(new Image()).src = w2mlEditWysiwygURI + "subscript.gif";
(new Image()).src = w2mlEditWysiwygURI + "superscript.gif";
(new Image()).src = w2mlEditWysiwygURI + "underline.gif";
(new Image()).src = w2mlEditWysiwygURI + "undo.gif";
(new Image()).src = w2mlEditWysiwygURI + "vsep.gif";
