//
// htmlArea v3.0 - Copyright (c) 2002 interactivetools.com, inc.
// This copyright notice MUST stay intact for use (see license.txt).
//
// A free WYSIWYG editor replacement for <textarea> fields.
// For full source code and docs, visit http://www.interactivetools.com/
//
// Version 3.0 developed by Mihai Bazon for InteractiveTools.
//           http://students.infoiasi.ro/~mishoo
//
// $Id: htmlarea.js,v 1.3 2003/02/17 13:57:07 mishoo Exp $

function HTMLArea(textarea, config) {
	if (HTMLArea.checkSupportedBrowser()) {
		if (typeof config == "undefined") {
			this.config = new HTMLArea.Config();
		} else {
			this.config = config;
		}
		if (this.config.debug) {
			// alert("DEBUG ON!!");
		}
		this._htmlArea = null;
		this._textArea = textarea;
		this._mode = "wysiwyg";
	}
};

HTMLArea.Config = function () {
	this.version = "3.0";

	this.width = "auto";
	this.height = "auto";

	this.sizeIncludesToolbar = true;

	this.bodyStyle = "background-color: #fff; font-family: verdana,sans-serif";
	this.editorURL = "htmlarea/";

	this.imgURL = "images/";
	this.popupURL = "popups/";

	this.debug = 0;

	this.replaceNextLines = 0;
	this.plainTextInput = 0;

	this.toolbar = [ [ "fontname", "space" ],
			 [ "fontsize", "space" ],
			 [ "formatblock", "space"],
			 [ "bold", "italic", "underline", "separator" ],
			 [ "strikethrough", "subscript", "superscript", "separator" ],
			 [ "justifyleft", "justifycenter", "justifyright", "justifyfull", "separator" ],
			 [ "orderedlist", "unorderedlist", "outdent", "indent", "separator" ],
			 [ "forecolor", "backcolor", "separator" ],
			 [ "horizontalrule", "createlink", "insertimage", "inserttable", "htmlmode", "separator" ]
		];

	this.fontname = {
		"Arial":           'arial,helvetica,sans-serif',
		"Courier New":     'courier new,courier,monospace',
		"Georgia":         'georgia,times new roman,times,serif',
		"Tahoma":          'tahoma,arial,helvetica,sans-serif',
		"Times New Roman": 'times new roman,times,serif',
		"Verdana":         'verdana,arial,helvetica,sans-serif',
		"impact":          'impact',
		"WingDings":       'wingdings'
	};

	this.fontsize = {
		"1 (8 pt)":  "1",
		"2 (10 pt)": "2",
		"3 (12 pt)": "3",
		"4 (14 pt)": "4",
		"5 (18 pt)": "5",
		"6 (24 pt)": "6",
		"7 (36 pt)": "7"
	};

	this.formatblock = {
		"Normal": "p",
		"Address": "address",
		"Formatted": "pre"
	};


	this.btnList = {
		bold:           ["Bold",                 "Bold",               "ed_format_bold.gif",       false],
		italic:         ["Italic",               "Italic",             "ed_format_italic.gif",     false],
		underline:      ["Underline",            "Underline",          "ed_format_underline.gif",  false],
		strikethrough:  ["StrikeThrough",        "Strikethrough",      "ed_format_strike.gif",     false],
		subscript:      ["SubScript",            "Subscript",          "ed_format_sub.gif",        false],
		superscript:    ["SuperScript",          "Superscript",        "ed_format_sup.gif",        false],
		justifyleft:    ["JustifyLeft",          "Justify Left",       "ed_align_left.gif",        false],
		justifycenter:  ["JustifyCenter",        "Justify Center",     "ed_align_center.gif",      false],
		justifyright:   ["JustifyRight",         "Justify Right",      "ed_align_right.gif",       false],
		justifyfull:    ["JustifyFull",          "Justify Full",       "ed_align_justify.gif",     false],
		orderedlist:    ["InsertOrderedList",    "Ordered List",       "ed_list_num.gif",          false],
		unorderedlist:  ["InsertUnorderedList",  "Bulleted List",      "ed_list_bullet.gif",       false],
		outdent:        ["Outdent",              "Decrease Indent",    "ed_indent_less.gif",       false],
		indent:         ["Indent",               "Increase Indent",    "ed_indent_more.gif",       false],
		forecolor:      ["ForeColor",            "Font Color",         "ed_color_fg.gif",          false],
		backcolor:      ["BackColor",            "Background Color",   "ed_color_bg.gif",          false],
		horizontalrule: ["InsertHorizontalRule", "Horizontal Rule",    "ed_hr.gif",                false],
		createlink:     ["CreateLink",           "Insert Web Link",    "ed_link.gif",              false],
		insertimage:    ["InsertImage",          "Insert Image",       "ed_image.gif",             false],
		inserttable:    ["InsertTable",          "Insert Table",       "insert_table.gif",         false],
		htmlmode:       ["HtmlMode",             "Toggle HTML Source", "ed_html.gif",              true],
		popupeditor:    ["popupeditor",          "Enlarge Editor",     "fullscreen_maximize.gif",  true],
		about:          ["about",                "About this editor",  "ed_about.gif",             true],
		help:           ["showhelp",             "Help using editor",  "ed_help.gif",              true]
	};


	for (var i in this.btnList) {
		var btn = this.btnList[i];
		if (typeof HTMLArea.I18N.tooltips[i] != "undefined") {
			btn[1] = HTMLArea.I18N.tooltips[i];
		}
	}
};


HTMLArea.replaceAll = function() {
	var tas = document.getElementsByTagName("textarea");
	for (var i = tas.length; i > 0; (new HTMLArea(tas[--i])).generate());
};


HTMLArea.prototype._createToolbar = function () {
	var editor = this;

	var toolbar = document.createElement("div");
	this._toolbar = toolbar;
	toolbar.className = "toolbar";
	toolbar.unselectable = "1";
	if (editor.config.debug) {
		toolbar.style.border = "1px solid red";
	}
	var tb_row = null;
	var tb_objects = new Object();
	this._toolbarObjects = tb_objects;


	function newLine() {
		var table = document.createElement("table");
		table.border = "0px";
		table.cellSpacing = "0px";
		table.cellPadding = "0px";
		toolbar.appendChild(table);

		var tb_body = document.createElement("tbody");
		table.appendChild(tb_body);
		tb_row = document.createElement("tr");
		tb_body.appendChild(tb_row);
	};

	newLine();


	function createButton(txt) {

		function setButtonStatus(id, newval) {
			var oldval = this[id];
			var el = this.element;
			if (oldval != newval) {
				switch (id) {
				    case "enabled":
					if (newval) {
						HTMLArea._removeClass(el, "buttonDisabled");
						el.disabled = false;
					} else {
						HTMLArea._addClass(el, "buttonDisabled");
						el.disabled = true;
					}
					break;
				    case "active":
					if (newval) {
						HTMLArea._addClass(el, "buttonPressed");
					} else {
						HTMLArea._removeClass(el, "buttonPressed");
					}
					break;
				}
				this[id] = newval;
			}
		};

		function createSelect() {
			var options = null;
			var el = null;
			var cmd = null;
			switch (txt) {
			    case "fontsize":
			    case "fontname":
			    case "formatblock":
				options = editor.config[txt];
				cmd = txt;
				break;
			}
			if (options) {
				el = document.createElement("select");
				var obj = {
					name: txt,
					element: el,
					enabled: true,
					text: false,
					cmd: cmd,
					state: setButtonStatus
				};
				tb_objects[txt] = obj;
				for (var i in options) {
					var op = document.createElement("option");
					op.appendChild(document.createTextNode(i));
					op.value = options[i];
					el.appendChild(op);
				}
				HTMLArea._addEvent(el, "change", function () {
					editor._comboSelected(el, txt);
				});
			}
			return el;
		};

		var el = null;
		var btn = null;
		switch (txt) {
		    case "separator":
			el = document.createElement("div");
			el.className = "separator";
			break;
		    case "space":
			el = document.createElement("div");
			el.className = "space";
			break;
		    case "linebreak":
			newLine();
			return false;
		    case "textindicator":
			el = document.createElement("div");
			el.appendChild(document.createTextNode(""));
			el.className = "indicator";
			el.title = HTMLArea.I18N.tooltips.textindicator;
			var obj = {
				name: txt,
				element: el,
				enabled: true,
				active: false,
				text: false,
				cmd: "textindicator",
				state: setButtonStatus
			};
			tb_objects[txt] = obj;
			break;
		    default:
			btn = editor.config.btnList[txt];
			break;
		}
		if (!el && btn) {
			el = document.createElement("div");
			el.title = btn[1];
			el.className = "button";

			var obj = {
				name: txt,
				element: el,
				enabled: true,
				active: false,
				text: btn[3],
				cmd: btn[0],
				state: setButtonStatus
			};
			tb_objects[txt] = obj;

			HTMLArea._addEvent(el, "mouseover", function () {
				if (obj.enabled) {
					HTMLArea._addClass(el, "buttonHover");
				}
			});
			HTMLArea._addEvent(el, "mouseout", function () {
				if (obj.enabled) with (HTMLArea) {
					_removeClass(el, "buttonHover");
					_removeClass(el, "buttonActive");
					(obj.active) && _addClass(el, "buttonPressed");
				}
			});
			HTMLArea._addEvent(el, "mousedown", function (ev) {
				if (obj.enabled) with (HTMLArea) {
					_addClass(el, "buttonActive");
					_removeClass(el, "buttonPressed");
					_stopEvent(is_ie ? window.event : ev);
				}
			});

			HTMLArea._addEvent(el, "click", function (ev) {
				if (obj.enabled) with (HTMLArea) {
					_removeClass(el, "buttonActive");
					_removeClass(el, "buttonHover");
					editor._buttonClicked(txt);
					_stopEvent(is_ie ? window.event : ev);
				}
			});
			var img = document.createElement("img");
			img.src = editor.imgURL(btn[2]);
			el.appendChild(img);
		} else if (!el) {
			el = createSelect();
		}
		if (el) {
			var tb_cell = document.createElement("td");
			tb_row.appendChild(tb_cell);
			tb_cell.appendChild(el);
		} else {
			alert("FIXME: Unknown toolbar item: " + txt);
		}
		return el;
	};

	for (var i in this.config.toolbar) {
		var group = this.config.toolbar[i];
		for (var j in group) {
			createButton(group[j]);
		}
	}

	this._htmlArea.appendChild(toolbar);
};


HTMLArea.prototype.generate = function () {
	var editor = this;

	var textarea = this._textArea;
	if (typeof textarea == "string") {

		this._textArea = textarea = document.getElementById(textarea);
	}
	this._ta_size = {
		w: textarea.offsetWidth,
		h: textarea.offsetHeight
	};

	textarea.style.display = "none";


	var htmlarea = document.createElement("div");
	htmlarea.className = "htmlarea";
	this._htmlArea = htmlarea;


	textarea.parentNode.insertBefore(htmlarea, textarea);


	HTMLArea._addEvent(textarea.form, "submit", function (event) {
		editor._formSubmit(HTMLArea.is_ie ? window.event : event);
	});


	this._createToolbar();


	var iframe = document.createElement("iframe");
	htmlarea.appendChild(iframe);
	this._iframe = iframe;




	var height = (this.config.height == "auto" ? (this._ta_size.h + "px") : this.config.height);
	height = parseInt(height);
	var width = (this.config.width == "auto" ? (this._ta_size.w + "px") : this.config.width);
	width = parseInt(width);

	iframe.style.width = width + "px";
	if (this.config.sizeIncludesToolbar) {

		height -= this._toolbar.offsetHeight;
	}
	iframe.style.height = height + "px";

	textarea = document.createElement("textarea");


	textarea.style.display = "none";


	textarea.style.width = iframe.style.width;
	textarea.style.height = iframe.style.height;


	htmlarea.appendChild(textarea);


	this._textArea2 = textarea;


	function initIframe() {
		var doc = editor._iframe.contentWindow.document;
		if (!doc) {
			if (HTMLArea.is_gecko) {
				setTimeout(function () { editor._initIframe(); }, 10);
				return false;
			} else {
				alert("ERROR: IFRAME can't be initialized.");
			}
		}
		if (HTMLArea.is_gecko) {

			doc.designMode = "on";
		}
		editor._doc = doc;
		doc.open();
		var html = "<html>\n";
		html += "<head>\n";
		html += "<style> body { " + editor.config.bodyStyle + " } </style>\n";
		html += "</head>\n";
		html += "<body>\n";
		html += editor._textArea.value;
		html += "</body>\n";
		html += "</html>";
		doc.write(html);
		doc.close();

		if (HTMLArea.is_ie) {

			doc.body.contentEditable = true;
		}

		editor.focusEditor();

		HTMLArea._addEvents
			(doc, ["keydown", "keypress", "mousedown", "mouseup", "drag"],
			 function (event) {
				 return editor._editorEvent(HTMLArea.is_ie ? editor._iframe.contentWindow.event : event);
			 });
		editor.updateToolbar();
		editor.focusEditor();
	};
	setTimeout(initIframe, HTMLArea.is_gecko ? 10 : 0);
};


HTMLArea.prototype.setMode = function(mode) {
	switch (mode) {
	    case "textmode":
		this._textArea2.value = this.getHTML();
		this._iframe.style.display = "none";
		this._textArea2.style.display = "block";
		break;
	    case "wysiwyg":
		this._doc.body.innerHTML = this.getHTML();
		this._iframe.style.display = "block";
		this._textArea2.style.display = "none";
		if (HTMLArea.is_gecko) {

			this._doc.designMode = "on";
		}
		break;
	    default:
		alert("Mode <" + mode + "> not defined!");
		return false;
	}
	this._mode = mode;
	this.focusEditor();
};


HTMLArea.prototype.focusEditor = function() {
	switch (this._mode) {
	    case "wysiwyg":
		this._iframe.contentWindow.focus();
		break;
	    case "textmode":
		this._textArea2.focus();
		break;
	    default:
		alert("ERROR: mode " + this._mode + " is not defined");
		break;
	}
	return this._doc;
};


HTMLArea.prototype.updateToolbar = function() {
	var doc = this._doc;
	var text = (this._mode == "textmode");
	for (var i in this._toolbarObjects) {
		var btn = this._toolbarObjects[i];
		var cmd = btn.cmd;
		if (typeof cmd == "function") {
			continue;
		}
		cmd = cmd.toLowerCase();
		btn.state("enabled", !text || btn.text);
		switch (cmd) {
		    case "fontname":
		    case "fontsize":
		    case "formatblock":
			if (!text) {
				var value = ("" + doc.queryCommandValue(cmd)).toLowerCase();
				if (!value) {

					break;
				}
				var options = this.config[i];
				var k = 0;

				for (var j in options) {

					if ((j.toLowerCase() == value) ||
					    (options[j].substr(0, value.length).toLowerCase() == value)) {
						btn.element.selectedIndex = k;
						break;
					}
					++k;
				}
			}
			break;
		    case "textindicator":
			if (!text) {
				try {with (btn.element.style) {
					backgroundColor = HTMLArea._makeColor(doc.queryCommandValue("backcolor"));
					color = HTMLArea._makeColor(doc.queryCommandValue("forecolor"));
					
				}} catch (e) {
					
				}
			}
			break;
		    case "htmlmode":
			btn.state("active", text);
			break;
		    default:
			try {
				btn.state("active", (!text && doc.queryCommandState(cmd)));
			} catch (e) {}
			break;
		}
	}
};


HTMLArea.prototype.insertNodeAtSelection = function(toBeInserted) {
	if (!HTMLArea.is_ie) {
		var sel = this._getSelection();
		var range = this._createRange(sel);

		sel.removeAllRanges();
		range.deleteContents();
		var node = range.startContainer;
		var pos = range.startOffset;
		range = this._createRange();
		switch (node.nodeType) {
		    case 3:
			if (toBeInserted.nodeType == 3) {

				node.insertData(pos, toBeInserted.data);
				range.setEnd(node, pos + toBeInserted.length);
				range.setStart(node, pos + toBeInserted.length);
			} else {
				node = node.splitText(pos);
				node.parentNode.insertBefore(toBeInserted, node);
				range.setStart(node, 0);
				range.setEnd(node, 0);
			}
			break;
		    case 1:
			node = node.childNodes[pos];
			node.parentNode.insertBefore(toBeInserted, node);
			range.setStart(node, 0);
			range.setEnd(node, 0);
			break;
		}
		sel.addRange(range);
	} else {
		return null;
	}
};

HTMLArea.prototype.insertHTML = function(html) {
	var sel = this._getSelection();
	var range = this._createRange(sel);
	if (HTMLArea.is_ie) {
		range.pasteHTML(html);
	} else {

		var fragment = this._doc.createDocumentFragment();
		var div = this._doc.createElement("div");
		div.innerHTML = html;
		while (div.firstChild) {

			fragment.appendChild(div.firstChild);
		}

		var node = this.insertNodeAtSelection(fragment);
	}
};

HTMLArea.prototype.surroundHTML = function(startTag, endTag) {
	var html = this.getSelectedHTML();

	this.insertHTML(startTag + html + endTag);
};


HTMLArea.prototype.getSelectedHTML = function() {
	var sel = this._getSelection();
	var range = this._createRange(sel);
	var existing = null;
	if (HTMLArea.is_ie) {
		existing = range.htmlText;
	} else {
		existing = HTMLArea.getHTML(range.cloneContents(), false);
	}
	return existing;
};


HTMLArea.prototype._insertImage = function() {
	var sel = this._getSelection();
	var range = this._createRange(sel);
	var editor = this;
	this._popupDialog("insert_image.php", function(param) {
		if (!param) {
			return false;
		}
		editor._execCommand("insertimage", false, param["f_url"]);
		var img = null;
		if (HTMLArea.is_ie) {
			img = range.parentElement();

			if (img.tagName.toLowerCase() != "img") {
				img = img.previousSibling;
			}
		} else {
			img = range.startContainer.previousSibling;
		}
		for (field in param) {
			var value = param[field];
			if (!value) {
				continue;
			}
			switch (field) {
			    case "f_alt":
				img.alt = value;
				break;
			    case "f_border":
				img.border = parseInt(value);
				break;
			    case "f_align":
				img.align = value;
				break;
			    case "f_vert":
				img.vspace = parseInt(value);
				break;
			    case "f_horiz":
				img.hspace = parseInt(value);
				break;
			}
		}
	}, null);
};


HTMLArea.prototype._insertTable = function() {
	var sel = this._getSelection();
	var range = this._createRange(sel);
	var editor = this;
	this._popupDialog("insert_table.html", function(param) {
		if (!param) {
			return false;
		}
		var doc = editor._doc;

		var table = doc.createElement("table");

		for (var field in param) {
			var value = param[field];
			if (!value) {
				continue;
			}
			switch (field) {
			    case "f_width":
				table.style.width = value + param["f_unit"];
				break;
			    case "f_align":
				table.align = value;
				break;
			    case "f_border":
				table.border = parseInt(value);
				break;
			    case "f_spacing":
				table.cellspacing = parseInt(value);
				break;
			    case "f_padding":
				table.cellpadding = parseInt(value);
				break;
			}
		}
		var tbody = doc.createElement("tbody");
		table.appendChild(tbody);
		for (var i = 0; i < param["f_rows"]; ++i) {
			var tr = doc.createElement("tr");
			tbody.appendChild(tr);
			for (var j = 0; j < param["f_cols"]; ++j) {
				var td = doc.createElement("td");
				tr.appendChild(td);
				if (HTMLArea.is_gecko) {

					td.appendChild(doc.createElement("br"));
				}
			}
		}
		if (HTMLArea.is_ie) {
			range.pasteHTML(HTMLArea.getHTML(table, true));
		} else {

			editor.insertNodeAtSelection(table);
		}
		return true;
	}, null);
};


HTMLArea.prototype._buttonClicked = function(txt) {
	var editor = this;
	this.focusEditor();
	var btn = this.config.btnList[txt];
	if (!btn) {
		alert("FIXME: Unconfigured button!");
		return false;
	}
	var cmd = btn[0];
	if (typeof cmd == "function") {
		return cmd(this, txt);
	}
	switch (cmd.toLowerCase()) {
	    case "htmlmode":
		this.setMode(this._mode != "textmode" ? "textmode" : "wysiwyg");
		break;
	    case "forecolor":
	    case "backcolor":
		this._popupDialog("select_color.html", function(color) {
			editor._execCommand(cmd, false, "#" + color);
		}, HTMLArea._colorToRgb(this._doc.queryCommandValue(btn[0])));
		break;
	    case "createlink":
		this._execCommand(cmd, true);
		break;
	    case "insertimage":
		this._insertImage();
		break;
	    case "inserttable":
		this._insertTable();
		break;
	    case "popupeditor":
		if (HTMLArea.is_ie) {
			window.open(this.popupURL("fullscreen.html"), "ha_fullscreen",
				    "toolbar=no,location=no,directories=no,status=yes,menubar=no," +
				    "scrollbars=no,resizable=yes,width=640,height=480");
		} else {
			window.open(this.popupURL("fullscreen.html"), "ha_fullscreen",
				    "toolbar=no,menubar=no,personalbar=no,width=640,height=480," +
				    "scrollbars=no,resizable=yes");
		}

		HTMLArea._object = this;
		break;
	    case "about":
		this._popupDialog("about.html", null, null);
		break;
	    case "help":
		alert("Help not implemented");
		break;
	    default:
		this._execCommand(btn[0], false, "");
		break;
	}
	this.updateToolbar();
	return false;
};


HTMLArea.prototype._comboSelected = function(el, txt) {
	this.focusEditor();
	var value = el.options[el.selectedIndex].value;
	switch (txt) {
	    case "fontname":
	    case "fontsize":
		this._execCommand(txt, false, value);
		break;
	    case "formatblock":
		if (HTMLArea.is_ie) { // sad but true
			value = "<" + value + ">";
		}
		this._execCommand(txt, false, value);
		break;
	    default:
		alert("FIXME: combo box " + txt + " not implemented");
		break;
	}
};


HTMLArea.prototype._execCommand = function(cmdID, UI, param) {
	switch (cmdID.toLowerCase()) {
	    case "createlink":
		if (HTMLArea.is_ie || !UI) {
			this._doc.execCommand(cmdID, UI, param);
		} else {

			if ((param = prompt("Enter URL"))) {
				this._doc.execCommand(cmdID, false, param);
			}
		}
		break;
	    case "backcolor":
		if (HTMLArea.is_ie) {
			this._doc.execCommand(cmdID, UI, param);
		} else {
			this._doc.execCommand("hilitecolor", UI, param);
		}
		break;
	    default:
		this._doc.execCommand(cmdID, UI, param);
		break;
	}
	this.focusEditor();
};

HTMLArea.prototype._editorEvent = function(ev) {
	var editor = this;
	var keyEvent = (HTMLArea.is_ie && ev.type == "keydown") || (ev.type == "keypress");
	if (keyEvent && ev.ctrlKey) {
		var sel = null;
		var range = null;
		var key = String.fromCharCode(HTMLArea.is_ie ? ev.keyCode : ev.charCode).toLowerCase();
		var cmd = null;
		var value = null;
		switch (key) {
		    case 'a':
			if (!HTMLArea.is_ie) {

				sel = this._getSelection();
				sel.removeAllRanges();
				range = this._createRange();
				range.selectNodeContents(this._doc.body);
				sel.addRange(range);
				HTMLArea._stopEvent(ev);
			}
			break;



		    case 'b':
			(!HTMLArea.is_ie) && (cmd = "bold");
			break;
		    case 'i':
			(!HTMLArea.is_ie) && (cmd = "italic");
			break;
		    case 'u':
			(!HTMLArea.is_ie) && (cmd = "underline");
			break;
		    case 's':
			cmd = "strikethrough";
			break;
		    case 'l':
			cmd = "justifyleft";
			break;
		    case 'e':
			cmd = "justifycenter";
			break;
		    case 'r':
			cmd = "justifyright";
			break;
		    case 'j':
			cmd = "justifyfull";
			break;


		    case '1':
		    case '2':
		    case '3':
		    case '4':
		    case '5':
		    case '6':
			cmd = "formatblock";
			value = "h" + key;
			if (HTMLArea.is_ie) {
				value = "<" + value + ">";
			}
			break;
		}
		if (cmd) {

			this._execCommand(cmd, false, value);
			HTMLArea._stopEvent(ev);
		}
	}

	setTimeout(function() {
		editor.updateToolbar();
	}, 50);
};


HTMLArea.prototype._formSubmit = function(ev) {

	this._textArea.value = this.getHTML();
};


HTMLArea.prototype.getHTML = function() {
	switch (this._mode) {
	    case "wysiwyg":
		return HTMLArea.getHTML(this._doc.body, false);
	    case "textmode":
		return this._textArea2.value;
	    default:
		alert("Mode <" + mode + "> not defined!");
		return false;
	}
};


HTMLArea.prototype.getInnerHTML = function() {
	switch (this._mode) {
	    case "wysiwyg":
		return this._doc.body.innerHTML;
	    case "textmode":
		return this._textArea2.value;
	    default:
		alert("Mode <" + mode + "> not defined!");
		return false;
	}
};


HTMLArea.prototype.setHTML = function(html) {
	switch (this._mode) {
	    case "wysiwyg":
		this._doc.body.innerHTML = html;
		break;
	    case "textmode":
		this._textArea2.value = html;
		break;
	    default:
		alert("Mode <" + mode + "> not defined!");
	}
	return false;
};


HTMLArea.agt = navigator.userAgent.toLowerCase();
HTMLArea.is_ie     = ((HTMLArea.agt.indexOf("msie") != -1) && (HTMLArea.agt.indexOf("opera") == -1));
HTMLArea.is_opera  = (HTMLArea.agt.indexOf("opera") != -1);
HTMLArea.is_mac    = (HTMLArea.agt.indexOf("mac") != -1);
HTMLArea.is_mac_ie = (HTMLArea.is_ie && HTMLArea.is_mac);
HTMLArea.is_win_ie = (HTMLArea.is_ie && !HTMLArea.is_mac);
HTMLArea.is_gecko  = (navigator.product == "Gecko");


HTMLArea._object = null;


HTMLArea.checkSupportedBrowser = function() {

	if (HTMLArea.is_gecko) {
		if (navigator.productSub < 20021201) {
			alert("You need at least Mozilla-1.3 Alpha.\n" +
			      "Sorry, your Gecko is not supported.");
			return false;
		}
		if (navigator.productSub < 20030210) {
			alert("Mozilla < 1.3 Beta is not supported!\n" +
			      "I'll try, though, but it might not work.");
		}
	}
	return HTMLArea.is_gecko || HTMLArea.is_ie;
};


HTMLArea.prototype._getSelection = function() {
	if (HTMLArea.is_ie) {
		return this._doc.selection;
	} else {
		return this._iframe.contentWindow.getSelection();
	}
};


HTMLArea.prototype._createRange = function(sel) {
	if (HTMLArea.is_ie) {
		return sel.createRange();
	} else {
		this.focusEditor();
		if (sel) {
			return sel.getRangeAt(0);
		} else {
			return this._doc.createRange();
		}
	}
};



HTMLArea._addEvent = function(el, evname, func) {
	if (HTMLArea.is_ie) {
		el.attachEvent("on" + evname, func);
	} else {
		el.addEventListener(evname, func, true);
	}
};

HTMLArea._addEvents = function(el, evs, func) {
	for (var i in evs) {
		HTMLArea._addEvent(el, evs[i], func);
	}
};

HTMLArea._removeEvent = function(el, evname, func) {
	if (HTMLArea.is_ie) {
		el.detachEvent("on" + evname, func);
	} else {
		el.removeEventListener(evname, func, true);
	}
};

HTMLArea._removeEvents = function(el, evs, func) {
	for (var i in evs) {
		HTMLArea._removeEvent(el, evs[i], func);
	}
};

HTMLArea._stopEvent = function(ev) {
	if (HTMLArea.is_ie) {
		ev.cancelBubble = true;
		ev.returnValue = false;
	} else {
		ev.preventDefault();
		ev.stopPropagation();
	}
};

HTMLArea._removeClass = function(el, className) {
	if (!(el && el.className)) {
		return;
	}
	var cls = el.className.split(" ");
	var ar = new Array();
	for (var i = cls.length; i > 0;) {
		if (cls[--i] != className) {
			ar[ar.length] = cls[i];
		}
	}
	el.className = ar.join(" ");
};

HTMLArea._addClass = function(el, className) {

	HTMLArea._removeClass(el, className);
	el.className += " " + className;
};

HTMLArea._hasClass = function(el, className) {
	if (!(el && el.className)) {
		return false;
	}
	var cls = el.className.split(" ");
	for (var i = cls.length; i > 0;) {
		if (cls[--i] == className) {
			return true;
		}
	}
	return false;
};

HTMLArea._isBlockElement = function(el) {
	var blockTags = " body form textarea fieldset ul ol dl li div " +
		"p h1 h2 h3 h4 h5 h6 quote pre table thead " +
		"tbody tfoot tr td iframe ";
	return (blockTags.indexOf(" " + el.tagName.toLowerCase() + " ") != -1);
};

HTMLArea._needsClosingTag = function(el) {
	var closingTags = " script style div span ";
	return (closingTags.indexOf(" " + el.tagName.toLowerCase() + " ") != -1);
};


HTMLArea.getHTML = function(root, outputRoot) {
	function encode(str) {

		str = str.replace(/&/ig, "&amp;");
		str = str.replace(/</ig, "&lt;");
		str = str.replace(/>/ig, "&gt;");
		str = str.replace(/\"/ig, "&quot;");
		return str;
	};
	var html = "";
	switch (root.nodeType) {
	    case 1:
	    case 11:
		var closed;
		var i;
		if (outputRoot) {
			closed = (!(root.hasChildNodes() || HTMLArea._needsClosingTag(root)));
			html = "<" + root.tagName.toLowerCase();
			var attrs = root.attributes;
			for (i = 0; i < attrs.length; ++i) {
				var a = attrs.item(i);
				if (!a.specified) {
					continue;
				}
				var name = a.name.toLowerCase();
				if (name.substr(0, 4) == "_moz") {

					continue;
				}
				var value;
				if (name != 'style') {
					value = a.value;
				} else {
					value = root.style.cssText.toLowerCase();
				}
				if (value.substr(0, 4) == "_moz") {


					continue;
				}
				html += " " + name + '="' + value + '"';
			}
			html += closed ? " />" : ">";
		}
		for (i = root.firstChild; i; i = i.nextSibling) {
			html += HTMLArea.getHTML(i, true);
		}
		if (outputRoot && !closed) {
			html += "</" + root.tagName.toLowerCase() + ">";
		}
		break;
	    case 3:
		html = encode(root.data);
		break;
	    case 8:
		html = "<!--" + root.data + "-->";
		break;
	}
	return html;
};


HTMLArea._makeColor = function(v) {
	if (typeof v != "number") {

		return v;
	}

	var r = v & 0xFF;
	var g = (v >> 8) & 0xFF;
	var b = (v >> 16) & 0xFF;
	return "rgb(" + r + "," + g + "," + b + ")";
};


HTMLArea._colorToRgb = function(v) {

	function hex(d) {
		return (d < 16) ? ("0" + d.toString(16)) : d.toString(16);
	};

	if (typeof v == "number") {

		var r = v & 0xFF;
		var g = (v >> 8) & 0xFF;
		var b = (v >> 16) & 0xFF;
		return "#" + hex(r) + hex(g) + hex(b);
	}

	if (v.substr(0, 3) == "rgb") {

		var re = /rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)/;
		if (v.match(re)) {
			var r = parseInt(RegExp.$1);
			var g = parseInt(RegExp.$2);
			var b = parseInt(RegExp.$3);
			return "#" + hex(r) + hex(g) + hex(b);
		}

		return null;
	}

	if (v[0] == "#") {

		return v;
	}


	return null;
};


HTMLArea.prototype._popupDialog = function(url, action, init) {
	Dialog(this.popupURL(url), action, init);
};



HTMLArea.prototype.imgURL = function(file) {
	return this.config.editorURL + this.config.imgURL + file;
};

HTMLArea.prototype.popupURL = function(file) {
	return this.config.editorURL + this.config.popupURL + file;
};


