function firstRangeItem(editor,selection,range) {
	if (editor.browser=='mozilla') {
		return selection.anchorNode.childNodes[selection.anchorOffset];
	} else {
		return range.item(0);
	}
}

function selectionType(editor,selection,range) {
	if (editor.browser=='mozilla') {
		if ((selection.rangeCount==1) && (range.startContainer==range.endContainer && (range.endOffset-range.startOffset)==1)) {
			return 'Control';
		} else {
		 return 'Text';
		}
	} else {
		return selection.type
	}
}

function rangeParent(editor,selection,range) {
	if (editor.browser=='mozilla') {
		if (selectionType(editor,selection,range)=='Control') {
			return selection.anchorNode.childNodes[selection.anchorOffset];
		} else {
			return range.startContainer;
		}
	} else {
		if (selectionType(editor,selection,range)=='Control') {
			return range.item(0).parentElement;
		} else {
			return range.parentElement();
		}
	}
}

function getSel(editor,editorDocument){
	if (editor.browser=='mozilla') {
		return editor.getSelection();
	} else {
		return editorDocument.selection;
	}
}

function getRange(editor,selection){
	if (editor.browser=='mozilla') {
		return selection.getRangeAt(0);
	} else {
		return selection.createRange();
	}
}

function executeDialog(editor,href,currentValues,dlgWidth,dlgHeight) {
	var dialogWindow;
	if(editor.browser=='mozilla') {
		editor.tagValues = currentValues
		dialogWindow = editor.open(href,'editorDlg','width='+ dlgWidth + ',height='+ dlgHeight + ',toolbar=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=no,modal=yes');
		return null;
	} else {
		return editor.showModalDialog(href,currentValues,'dialogWidth:'+ dlgWidth + 'px; dialogHeight:'+ dlgHeight + 'px;help:0;status:no;');
	}
}

	function getDocumentObj(editorFrame) {
		return editorFrame.document;
	}

	function getEditorObj(editorName) {
		// if contentDocument exists, W3C compliant (Mozilla)
		if (document.getElementById(editorName).contentDocument){
			document.getElementById(editorName).contentWindow.browser='mozilla';
		} else {
			// IE
			document.getElementById(editorName).contentWindow.browser='ie';
		}
			return document.getElementById(editorName).contentWindow;
	}
	
	function refocus(editor) {
			editor.focus();
	}
	
	function format_selection(editor_name,command) {
		var editor,editorDocument;
		editor=getEditorObj(editor_name);
		editorDocument = getDocumentObj(editor);
		refocus(editor);
		if ((editorDocument.format=='HTML') || (command=='Cut') || (command=='Paste') || (command=='Copy')) {
			editorDocument.execCommand(command,false, arguments[2])
			// give the focus back to the editor
			refocus(editor);
		} else {
			alert('Sorry! Formatting is not possible in source mode.'); 
		}
	}
	
	function cut_copy_paste(editor_name,command) {
		var editor,editorDocument;
		editor=getEditorObj(editor_name);
		editorDocument = getDocumentObj(editor);
		refocus(editor);
		try {
			editorDocument.execCommand(command,false, arguments[2])
		} catch(er) {
			alert('Sorry, your browser does not permit this operation from the toolbar. Please use the appropriate keyboard shortcut instead.');
		}
		// give the focus back to the editor
		refocus(editor);
	}
	
	function pastePlainText(editor_name) {
		var textIn,textOut,editor,editorDocument,tr;
		//if (editorDocument.format=='HTML') {
			editor=getEditorObj(editor_name);
			if (editor.browser=='mozilla') {
				executeDialog(editor,web_editor_rootpath + "core/web_editor/plainTextDlg.htm",'',605,250);
			} else {
				editorDocument = getDocumentObj(editor);
				textIn=editor.clipboardData.getData('Text');
				// the getData method returns plain text so we simply need to convert the line breaks to <br>
				textOut=textIn.replace(/\r\n\r\n/g,'\n'); //Need this since paragraphs in word are done with a double new line
				textOut=textOut.replace(/\r/g,'');
				textOut=textOut.replace(/\n/g,'</p><p>');
				textOut='<p>'+textOut+'</p>';
				textOut=textOut.replace(/<p><\/p>/g,'<p>&nbsp;</p>'); //Need this as <p></p> is impossible to see in the editor
				//delete the current selection
				format_selection(editor_name,'delete');
				//format_selection(editor_name,'insert',textOut);
				tr = editorDocument.selection.createRange();
				// collapse selection to a cursor
				tr.collapse(true);
				tr.pasteHTML(textOut);
			}
		/*} else {
			alert('Sorry! Not available in source mode.');
		}*/ 
	}
	
	function pasteFromWord(editor_name) {
		var textIn,textOut,editor,tr,pastebox,pasteBoxTextRange,editorDocument;
		var wordHTML,cleanedHTML;
		editor=getEditorObj(editor_name);
		editorDocument = getDocumentObj(editor);
		if (editorDocument.format=='HTML') {
			if (editor.browser=='mozilla') {
				executeDialog(editor,web_editor_rootpath + "core/web_editor/pasteWordDlg.htm",'',605,250);
			} else {
				pastebox=document.all(editor_name+'_pastebox');
				// paste the contents of the clipboard into the pastebox
				format_selection(editor_name,'delete');
				tr = editorDocument.selection.createRange();
				// collapse selection to a cursor
				tr.collapse(true);
				pastebox.setActive();
				pasteBoxTextRange=document.selection.createRange();
				pasteBoxTextRange.execCommand('paste');
				// grab the unclean HTML
				wordHTML=pastebox.innerHTML;
				pastebox.innerHTML='';
				// clean it
				cleanedHTML=cleanWordHTML(wordHTML);
				//delete the current selection
				tr.pasteHTML(cleanedHTML);
			}
		} else {
			alert('Sorry! Not available in source mode.');
		} 
	}
	
	function insertAtCursor(editor_name,textToInsert) {
		var editor,tr,editorDocument;
		// get the current editor object
		editor=getEditorObj(editor_name);
		editorDocument = getDocumentObj(editor);
		// set the focus to this editor
		refocus(editor);
		// get the selected range
		tr = editorDocument.selection.createRange();
		// collapse selection to a cursor
		tr.collapse(true);
		tr.pasteHTML(textToInsert);
	}
	
	function clear_link(editor_name) {
		var editor,currentRange,currentHREF,imageParentTag;
		var editorDocument,currentSelection;
		// get the current editor object
		editor=getEditorObj(editor_name);
		editorDocument = getDocumentObj(editor);
		// set the focus to this editor
		refocus(editor);
		// get the selected range
		currentSelection = getSel(editor,editorDocument);
		currentRange = getRange(editor,currentSelection);
		currentHREF = getAncestor(rangeParent(editor,currentSelection,currentRange),'a');
		if (currentHREF) {
			if (editor.browser == 'mozilla') {
				currentRange.selectNode(currentHREF);
				var tempNode = currentRange.extractContents().childNodes[0];
				var tempChild,childCounter
				for (var i=tempNode.childNodes.length-1;i>=0;i--) {
					currentRange.insertNode(tempNode.childNodes[i]);
				}
			} else {
				currentHREF.removeNode(false);
			}
		}
		refocus(editor);
	}
	
	function getAncestor(currEl,requiredTagName) {
		var undefined;
		while ((currEl.tagName==undefined) || currEl.tagName.toLowerCase() != "body") {
			if (currEl.tagName!=undefined) {
				if (currEl.tagName.toLowerCase() == requiredTagName.toLowerCase()) {
					return currEl;
				}
			}
			currEl = currEl.parentNode;
		}
		return null;
	}
	
	function insert_link(editor_name,tagType) {
		var editor,currentElement,currentValues = new Array(), newValues = null;
		var editorDocument;
		// get the current editor object
		editor=getEditorObj(editor_name);
		editorDocument = getDocumentObj(editor);
		// set the focus to this editor
		refocus(editor);
		// get the selected range
		editor.dialogEditParams.tagType = tagType;
		editor.dialogEditParams.currentSelection = getSel(editor,editorDocument);
		editor.dialogEditParams.currentRange = getRange(editor,editor.dialogEditParams.currentSelection);
		// extract any existing anchor tag information
		if (selectionType(editor,editor.dialogEditParams.currentSelection,editor.dialogEditParams.currentRange) == 'Control') {
			editor.dialogEditParams.imageTag = firstRangeItem(editor,editor.dialogEditParams.currentSelection,editor.dialogEditParams.currentRange);
			if ((editor.dialogEditParams.imageTag.tagName.toLowerCase() != "img") && (editor.dialogEditParams.imageTag.tagName.toLowerCase() != "a")) {
			 return;
			} else {
				editor.dialogEditParams.currentHREF = getAncestor(rangeParent(editor,editor.dialogEditParams.currentSelection,editor.dialogEditParams.currentRange),'a');
			}
		} else {
			editor.dialogEditParams.currentHREF = getAncestor(rangeParent(editor,editor.dialogEditParams.currentSelection,editor.dialogEditParams.currentRange),'a')
		}
		currentValues['siteURL']=web_editor_siteURL;
		currentValues['documentPickerLink']=editor.documentPickerLink;
		currentValues['urlPickerLink']=editor.urlPickerLink;
		// if we have a current link, then parse the link and get the current values
		if (editor.dialogEditParams.currentHREF) {
			currentValues['name'] = editor.dialogEditParams.currentHREF.name;
			//currentValues['class'] = currentHREF.className;
			//currentValues['style'] = currentHREF.style.cssText;
			currentValues['url'] = editor.dialogEditParams.currentHREF.href;
			currentValues['title'] = editor.dialogEditParams.currentHREF.title;
			// not sure what the differnece is between this and getAttribute('href',2);
			currentValues['target'] = editor.dialogEditParams.currentHREF.target;
		} else {
			// set default values for new link
			currentValues['url'] = '';
			currentValues['title'] = '';
			currentValues['name'] = '';
			currentValues['target'] = '';
			//currentValues['class'] = '';
			//currentValues['style'] = '';   
		}
		if ((currentValues['name'].length>0) && (tagType!='anchor')) {
			alert('Sorry! This is an anchor tag, not a link.');
		} else if ((currentValues['url'].length>0) && (tagType=='anchor')) {
			alert('Sorry! This is a link, not an anchor.');
		} else {
			currentValues['anchors'] = '';
			for ( var i = 0; i < editorDocument.anchors.length; i++) {
				if (currentValues['anchors'].length > 0) {
					currentValues['anchors'] = currentValues['anchors'] + ',';
				} 
				currentValues['anchors'] = currentValues['anchors'] + editorDocument.anchors[i].name;
			}
			if ((editor.dialogEditParams.currentHREF && editor.dialogEditParams.currentHREF.name.length > 0) || (tagType == 'anchor')) {
				newValues = executeDialog(editor,web_editor_rootpath + "core/web_editor/anchorDlg.htm",currentValues,340,150);
			} else if (editor.dialogEditParams.currentHREF || tagType != 'anchor') {
				newValues = executeDialog(editor,web_editor_rootpath + "core/web_editor/hyperlinkDlg.htm",currentValues,355,320);
			}
			editor.processLinkEdit(newValues);
		}
		// Reselect and give the focus back to the editor
		refocus(editor);
	}

	function update_image(editor_name) {
		var editor,currentValues = new Array(), newValues = null;
		var editorDocument;
		// get the current editor object
		editor=getEditorObj(editor_name);
		editorDocument = getDocumentObj(editor);
		// set the focus to this editor
		refocus(editor);
		// get the selected range
		editor.dialogEditParams.currentSelection = getSel(editor,editorDocument);
		editor.dialogEditParams.currentRange = getRange(editor,editor.dialogEditParams.currentSelection);

		// extract any existing image tag information
		editor.dialogEditParams.currentIMG = null;
		if (selectionType(editor,editor.dialogEditParams.currentSelection,editor.dialogEditParams.currentRange) == 'Control') {
			editor.dialogEditParams.currentIMG = firstRangeItem(editor,editor.dialogEditParams.currentSelection,editor.dialogEditParams.currentRange);
			if (editor.dialogEditParams.currentIMG.tagName.toLowerCase() != "img") {
				editor.dialogEditParams.currentIMG = null;
			}
		}
		// Load the currentValue array
		currentValues['siteURL']=web_editor_siteURL;
		currentValues['pickerLink']=editor.imagePickerLink;
		if (editor.dialogEditParams.currentIMG) {
			currentValues['src'] = editor.dialogEditParams.currentIMG.src;
			currentValues['width'] = editor.dialogEditParams.currentIMG.width;
			currentValues['height'] = editor.dialogEditParams.currentIMG.height;
			currentValues['alt'] = editor.dialogEditParams.currentIMG.alt;
			currentValues['border'] = editor.dialogEditParams.currentIMG.border;
			currentValues['hspace'] = editor.dialogEditParams.currentIMG.hspace;
			if (editor.dialogEditParams.currentIMG.vspace==-1) {
				currentValues['vspace'] = 0;
			} else {
				currentValues['vspace'] = editor.dialogEditParams.currentIMG.vspace;
			}
			currentValues['align'] = editor.dialogEditParams.currentIMG.align;
		} else {
			// set default values for new image
			currentValues['src'] = '';
			currentValues['width'] = '';
			currentValues['height'] = '';
			currentValues['alt'] = '';   
			currentValues['border'] = '';
			currentValues['hspace'] = '';
			currentValues['vspace'] = '';
			currentValues['align'] = '';
		}
		// open the dialog
		if (editor.imagePickerLink == '') {
			newValues = executeDialog(editor,web_editor_rootpath + "core/web_editor/imageDlg.asp",currentValues,520,400);
		} else {
			newValues = executeDialog(editor,web_editor_rootpath + "core/web_editor/imageDlg.asp?pickermode=1",currentValues,520,400);
		}
		// process the results
		editor.processImageEdit(newValues);
	}
	
	function tagHeader(tagHTML) {
		return tagHTML.match(/<([^>])*>/)[0];
	}
	
	function update_table(editor_name) {
		var editor,currentValues = new Array(), newValues = null;
		var editorDocument;
		// get the current editor object
		editor=getEditorObj(editor_name);
		editorDocument = getDocumentObj(editor);
		// set the focus to this editor
		refocus(editor);
		// get the selected range
		editor.dialogEditParams.currentSelection = getSel(editor,editorDocument);
		editor.dialogEditParams.currentRange = getRange(editor,editor.dialogEditParams.currentSelection);

		editor.dialogEditParams.currentTable = null;
		// extract any existing table tag information
		if (selectionType(editor,editor.dialogEditParams.currentSelection,editor.dialogEditParams.currentRange) == 'Control') {
			editor.dialogEditParams.currentTable = firstRangeItem(editor,editor.dialogEditParams.currentSelection,editor.dialogEditParams.currentRange);
			if (editor.dialogEditParams.currentTable.tagName.toLowerCase() != "table") {
				editor.dialogEditParams.currentTable = null;
			}
		} else {
			editor.dialogEditParams.currentTable = getAncestor(rangeParent(editor,editor.dialogEditParams.currentSelection,editor.dialogEditParams.currentRange),'table')
		}
		// Load the currentValue array
		//currentValues['siteURL']=web_editor_siteURL;
		if (editor.dialogEditParams.currentTable) {
			currentValues['rows'] = editor.dialogEditParams.currentTable.rows.length;
			currentValues['cols'] = 1;
			for (var rowCounter=0;rowCounter<editor.dialogEditParams.currentTable.rows.length;rowCounter++) {
				if (currentValues['cols']<editor.dialogEditParams.currentTable.rows[rowCounter].cells.length) {
					currentValues['cols']=editor.dialogEditParams.currentTable.rows[rowCounter].cells.length
				}
			}
			currentValues['width'] = editor.dialogEditParams.currentTable.width;
			//currentValues['height'] = editor.dialogEditParams.currentTable.height;
			currentValues['border'] = editor.dialogEditParams.currentTable.border;
			currentValues['cellSpacing'] = editor.dialogEditParams.currentTable.cellSpacing;
			currentValues['cellPadding'] = editor.dialogEditParams.currentTable.cellPadding;
			if (editor.dialogEditParams.currentTable.caption!=null) {
				currentValues['caption'] = editor.dialogEditParams.currentTable.caption.innerHTML;
			} else {
				currentValues['caption'] = '';
			} 
			currentValues['summary'] = editor.dialogEditParams.currentTable.summary;
			//currentValues['align'] = currentTable.align;
			currentValues['newTable'] = 0;
		} else {
			// set default values for new image
			currentValues['rows'] = 3;
			currentValues['cols'] = 2;
			currentValues['width'] = '';
			//currentValues['height'] = '';
			currentValues['border'] = 0;
			currentValues['cellSpacing'] = 3;
			currentValues['cellPadding'] = 3;
			currentValues['caption'] = '';
			currentValues['summary'] = '';
			//currentValues['align'] = '';
			currentValues['newTable'] = 1;
		}
		// open the dialog
		newValues = executeDialog(editor,web_editor_rootpath + "core/web_editor/tableDlg.asp",currentValues,520,400);
		// process the results
		editor.processTableEdit(currentValues,newValues);
		/*
		Issues:
		
		1) We'd like to be able to merge and seperate columns and rows to create colspans and rowspans
					this can be done via the colspan and rowspan properties of the cell but we need to look for and merge neighbouring cells
		2) We'd like to be able to format cells especially vertical alignment
		3) we'd like to be able to manipulate the table from right click context menus
		4) not sure what to do about height and width and bordercolor and bgcolor etc.
		5) We would like to add in some accesibility features like table headers and table data scope
		*/
	}
		
	function checkSpelling(textIn) {
		// Not working at the moment
		//this code works in a stand alone HTML page but not here for some reason
		var wordApp = new ActiveXObject("Word.Application");
		wordApp.WindowState = 2;
		wordApp.Visible=true;
		var wordDoc = wordApp.Documents.add();
		wordDoc.Content=textIn;
		wordDoc.CheckSpelling();
		var correctedText = wordDoc.content;
		//write text back to editor
		wordDoc.Close(false);
		wordDoc = null;
		wordApp.Application.Quit(true);
		wordApp = null;
	}
	
	function getClassList(editor_name) {
		var selector,property,undefined;
		var editor=getEditorObj(editor_name);
		var editorDocument = getDocumentObj(editor);
		var styleSheetObj = editorDocument.styleSheets[0];
		for (i=0;i<styleSheetObj.rules.length;i++) {
			selector=styleSheetObj.rules[i].selectorText;
			if (selector.substring(0,1)=='.') {
				// Populate an array of available classes here such as a dropdown
				//alert(selector);
			} 
		}
	}
	
	function getTagHierarchy(aTextRange) {
		var workingElement = aTextRange.parentElement();
		var resultArr = new Array();
		while (workingElement!=null) {
			resultArr[resultArr.length]=workingElement.tagName;
			workingElement=workingElement.parentElement;
		} 
		return resultArr;
	}
	
	function testTagHierarchy(editor_name) {
		var editor=getEditorObj(editor_name);
		var editorDocument = getDocumentObj(editor);
		var tr=editorDocument.selection.createRange();
		alert(getTagHierarchy(tr));
	}
	
	function selectParentBlock(editor_name) {
		var parentBlockElement;
		var editor=getEditorObj(editor_name);
		var editorDocument = getDocumentObj(editor);
		if (editorDocument.selection.type=='control') {
			// doesn't work for control ranges
		} else {
			var tr=editorDocument.selection.createRange();
			parentBlockElement=tr.parentElement();
			tr.moveToElementText(parentBlockElement);
			tr.select();
		} 
	}
	
	// Initialize the editor with an empty document
	// 2/2/05 new styleSheet parameter added, shouldn't cause any problems as javascript supports overloaded functions
	function init_editor(formName,field_name,fontfamily,fontsize,initial_value,styleSheet,localImagePickerLink,localDocPickerLink,localURLPickerLink) {
		var editor,editor_name,tr,headHTML,styleSheetObj,editorDocument; 
		editor_name=field_name+'_editor';  
		editor=getEditorObj(editor_name);
		editorDocument = getDocumentObj(editor);
		if (editor.browser!='mozilla') {
			editorDocument.designMode="On";
		}
		// This repeated line of code is needed to combat a bug on windows 2000 machines when accessing windows 2003 server sites
		// The bug results in the reference to the document object being lost when designmode is set.
		//http://technet2.microsoft.com/WindowsServer/en/library/8e06b837-0027-4f47-95d6-0a60579904bc1033.mspx?mfr=true
		editorDocument = getDocumentObj(editor);
		editorDocument.open();
		editorDocument.write('<html><head><base href="' + web_editor_siteURL + '/"></base>');
		editorDocument.write('</head><body></body></html>');
		editorDocument.close();
		// Default format is WYSIWYG HTML, this is just a javascript variable
		if ((styleSheet!=null) && (styleSheet!='')) {
			if (editor.browser=='mozilla') {
				var e=editorDocument.createElement('LINK');
				e.rel='stylesheet';
				e.type='text/css';
				e.href=styleSheet;
				editorDocument.getElementsByTagName("HEAD")[0].appendChild(e);
			} else {
				styleSheetObj = editorDocument.createStyleSheet(styleSheet);
			}
		//	setTimeout('getClassList(\''+editor_name+'\');',500);
		} 
		editorDocument.defaultfontfamily=fontfamily;
		editorDocument.defaultfontsize=fontsize;
		if (fontfamily!='') {
			editorDocument.body.style.fontFamily = fontfamily;
		} 
		if (fontsize!='') {
			editorDocument.body.style.fontSize = fontsize;
		}
		initial_value = stringReplace(initial_value,'href="/','href="')
		initial_value = stringReplace(initial_value,'href=/','href=')
		initial_value = stringReplace(initial_value,'src="/','src="')
		initial_value = stringReplace(initial_value,'src=/','src=')
		if (editor.browser=='mozilla') {
			try {
				editorDocument.execCommand('styleWithCSS',false,false);
			} catch(err) {
				//alert('styleWithCSS Not supported')
			}
			try {
				editorDocument.execCommand('useCSS',false,true);
			} catch(err) {
				//alert('useCSS Not supported')
			}
			initial_value = swapTag(initial_value,"strong","b");
			initial_value = swapTag(initial_value,"em","i");
		}
		if (initial_value!='') {
			if (editor.browser=='mozilla') {
				editorDocument.body.innerHTML = initial_value;
			} else {
				//load the initial value with nasty fix top hide param tags from ie
				editorDocument.body.innerHTML = initial_value;
				//.replace(/([^~])(<param[^>]*?>)/ig,'$1<!--[~$2~]-->');
			}
		}
		if (editor.browser=='mozilla') {
			editorDocument.designMode="On";
		}
		editor.imagePickerLink = localImagePickerLink;
		editor.documentPickerLink = localDocPickerLink;
		editor.urlPickerLink = localURLPickerLink;
		editorDocument.format='HTML';
		editor.dialogEditParams = new Object();
		// custom editor method for processing the results of an image add/edit operation
		// This has had to be seperated out as mozilla does not support modal dialog windows
		editor.processLinkEdit = function(newValues) {
			if (newValues != null) {
				//assign the existing link its new properties
				if (this.dialogEditParams.currentHREF) {
					if (this.dialogEditParams.currentHREF.name.length>0) {
						this.dialogEditParams.currentHREF.name = newValues['name'];
						//currentHREF.className = newValues["class"];
						//currentHREF.style.cssText = newValues["style"];
					} else {
						this.dialogEditParams.currentHREF.href = newValues['url'];
						this.dialogEditParams.currentHREF.title = newValues['title'];
						this.dialogEditParams.currentHREF.target = newValues['target'];
						//currentHREF.className = newValues["class"];
						//currentHREF.style.cssText = newValues["style"];
					}
				} else {
					//create the link around the image
					if (this.dialogEditParams.imageTag) {
						if (this.browser=='mozilla') {
							var newLinkNode;
							if (this.dialogEditParams.tagType=='anchor') {
								if (newValues["name"].length>0) {
									var newLinkNode = editorDocument.createElement('A');
									newLinkNode.name = newValues['name'];
								}
							} else if (newValues["url"].length>0) {
								var newLinkNode = editorDocument.createElement('A');
								newLinkNode.href = newValues["url"];
								newLinkNode.title = newValues["title"];
								newLinkNode.target = newValues["target"];
							}
							this.dialogEditParams.currentRange.selectNode(this.dialogEditParams.imageTag);
							newLinkNode.appendChild(this.dialogEditParams.currentRange.extractContents());
							this.dialogEditParams.currentRange.insertNode(newLinkNode);
						} else {
							var linkHTML;
							if (this.dialogEditParams.tagType=='anchor') {
								if (newValues["name"].length>0) {
									linkHTML = "<a name=\"" + newValues["name"] + "\">" + this.dialogEditParams.imageTag.outerHTML + "</a>";
								}
							} else if (newValues["url"].length>0) {
								linkHTML = '<a href="' + newValues["url"] + '"';
								if (newValues["title"] != '') {
									linkHTML = linkHTML + ' title="' + newValues["title"] + '"';
								} 
								if (newValues["target"] != '') {
									linkHTML = linkHTML + ' target="' + newValues["target"] + '"';
								} 
								linkHTML = linkHTML + '>' + this.dialogEditParams.imageTag.outerHTML + '</a>';
							}
							this.dialogEditParams.imageTag.outerHTML = linkHTML;
						}
					} else {
						//create a new link
						if (this.dialogEditParams.tagType=='anchor') {
							if (newValues['name'].length>0) {
								if (this.browser=='mozilla') {
									var newLinkNode = editorDocument.createElement('A');
									newLinkNode.name = newValues['name'];
									newLinkNode.appendChild(this.dialogEditParams.currentRange.extractContents());
									this.dialogEditParams.currentRange.insertNode(newLinkNode);
								} else {
									this.dialogEditParams.currentRange.pasteHTML('<a name="' + newValues['name'] + '">' + this.dialogEditParams.currentRange.htmlText + '</a>');
									this.dialogEditParams.currentRange.select();
								}
							}
						} else if (newValues["url"].length>0) {
							if (this.browser=='mozilla') {
								var newLinkNode = editorDocument.createElement('A');
								newLinkNode.href = newValues["url"];
								newLinkNode.title = newValues["title"];
								newLinkNode.target = newValues["target"];
								newLinkNode.appendChild(this.dialogEditParams.currentRange.extractContents());
								this.dialogEditParams.currentRange.insertNode(newLinkNode);
							} else {
								var newLink = '';
								newLink = '<a href="' + newValues["url"] + '"';
								if (newValues["title"] != '') {
									newLink = newLink + ' title="' + newValues["title"] + '"';
								} 
								if (newValues["target"] != '') {
									newLink = newLink + ' target="' + newValues["target"] + '"';
								} 
								newLink = newLink + '>' + this.dialogEditParams.currentRange.htmlText + '</a>';
								this.dialogEditParams.currentRange.pasteHTML(newLink); 
								this.dialogEditParams.currentRange.select();
							}
						} 
					}
				}
			}
		};
		// custom editor method for processing the results of an image edit operation
		// This has had to be seperated out as mozilla does not support modal dialog windows
		editor.processImageEdit = function(newValues) {
			if (newValues != null) {
				if (this.dialogEditParams.currentIMG) {
					this.dialogEditParams.currentIMG.src = newValues['src'];
					this.dialogEditParams.currentIMG.width = newValues['width'];
					this.dialogEditParams.currentIMG.height = newValues['height'];
					this.dialogEditParams.currentIMG.alt = newValues['alt'];
					this.dialogEditParams.currentIMG.border = newValues['border'];
					this.dialogEditParams.currentIMG.hspace = newValues['hspace'];
					this.dialogEditParams.currentIMG.vspace = newValues['vspace'];
					this.dialogEditParams.currentIMG.align = newValues['align'];
					this.dialogEditParams.currentIMG.style.cssText = '';
				} else {
					if (this.browser=='mozilla') {
						var newImgNode = this.document.createElement('img');
						newImgNode.src=newValues['src'];
						if (newValues['width'].length>0) {
							newImgNode.width=newValues['width'];
						}
						if (newValues['height'].length>0) {
							newImgNode.height=newValues['height'];
						}
						if (newValues['border'].length>0) {
							newImgNode.border=newValues['border'];
						}
						if (newValues['hspace'].length>0) {
							newImgNode.hspace=newValues['hspace'];
						}
						if (newValues['vspace'].length>0) {
							alert(newValues['vspace']);
							newImgNode.vspace=newValues['vspace'];
						}
						if (newValues['align'].length>0) {
							newImgNode.align=newValues['align'];
						}
						if (newValues['alt'].length>0) {
							newImgNode.alt=newValues['alt'];
						}
						this.dialogEditParams.currentRange.insertNode(newImgNode);
					} else {
						this.dialogEditParams.currentRange.collapse(true);
						var imgTag;
						imgTag = '<img src="' + newValues['src'] + '"';
						if (newValues['width'].length>0) {
							imgTag = imgTag + ' width="' + newValues['width'] + '"';
						}
						if (newValues['height'].length>0) {
							imgTag = imgTag + ' height="' + newValues['height'] + '"';
						}
						if (newValues['border'].length>0) {
							imgTag = imgTag + ' border="' + newValues['border'] + '"';
						}
						if (newValues['hspace'].length>0) {
							imgTag = imgTag + ' hspace="' + newValues['hspace'] + '"';
						}
						if (newValues['vspace'].length>0) {
							imgTag = imgTag + ' vspace="' + newValues['vspace'] + '"';
						}
						if (newValues['align'].length>0) {
							imgTag = imgTag + ' align="' + newValues['align'] + '"';
						}
						if (newValues['alt'].length>0) {
							imgTag = imgTag + ' alt="' + newValues['alt'] + '"';
						}
						imgTag = imgTag +'>';
						this.dialogEditParams.currentRange.pasteHTML(imgTag);
					}
				}
			}
			// Reselect and give the focus back to the editor
			refocus(this);
		};
		// custom editor method for processing the results of a table edit operation
		// This has had to be seperated out as mozilla does not support modal dialog windows
		editor.processTableEdit = function(currentValues,newValues) {
			if (newValues != null) {
				if (this.dialogEditParams.currentTable) {
					// Update the simple table properties
					this.dialogEditParams.currentTable.width = newValues['width'];
					//this.dialogEditParams.currentTable.height = newValues['height'];
					this.dialogEditParams.currentTable.border = newValues['border'];
					this.dialogEditParams.currentTable.cellSpacing = newValues['cellSpacing'];
					this.dialogEditParams.currentTable.cellPadding = newValues['cellPadding'];
					// Caption is handled slightly differently as it is a child element and not an attribute of the table element
					// as such currentTable.caption only exists when the element exists
					if (newValues['caption']=='') {
						if (this.dialogEditParams.currentTable.caption) {
							if (this.browser=='mozilla') {
								this.dialogEditParams.currentTable.removeChild(this.dialogEditParams.currentTable.caption);
							} else {
								// We cannot delete the caption as it causes an internal error in ie.
								this.dialogEditParams.currentTable.caption.innerHTML = '';
							}
						}
					} else {
						if (this.dialogEditParams.currentTable.caption) {
							if (this.browser=='mozilla') {
								// Delete the existing one and add a new one to force the update of the caption.
								this.dialogEditParams.currentTable.removeChild(this.dialogEditParams.currentTable.caption);
								var newCaption = this.document.createElement('caption');
								newCaption.innerHTML = newValues['caption'];
								this.dialogEditParams.currentTable.appendChild(newCaption);
							} else {
								this.dialogEditParams.currentTable.caption.innerHTML = newValues['caption'];
							}
						} else {
							var newCaption = this.document.createElement('caption');
							newCaption.innerHTML = newValues['caption'];
							this.dialogEditParams.currentTable.appendChild(newCaption);
						}
					} 
					this.dialogEditParams.currentTable.summary = newValues['summary'];
					if (currentValues['rows']!=newValues['rows']) {
						// The number of rows in this table have changed
						if (currentValues['rows']>newValues['rows']) { 
							//The number of rows has been reduced
							//Delete unwanted rows
							while (this.dialogEditParams.currentTable.rows.length>newValues['rows']) {
								this.dialogEditParams.currentTable.deleteRow(-1);//currentTable.rows.length-1
							}
						} else {
							//The number of rows has been increased
							while (this.dialogEditParams.currentTable.rows.length<newValues['rows']) {
								//Insert blank rows
								newRow = this.dialogEditParams.currentTable.insertRow(-1);
								for (cellCounter=0;cellCounter<newValues['cols'];cellCounter++) {
									//insert blank cells
									newRow.insertCell(-1);
								}
							}
						}
					}
					if (currentValues['cols']!=newValues['cols']) {
						// The number of columns has changed
						for (rowCounter=0;rowCounter<this.dialogEditParams.currentTable.rows.length;rowCounter++) {
							if (currentValues['cols']>newValues['cols']) {
								// The number of columns has decreased
								while (this.dialogEditParams.currentTable.rows[rowCounter].cells.length>newValues['cols']) {
									this.dialogEditParams.currentTable.rows[rowCounter].deleteCell(-1);//currentTable.rows[rowCounter].cells.length-1
								}
							} else {
								// The number of columns has increased
								while (this.dialogEditParams.currentTable.rows[rowCounter].cells.length<newValues['cols']) {
									this.dialogEditParams.currentTable.rows[rowCounter].insertCell(-1);
								}
							}
						}
					}
				} else {
					if (this.browser=='mozilla') {
						var newTableNode = this.document.createElement('table');
						if (newValues['width'].length>0) {
							newTableNode.width=newValues['width'];
						}
						//if (newValues['height'].length>0) {
						//	newTableNode.height = newValues['height'];
						//}
						newTableNode.border=newValues['border'];
						/*if (newValues['align'].length>0) {
							newTableNode.align= newValues['align'];
						}*/
						newTableNode.cellSpacing = newValues['cellSpacing'];
						newTableNode.cellPadding = newValues['cellPadding'];
						if (newValues['summary'].length>0) {
							newTableNode.summary = newValues['summary'];
						}
						if (newValues['caption']!='') {
							newTableNode.createCaption().innerHTML = newValues['caption'];
						}
						for (var rows=0;rows<newValues['rows'];rows++){
							newRow = newTableNode.insertRow(0);
							for (cellCounter=0;cellCounter<newValues['cols'];cellCounter++) {
								//insert blank cells
								newRow.insertCell(0);
							}
						}
						this.dialogEditParams.currentRange.insertNode(newTableNode);
					} else {
						this.dialogEditParams.currentRange.collapse(true);
						tableTag = '<table';
						if (newValues['width'].length>0) {
							tableTag = tableTag + ' width="' + newValues['width'] + '"';
						}
						//if (newValues['height'].length>0) {
						//	tableTag = tableTag + ' height="' + newValues['height'] + '"';
						//}
						tableTag = tableTag + ' border="' + newValues['border'] + '"';
						/*if (newValues['align'].length>0) {
						// tableTag = tableTag + ' align="' + newValues['align'] + '"';
						}*/
						tableTag = tableTag + ' cellspacing="' + newValues['cellSpacing'] + '"';
						tableTag = tableTag + ' cellpadding="' + newValues['cellPadding'] + '"';
						if (newValues['summary'].length>0) {
							tableTag = tableTag + ' summary="' + newValues['summary'] + '"';
						}
						tableTag = tableTag +'>\n';
						if (newValues['caption'].length>0) {
							tableTag = tableTag + '<caption>' + newValues['caption'] + '</caption>\n';
						}
						for (var rows=0;rows<newValues['rows'];rows++){
							tableTag = tableTag + '<tr>\n';
							for (var cols=0;cols<newValues['cols'];cols++){
								tableTag = tableTag + ' <td></td>\n';
							}
							tableTag = tableTag + '</tr>\n';
						}    
						tableTag = tableTag + '</table>\n';
						this.dialogEditParams.currentRange.pasteHTML(tableTag);
					}
				}
			}
			// Reselect and give the focus back to the editor
			//this.dialogEditParams.currentRange.select();
			refocus(this);
		};
		//Only used by mozilla to get around paste limitations this method is called by 
		//the pasteDialogs to insert the processed paste text at the current cursor position
		editor.processPasteDlg = function(incomingHTML) {
			var currentSelection,currentRange,fragment;
			currentSelection = getSel(this,this.document);
			currentRange = getRange(this,currentSelection);
			currentRange.deleteContents();
			currentRange.collapse(true);
			fragment = this.document.createElement('body');
			fragment.innerHTML = incomingHTML;
			for (var i=fragment.childNodes.length-1;i>=0;i--) {
				currentRange.insertNode(fragment.childNodes[i]);
			}
		}
	}

	// Swap between WYSIWYG mode and raw HTML mode
	function swap_editor_mode(editor_name) {
		var editor,currentSelection,currentRange;
		editor=getEditorObj(editor_name);
		var editorDocument = getDocumentObj(editor);
		currentSelection = getSel(editor,editorDocument);
		currentRange = getRange(editor,currentSelection);
		currentRange.collapse;
		// need to disable format function in text mode
		if (editorDocument.format=="HTML") {
			if (editor.browser=='mozilla') {
				var html = document.createTextNode(editorDocument.body.innerHTML);
				editorDocument.body.innerHTML = "";
				editorDocument.body.appendChild(html);
			} else {
				editorDocument.body.innerText = editorDocument.body.innerHTML;
			}
			editorDocument.body.style.fontFamily = 'monospace';
			editorDocument.body.style.fontSize = '10pt';
			editorDocument.body.style.color = 'black';
			editorDocument.format='Text';
		}
		else {
			if (editor.browser=='mozilla') {
				var html = editorDocument.body.ownerDocument.createRange();
				html.selectNodeContents(editorDocument.body);
				editorDocument.body.innerHTML = html.toString();
			} else {
				//editorDocument.body.innerHTML = editorDocument.body.innerText;
				editorDocument.body.innerHTML = editorDocument.body.innerText;
				//.replace(/([^~])(<param[^>]*?>)/ig,'$1<!--[~$2~]-->');
			}
			editorDocument.body.style.fontFamily = editorDocument.defaultfontfamily;
			editorDocument.body.style.fontSize = editorDocument.defaultfontsize;
			editorDocument.body.style.color = '';
			editorDocument.format='HTML';
		}
		refocus(editor);
	}
	
	function build_editor(field_name,width,height,viewsource) {
		var editor, editor_name;
		editor_name=field_name+'_editor';
		document.write('<table cellspacing=0 cellpadding=0 border=0 width=' + width + '>');
		document.write('<tr><td bgcolor="silver">&nbsp;');
		document.write('<a href="javascript:void(format_selection(\'' + editor_name + '\',\'Undo\'));" title="Undo"><img src="'+web_editor_rootpath+'core/web_editor/images/undo.gif" border=0 alt="Undo" width="24" height="22"></a>');
		document.write('<a href="javascript:void(format_selection(\'' + editor_name + '\',\'Redo\'));" title="Redo"><img src="'+web_editor_rootpath+'core/web_editor/images/redo.gif" border=0 alt="Redo" width="24" height="22"></a>');
		document.write('<img src="'+web_editor_rootpath+'core/web_editor/images/divider.gif">');
		document.write('<a href="" onclick="format_selection(\'' + editor_name + '\',\'JustifyLeft\');return false;" title="Left justify"><img src="'+web_editor_rootpath+'core/web_editor/images/jleft.gif" border=0 alt="Left justify" width="24" height="22"></a>');
		document.write('<a href="" onclick="format_selection(\'' + editor_name + '\',\'JustifyCenter\');return false;" title="Justify centre"><img src="'+web_editor_rootpath+'core/web_editor/images/jcenter.gif" border=0 alt="Justify center" width="24" height="22"></a>');
		document.write('<a href="" onclick="format_selection(\'' + editor_name + '\',\'JustifyRight\');return false;" title="Right justify"><img src="'+web_editor_rootpath+'core/web_editor/images/jright.gif" border=0 alt="Right justify" width="24" height="22"></a>');
		document.write('<a href="" onclick="format_selection(\'' + editor_name + '\',\'JustifyFull\');return false;" title="Justify"><img src="'+web_editor_rootpath+'core/web_editor/images/justify.gif" border=0 alt="Justify" width="24" height="22"></a>');
		document.write('<img src="'+web_editor_rootpath+'core/web_editor/images/divider.gif">');
		document.write('<a href="" onclick="format_selection(\'' + editor_name + '\',\'InsertUnorderedList\');return false;" title="Bulleted list"><img src="'+web_editor_rootpath+'core/web_editor/images/ulist.gif" border=0 alt="Bulletted list" width="24" height="22"></a>');
		document.write('<a href="" onclick="format_selection(\'' + editor_name + '\',\'InsertOrderedList\');return false;" title="Numbered list"><img src="'+web_editor_rootpath+'core/web_editor/images/olist.gif" border=0 alt="Numbered list" width="24" height="22"></a>');
		document.write('<a href="" onclick="format_selection(\'' + editor_name + '\',\'Indent\');return false;" title="Indent"><img src="'+web_editor_rootpath+'core/web_editor/images/indent.gif" border=0 alt="Indent" width="24" height="22"></a>');
		document.write('<a href="" onclick="format_selection(\'' + editor_name + '\',\'Outdent\');return false;" title="Outdent"><img src="'+web_editor_rootpath+'core/web_editor/images/outdent.gif" border=0 alt="Outdent" width="24" height="22"></a>');
		document.write('<img src="'+web_editor_rootpath+'core/web_editor/images/divider.gif">');
		document.write('<a href="" onclick="cut_copy_paste(\'' + editor_name + '\',\'Cut\');return false;" title="Cut"><img src="'+web_editor_rootpath+'core/web_editor/images/cut.gif" border=0 alt="Cut" width="24" height="22"></a>');
		document.write('<a href="" onclick="cut_copy_paste(\'' + editor_name + '\',\'Copy\');return false;" title="Copy"><img src="'+web_editor_rootpath+'core/web_editor/images/copy.gif" border=0 alt="Copy" width="24" height="22"></a>');
		document.write('<a href="" onclick="cut_copy_paste(\'' + editor_name + '\',\'Paste\');return false;" title="Paste"><img src="'+web_editor_rootpath+'core/web_editor/images/paste.gif" border=0 alt="Paste" width="24" height="22"></a>');
		document.write('<a href="javascript:void(pastePlainText(\''+ editor_name + '\'));" title="Paste as plain text"><img src="'+web_editor_rootpath+'core/web_editor/images/paste-text.gif" border=0 alt="Paste as plain text" width="24" height="22"></a>');
		document.write('<a href="javascript:void(pasteFromWord(\''+ editor_name + '\'));" title="Paste from Word"><img src="'+web_editor_rootpath+'core/web_editor/images/paste-word.gif" border=0 alt="Paste from MS Word" width="24" height="22"></a>');
		//document.write('<a href="javascript:void(selectParentBlock(\''+ editor_name + '\'));"><img src="'+web_editor_rootpath+'core/web_editor/images/expand.gif" border=0 alt="select parent block" width="24" height="22"></a>');
		document.write('</td></tr>');
		document.write('<tr><td bgcolor="gray"><img src="' + web_editor_rootpath + 'images/spacer.gif" width="' + (width+1) + '" height="1"></td></tr>');
		document.write('<tr><td bgcolor="silver">&nbsp;');
		document.write('<a href="" onclick="insert_link(\'' + editor_name + '\',\'link\');return false;" title="Create/Edit hyperlink"><img src="'+web_editor_rootpath+'core/web_editor/images/link.gif" border=0 alt="Create/Edit hyperlink" width="24" height="22"></a>');
		document.write('<a href="" onclick="insert_link(\'' + editor_name + '\',\'anchor\');return false;" title="Create/Edit anchor"><img src="'+web_editor_rootpath+'core/web_editor/images/anchor.gif" border=0 alt="Create/Edit anchor" width="24" height="22"></a>');
		document.write('<a href="" onclick="clear_link(\'' + editor_name + '\');return false;" title="Remove hyperlink/anchor"><img src="'+web_editor_rootpath+'core/web_editor/images/unlink.gif" border=0 alt="Remove hyperlink/anchor" width="24" height="22"></a>');
		document.write('<img src="'+web_editor_rootpath+'core/web_editor/images/divider.gif">');
		document.write('<a href="" onclick="update_image(\'' + editor_name + '\');return false;" title="Insert/Edit image"><img src="'+web_editor_rootpath+'core/web_editor/images/image.gif" border=0 alt="Insert/Edit image" width="24" height="22"></a>');
		document.write('<img src="'+web_editor_rootpath+'core/web_editor/images/divider.gif">');
		document.write('<a href="javascript:void(update_table(\'' + editor_name + '\'));" title="Insert/Edit table"><img src="'+web_editor_rootpath+'core/web_editor/images/table.gif" border=0 alt="Insert/Edit table" width="24" height="22"></a>');
		document.write('<img src="'+web_editor_rootpath+'core/web_editor/images/divider.gif">');
		document.write('<a href="" onclick="format_selection(\'' + editor_name + '\',\'Bold\');return false;" title="Bold"><img src="'+web_editor_rootpath+'core/web_editor/images/bold.gif" border=0 alt="Bold" width="24" height="22"></a>');
		document.write('<a href="" onclick="format_selection(\'' + editor_name + '\',\'Italic\');return false;" title="Italic"><img src="'+web_editor_rootpath+'core/web_editor/images/italic.gif" border=0 alt="Italic" width="24" height="22"></a>');
		document.write('<a href="" onclick="format_selection(\'' + editor_name + '\',\'Underline\');return false;" title="Underline"><img src="'+web_editor_rootpath+'core/web_editor/images/underline.gif" border=0 alt="Underline" width="24" height="22"></a>');
		document.write('<img src="'+web_editor_rootpath+'core/web_editor/images/divider.gif">');
		document.write('<a href="" onclick="format_selection(\'' + editor_name + '\',\'Subscript\');return false;" title="Subscript"><img src="'+web_editor_rootpath+'core/web_editor/images/sub.gif" border=0 alt="Subscript" width="24" height="22"></a>');
		document.write('<a href="" onclick="format_selection(\'' + editor_name + '\',\'Superscript\');return false;" title="Superscript"><img src="'+web_editor_rootpath+'core/web_editor/images/sup.gif" border=0 alt="Superscript" width="24" height="22"></a>');
		document.write('<img src="'+web_editor_rootpath+'core/web_editor/images/divider.gif">');
		document.write('<a href="" onclick="format_selection(\'' + editor_name + '\',\'FormatBlock\',\'<h1>\');return false;" title="Level 1 header"><img src="'+web_editor_rootpath+'core/web_editor/images/h1.gif" border=0 alt="Leve1 1 header" width="24" height="22"></a>');
		document.write('<a href="" onclick="format_selection(\'' + editor_name + '\',\'FormatBlock\',\'<h2>\');return false;" title="Level 2 header"><img src="'+web_editor_rootpath+'core/web_editor/images/h2.gif" border=0 alt="Leve1 2 header" width="24" height="22"></a>');
		document.write('<a href="" onclick="format_selection(\'' + editor_name + '\',\'FormatBlock\',\'<h3>\');return false;" title="Level 3 header"><img src="'+web_editor_rootpath+'core/web_editor/images/h3.gif" border=0 alt="Leve1 3 header" width="24" height="22"></a>');
		document.write('<a href="" onclick="format_selection(\'' + editor_name + '\',\'FormatBlock\',\'<h4>\');return false;" title="Level 4 header"><img src="'+web_editor_rootpath+'core/web_editor/images/h4.gif" border=0 alt="Leve1 4 header" width="24" height="22"></a>');
		document.write('<a href="" onclick="format_selection(\'' + editor_name + '\',\'FormatBlock\',\'<h5>\');return false;" title="Level 5 header"><img src="'+web_editor_rootpath+'core/web_editor/images/h5.gif" border=0 alt="Leve1 5 header" width="24" height="22"></a>');
		document.write('<a href="" onclick="format_selection(\'' + editor_name + '\',\'FormatBlock\',\'<p>\');return false;" title="Remove header"><img src="'+web_editor_rootpath+'core/web_editor/images/remove_h.gif" border=0 alt="Remove header" width="24" height="22"></a>');
		//document.write('<a href="" onclick="insertAtCursor(\'' + editor_name + '\',\'<hr>\');return false;"><img src="'+web_editor_rootpath+'core/web_editor/images/hr.gif" border=0 alt="Insert Horizontal Rule"></a>');
		document.write('<a href="javascript:void(format_selection(\'' + editor_name + '\',\'InsertHorizontalRule\'));" title="Horizontal rule"><img src="'+web_editor_rootpath+'core/web_editor/images/hr.gif" border=0 alt="Insert Horizontal Rule" width="24" height="22"></a>');
		document.write('</td></tr>');
		document.write('<tr><td bgcolor="silver">');
		document.write('<input type="hidden" name="' + field_name + '">');
		document.write('<iframe name="' + editor_name + '" width="' + width + '" height="' + height + '" id="' + editor_name + '" src="'+web_editor_rootpath+'core/web_editor/blank.htm"></iframe>');
		document.write('<div id="' + editor_name + '_pastebox" contenteditable="true" style="width:1px;height:1px;border:0px solid black;overflow:hidden;"></div>');
		// The following code loads the deprecated DHTML Edit Control rather than the MSHTML Editor which is used by default in later browsers
		//document.write('<object classid="clsid:2D360201-FFF5-11d1-8D03-00A0C959BC0A" width="'+width+'" height="'+height+'" id="'+editor_name+'">');
		//document.write('<param name="ScrollbarAppearance" value="0">');
		//document.write('</object>');
		document.write('</td></tr>');
		document.write('<tr><td bgcolor="silver">');
		if (viewsource==1) {
			document.write('&nbsp;<a href="" onclick="return false;" onmouseup="swap_editor_mode(\'' + editor_name + '\')"><img src="'+web_editor_rootpath+'core/web_editor/images/mode.gif" border=0 alt="toggle html/source" width="24" height="22"></a><img src="'+web_editor_rootpath+'core/web_editor/images/divider.gif">');
		} 
		document.write('</td></tr>');
		document.write('</table>');
	}

	function save_editor(form,field_name,xhtml) {
		var editor, editor_name;
		editor_name=field_name+'_editor';
		editor=getEditorObj(editor_name);
		var editorDocument = getDocumentObj(editor);
		if (editorDocument.format=="Text") {
			swap_editor_mode(editor_name)
		}
		field_value=editorDocument.body.innerHTML;
		if (editor.browser!='mozilla') {
			// Undo nasty param hiding fix in ie
			field_value = field_value;
			//.replace(/<!--\[~(<param[^>]*?>)~\]-->/ig, '$1');
		}
		// Made more specific to text that NEEDS to be replaced
		field_value = correctEditorPaths(field_value,web_editor_siteURL)
		/*field_value = stringReplace(field_value,'href="'+web_editor_siteURL+'/#','href="#');
		field_value = stringReplace(field_value,'href="'+web_editor_siteURL+'/','href="/');
		field_value = stringReplace(field_value,'src="'+web_editor_siteURL+'/#','src="#');
		field_value = stringReplace(field_value,'src="'+web_editor_siteURL+'/','src="/');*/
		field_value = field_value.replace(/<p>&nbsp;<\/p>/ig, '');
		field_value = encodeEmailAddresses(field_value);
		field_value = buildCompliantHTML(field_value);
		if (xhtml) {
			field_value = ensureTagClosure(field_value);
			field_value = fixListNesting(field_value);
			field_value = expandMinimalisedAttributes(field_value);
		} 
		formfield=eval('form.'+field_name);
		formfield.value=field_value;
	}

/*
Other stuff

Tables
	- when a table has no cellspacing or padding it becomes impossible to select!
	- ideally it should not be possible to set these attributes to zero which is fine except when pasting from word.
	- only thing to do would be to disallow these attributes in word cleanup.
Undo/Redo - works in both text only and html mode and as such can do strange things 
Find/Replace
special characters
print
style,fonts,colours
spelling
*/
