
// VisualEditor (object)

function VisualEditor()
{
  
  // ===================================================================
  // Settings
  // ===================================================================
	this.ALLOW_HTML_ENTRY = true;
	this.ALLOW_LINK_ONLY_PASTE = true;
	this.PREVIEW_IS_HIDDEN = true;

  	this.IMAGES_LOCATION = "http://www.net-conception.co.uk/CmnAssets/EIY/"; 
  	this.DEFAULT_ALIGNMENT = "left";
	//  this.EDIT_SOURCE = true; // if false, the mode tabs are never exposed
  	this.ENABLE_IFRAME = true; // if false, the IFRAME is never appended
                             // this field is also used to detect if we 
                             // in VisEd or html mode (true) or
                             // preview only mode (false)
  	this.ENABLE_KEYBOARD_CONTROLS = true; 
  	this.ALLOW_FULL_PASTE = true;

	this.DEBUG = false;
  	this.DEBUG_CHECK_FORMATTING = false;

  	this.frameBodyStyle = "border:0; margin:2px; padding:8px 2px 8px 2px; _padding:8px 2px 8px 2px; width:auto; font-family: arial, Helvetica, sans-serif; font-size: 10pt;";  
  	//above line adds CSS notation to the body of the IFRAME
    
  
  	// Design Mode Toolbar Data
  	// First of each pair is the display name, second is the value.
  	// If name ends in asterisk, then it is the default (otherwise first one is default.)
  	// If value is null, then it is same as display name.
  	// Keep values lowercase for compatibility between IE and Moz.
  	this.FONTS = [
    	[ font, ''], 
  		['Arial', 'arial'], 
    	['Courier', 'courier new'],
    	['Georgia', 'georgia'], 
    	['Lucida Grande', 'lucida grande'], 
    	['Times', 'times new roman'],
    	['Trebuchet', 'trebuchet ms'], 
    	['Verdana', 'verdana'],
    	['Webdings', 'webdings']
  	];
  
  	this.FONT_SIZES = [
    	[ huge, '5'], 
    	[ large, '4'], 
    	[ normal_size + "*", '3'], 
    	[ small, '2'], 
    	[ tiny, '1']
  	];  
  
  	this.BACKCOLOR = Detect.IE() ? 'BackColor' : 'HiliteColor';  
  
 	// - Definition of buttons for the Visual Editor in the form:
	// - If equals "-", it signifies a gap
	// - If equals "b", it signifies a new line (break)
	// - If 4 parameters, it's a normal button: [ExecCommand & button id, tooltip, icon name, depressable]
	// - If 5 parameters, it's a drop down list (Select): [Select ID, not used, not used, not used, list]
	// - If 7 parameters, it's a special button: [ExecCommand, tooltip, icon name, visible, not used, onclick fn, onmouseup fn]
	this.CONTROLS = [
    	['FontName', null, null, false, this.FONTS],
		['-'],
    	['FontSize', null, null, false, this.FONT_SIZES],
		['-'],
		['ForeColor', 'Text colour', 'PaintBtn', true],    
		['-'],
		['RemoveFormat', 'Revert to Normal text', 'NormalBtn', true],
		['Bold', 'Bold', 'Bold Btn', true],
    	['Italic', 'Italic', 'Italic Btn', true],
		['-'],    
    	['JustifyLeft', 'Align left', 'LeftAlign', true],
    	['JustifyCenter', 'Centre', 'CentreAlign', true],
    	['JustifyRight', 'Align right', 'RightAlign', true],
    	['JustifyFull', 'Justify', 'JustifyAlign', true],
 		['b'],   
    	['InsertOrderedList', 'Numbered point', 'NumberedBtn', true],
    	['InsertUnorderedList', 'Bullet point', 'Bullet Btn', true],
    	['Indent', 'Indent', 'IndentBtn', true],
    	['Outdent', 'Outdent', 'OutdentBtn', true],
		['-'],
		['Add_Image', 'Image', 'Picture Btn', true, null, '', 'showImageDialog (true);'],
		['CreateLink', 'Link', 'Link Btn', true, null, '', 'showLinkDialog (true);'],
		['AddImageLink', 'Image link', 'Picture Link Btn', true, null, '', 'showImageLinkDialog (true);'],
		['-'],
		['AddDownload', 'Download', 'Download Btn', true, null, '', 'showDownloadDialog (true);'],
		['-'],
		['AddMailLink', 'Mail link', 'Mail Link Btn', true, null, '', 'showMailDialog (true);'],
		['-'],
		['AdvFeatures', 'Show advanced features', 'AdvFeatures', true, null, '', 'showAdvFeatures ();'],	
		['-'],
//		['AddTable', 'Table', 'Table Btn', false, null, '', 'showTableDialog ();'],	
//		['AddBox', 'Box', 'Box Btn', false, null, '', 'showBoxDialog ();'],	
//		['-'],
		['HtmlEd', 'HTML Editor', 'HtmlEd', false, null, '', 'VisEd.ShowSourceEditor();'],			
		['WysiwygEd', 'WYSIWYG Editor', 'WYSIWYG', false, null, '', 'VisEd.ShowVisualEditor();'],			
		['-'],
		['NoAdvFeatures', 'Hide advanced features', 'NoAdvFeatures', true, null, '', 'noAdvFeatures ();']	
	]; 
    
  	this.DEPRESSABLE = ["Bold", "Italic", "JustifyLeft", "ForeColor", this.BACKCOLOR, 
    					"JustifyCenter", "JustifyRight", "InsertOrderedList", "InsertUnorderedList", 
    					"CreateLink", "Indent", "Outdent", "Blockquote"];
  
  

	// - Determine which buttons are seen in which mode
	this.BASIC_WYSIWYG_CTRLS 		= ['ForeColor', 'RemoveFormat', 'Bold', 'Italic', 
										 		'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyFull', 
										 		'InsertOrderedList', 'InsertUnorderedList', 'Indent', 'Outdent', 
										 		'Add_Image', 'CreateLink', 'AddImageLink', 'AddDownload',
										 		'AddMailLink'];
//	this.ADV_WYSIWYG_CTRLS	 		= ['AddTable', 'AddBox', 'HtmlEd', 'NoAdvFeatures'];
	this.ADV_WYSIWYG_CTRLS	 		= ['HtmlEd', 'NoAdvFeatures'];
	this.NON_ADV_WYSIWYG_CTRLS 	= ['AdvFeatures'];
	this.BASIC_HTML_ED_CTRLS 		= ['WysiwygEd'];
  
	// - Associate functions with control keys
	this.KEY_COMMANDS = [];
  	this.KEY_COMMANDS.push(['CTRL_Z', null, 'VisEd.frameDoc.execCommand("Undo", false, "")']);
  	this.KEY_COMMANDS.push (['CTRL_T', null, 'togglePreview(e);']);
  	this.KEY_COMMANDS.push(['CTRL_Y', null, 'VisEd.frameDoc.execCommand("Redo", false, "")']);
	
  	// Properties
  	this.id = "VisEd"; //the name of this object within the window
  	this.divId = "VisEd"; //the name of the container surrounding the textarea
  	this.frameId = "VisualEditorframe"; 
  	this.debugField;
  	this.UNSUPPORTED_MODE = 0;
  	this.DESIGN_MODE = 1;
  	this.HTML_MODE = 2;
	this.ADV_CTRLS_ON = false;
  	this.START_MODE = this.DESIGN_MODE;  // start in WYSIWYG mode by default
  	this.mode;
  

  	// The make() method
  	this.make = function() 
  	{   
		this.div = document.getElementById(this.divId);   //get the container surrounding the textarea
    	if (!this.div) 
	  		return; 
		
		// store this user-defined object in a globally accessible
		// variable that is unique to the rich editor object
    	eval("window." + this.id + " = this");
    
    	// get the textarea within the rich editor    
    	this.textarea_orig = this.div.getElementsByTagName('textarea')[0];
    
    	// create palette container 
	 	var xyz = createElementandAppend('div', 'palette', "");
    	this.palette = xyz;
    
    	// create style container (called editarea) for the bars and editable areas, copy the
    	// textarea into this container, and hide the original textarea   
    	this.editarea = createElementandAppend('div', 'editarea', this.div);
    	appendClearObj(this.editarea);

    	/* Create a new textarea for Edit Html mode. We base the new on the one
      already in the page, but don't move or delete the one already in the
      page. This is so that the names and positions of the form elements on the
      page are the same when the page is first loaded and when the user leaves
      the page. Firefox will only cache form data (so that you can click "back"
      and see all the values as you left them) if that invariant is maintained. */
    	this.textarea = this.textarea_orig.cloneNode(true);
    	this.textarea.name = "htmlPostBody";

    	// need this so that FF's form cache gets copied in to new textarea
    	this.textarea.value = this.textarea_orig.value;

    	this.textarea_orig.id = "hiddenTextarea";

    	// Workaround for Opera bug that prevents manipulation of
    	// textareas that have display:none
    	this.textarea_orig.style.visibility = "hidden";
    	this.textarea_orig.style.position = "absolute";
    
    	this.editarea.appendChild(this.textarea);
    
    	// create toolbars container    
    	this.buttonBox = createElementandInsertBefore ('div', 'buttonBox', this.editarea, this.textarea);   
    	this.buttonBox.setAttribute('unselectable','on');
    	appendClearObj(this.buttonBox);
    
    	// create Design Mode toolbar
    	this.formatbar = this.createToolbar('formatbar', this.getRichBarButtonHTML());
        
    	// hide the rich bar if not started in design mode
    	if (this.START_MODE != this.DESIGN_MODE)
      	this.formatbar.style.display = 'none';
          
    	appendClearObj(this.buttonBox);      
    
    	// hide textarea, if started in design mode
    	if (this.START_MODE != this.HTML_MODE)
      	this.textarea.style.display = "none";   
    
    	// add editor frame to page
    	if (this.ENABLE_IFRAME) 
		{
      	var iframe = createElementandAppend('iframe', 'VisualEditorframe', this.editarea);
      	if (Detect.OPERA()) 
	    		iframe.src = 'serverid';

      	// get all objects needed to transform the frame      
      	this.frame = getIFrame(this.frameId);
      	this.frameWin = this.frame.contentWindow;
      	this.frameDoc = getIFrameDocument(this.frame);
      
      	// turn on rich-text editing for the frame ... for IE
      	// (which has to be BEFORE its body is set) 
      	if (Detect.IE()) 
	    		this.frameDoc.designMode = "On";
      
      	// write the body, or else the frame's Document object can't be acted upon.      
      	setIFrameBody(this.frame, this.frameBodyStyle + 'text-align:' + this.DEFAULT_ALIGNMENT);
      
      	// Now, IE needs a different traversal method to affect the IFRAME and BODY
      	// and one HTML container to prevent <p> tags from being inserted after 
      	// each carriage return.
      	if (Detect.IE()) 
	  		{
        		this.frame = getElement(this.frameId);
        		this.frameDoc = this.frame.contentWindow.document;
        		this.frameDoc.body.innerHTML = "<div></div>";
      	}
      
      	// add event handling
      
      	//Now, IE needs a different traversal method to set IFRAME events
      	var iframe = (Detect.IE()) ? getIFrame(this.frameId) : this.frame;
      	setIFrameEvent(iframe, "click", CheckFormatting);      
      
      	if (this.ENABLE_KEYBOARD_CONTROLS) 
	  		{
        		if (Detect.IE()) 
				{
          		// the key codes aren't captured correctly for IE if called during keypress
          		setIFrameEvent(iframe, "keydown", this.activateKeyCommands);
        		} 
				else 
          		setIFrameEvent(iframe, "keypress", this.activateKeyCommands);
      	}
      
      	if (!this.ALLOW_FULL_PASTE)
        		this.frameDoc.body.onbeforepaste = cleanPaste;	// Ensure html is cleaned up prior to a paste action
		
      	if (this.ALLOW_LINK_ONLY_PASTE)
        		this.frameDoc.body.onbeforepaste = smartPaste;  // Ensure html is cleaned up prior to a paste action
      
      	if (this.APPEND_TO_ACTIONS) 
	  		{
        		for (var x = 0; x < this.APPEND_TO_ACTIONS.length; x++) 
				{
          		var prepend = false;
          		if (this.APPEND_TO_ACTIONS[x][2]) 
						prepend = true;

					this.appendToAction (this.APPEND_TO_ACTIONS[x][0], this.APPEND_TO_ACTIONS[x][1], prepend);
        		}
      	}
      
      	// turn on rich-text editing for the frame ... for Mozilla
      	// (which has to be AFTER its body is set, and any time after the display 
      	//  style property is changed.)
      
      	if (!Detect.IE()) 
	    		this.frameDoc.designMode = "On";
      
      	// hide iframe, if started in html mode
      	if (this.START_MODE != this.DESIGN_MODE)
        		this.frame.style.display = "none";   
      
    	} // end of ENABLE_IFRAME block
          
    	// For Debug Mode
    	if (this.DEBUG) 
		{
      	var debugtitle = createElementandAppend ('div', 'debugtitle', this.editarea); 
      	debugtitle.innerHTML = 'Debug output:';
      	this.debugField = createElementandAppend ('textarea', 'debug', this.editarea); 
    	}
    
    	//move content from textarea to IFRAME
    	if (this.START_MODE == this.DESIGN_MODE) 
		{
      	this.mode = this.DESIGN_MODE;
      	this.ShowVisualEditor();
	  
      	// remember to fill IE with a div to prevent double-spacing
      	if (Detect.IE() && (this.frameDoc.body.innerHTML == ''))
        		this.frameDoc.body.innerHTML = '<div></div>';
		}
    	else
      	this.mode = this.HTML_MODE;

		document.close();
  	}   // make
	
}  // VisualEditor


function CorrectLinkAutoCompletionInImages() 
{
  
  	if (!Detect.IE()) 
    	return; // only IE currently has hyperlink auto-completion
  
  	var parent = getSelectedParentNode();
  
  	// if typed into the WYSIWYG edit area, auto-complete the end of the certain
  	// tags and bypass IE's auto-complete feature, so that a link doesn't wind up
  	// in the href or src attributes 
  	// (i.e. <img src="<a href="http://p/">http://p/</a>">)
  	try 
  	{
    	var httpImgPattern = new RegExp('&lt;img[^>]+src="[^"]+"$', 'gi');
    	var httpAPattern = new RegExp('&lt;a[^>]+href="[^"]+"$', 'gi');
    	var isImg = httpImgPattern.test(parent.innerHTML);  
    	var isAnchor = httpAPattern.test(parent.innerHTML);
    	if (isImg || isAnchor) 
		{
      	var event = getVisualEditorEventForIE();
      	var shiftPressed = isShiftKeyPressed(event);
      	var key = getKey(event);
      
      	// auto-complete the end of the tag if the user enters a space after
      	// the src attribute
      	if (key == 32) 
			{
        		var endTag = (isImg) ? ' \/>' : '>';
        		parent.innerHTML += endTag;
      	}
    	}
  	} 
  	catch(e) 
  	{
    	VisEd.addDebugMsg('CorrectLinkAutoCompletionInImages() failed. \n');
    	return true;
  	}
}

function RemoveLinksWithinTags(html) 
{
  	var httpPattern = new RegExp('&lt;img([^>]+)src=["]*(<a href="[^"]+">)([^<]+)</a>["]*', 'gi');
  	if (httpPattern.test(html))
    	html = html.replace(httpPattern, '&lt;img$1src="$3"');

  	var httpPattern = new RegExp('&lt;a([^>]+)href=["]*(<a href="[^"]+">)([^<]+)</a>["]*', 'gi');
  	if (httpPattern.test(html))
    	html = html.replace(httpPattern, '&lt;a$1href="$3"');

  	return html;
}

VisualEditor.prototype.appendToAction = function (methodName, func, prepend) 
// Create a VisualEditor method with the given methodname and function
{
  	var strFunc = eval('this.' + methodName).toString();
  	if (prepend) 
  	{
    	var funcPattern = new RegExp('function[ ]?\\(\\) \\{', 'gi');
    	var newFunc = strFunc.replace(funcPattern, 'function () {\n' + func + '\n');
  	} 
  	else
    	var newFunc = strFunc.replace(/}[\n\t\s]*$/g, func + '\n}');

  	eval('VisualEditor.prototype.' + methodName + ' = ' + newFunc);
}

/*
  Get all textarea data where it should be for form submission and Firefox form
  caching.

  @param disableTextarea If true, this function will temporarily disable the
  Edit HTML text area. Used to prevent this text area from being included in the
  form POST, where it will only waste bandwidth.
*/
VisualEditor.prototype.updateTextareas = function(disableTextarea) 
{
  if (this.mode == this.DESIGN_MODE) 
    VisEd.movePostBodyToTextarea();

  this.textarea_orig.value = this.textarea.value;

  if (disableTextarea) 
  {
    // This bit of code disables the text area only for the duration of the form
    // submission.
    this.textarea.disabled = true;

    var self = this;
    window.setTimeout(function() { self.textarea.disabled = false; }, 0);
  }

  return checkMaxChars(this.textarea_orig);
}


VisualEditor.prototype.clearDebugMsg = function() 
{
  if (this.DEBUG)
    this.debugField.value = '';
}

VisualEditor.prototype.addDebugMsg = function(s) 
{
  if (this.DEBUG)
    this.debugField.value += (s + '\n\n');
}

VisualEditor.prototype.createToolbar = function(strId, html) 
// - Create a new div with the given strId and put the given html inside to create a toolbar
{
  var bar = createElementandAppend('div', strId, this.buttonBox);
  bar.setAttribute('unselectable','on');
  appendClearObj(bar);
  bar.innerHTML = html; 
  appendClearObj(bar);
  return bar;
}

/*
 * cleanupDeletion()
 *
 * Since we can't get the selection of certain elements with certainty, we 
 * have to cleanup extraneous markup downstream on occasion.
 */
VisualEditor.prototype.cleanupDeletion = function() 
{
  	var tags = this.frameDoc.body.getElementsByTagName('font');
  	for (var i = 0; i < tags.length; i++) 
	{
    	var el = tags[i];
    	// - Clean up images
    	this.removeEmptyImageElements(el);
  	}
}

/* 
 * removeEmptyImageElements()
 *
 * If the given element is a Vis Ed Image container, then the node is 
 * removed while its content is retained.
 */
VisualEditor.prototype.removeEmptyImageElements = function(obj) 
{
  	if (!obj) 
		return;

	var imgTagPattern = new RegExp('<img', 'i'); 
  	if (obj.className == 'vised-image' && !obj.innerHTML.match(imgTagPattern)) 
	{ 
    	// remove the last node if it's the carriage return that was inserted for
    	// Firefox
    	if (Detect.MOZILLA()) 
		{
      	var last_node = obj.childNodes[obj.childNodes.length-1];
      	obj.removeChild(last_node);
    	}
    
    	// if there's content within the old container, insert it to a new node 
    	// in order to cleanup the styles before removing the container
    	var DELETE_ID = 'TEMP-VisEd-DELETE';
    	if (obj.innerHTML.length > 0) 
		{  
      	// make a temporary new node in the IFRAME
      	var new_node = this.frameDoc.createElement('font');
      	new_node.id = DELETE_ID;
    
      	// transfer the content of the image container to a new container
      	new_node.innerHTML = obj.innerHTML;
      	obj.parentNode.insertBefore(new_node, obj);
    	}  
    
    	// remove the old, empty image container
    	obj.parentNode.removeChild(obj);
    
    	// cleanup unneeded elements
    	if (this.frameDoc.getElementById(DELETE_ID)) 
		{
      	// remove the temp element but keep its content
      	var deletePattern = new RegExp('<font id="' + DELETE_ID + '">' + 
        									new_node.innerHTML + '</font>', 'i'); 
        
      	this.frameDoc.body.innerHTML = this.frameDoc.body.innerHTML.replace(deletePattern, new_node.innerHTML);
      
      	// occasionally a stray empty temp element can remain (especially in IE)
      	// and should be removed  
      	var deletePattern2 = new RegExp('<font id="' + DELETE_ID + '"></font>', 'i');
      
      	this.frameDoc.body.innerHTML = this.frameDoc.body.innerHTML.replace(deletePattern2, '');
    	}
  	}
}

function appendClearObj(obj) 
// - Append a div (that has style: 'clear' on both sides) to the given object
{
  var div = document.createElement('div');
  var divStyle = div.style;
  divStyle.clear = "both";
  obj.appendChild(div);
}


// ===================================================================
// Copy-n-paste 
// ===================================================================

var hiddenPaste, currentEditorSelection;

function smartPaste() 
{ 
  currentEditorSelection = GetRange();
  hiddenPaste = createElementandAppend ('div', 'smartPaste');
  hiddenPaste.style.height = 1;
  hiddenPaste.style.width = 1;
  hiddenPaste.style.overflow = "hidden";
  hiddenPaste.onpaste = waitToPaste;
  hiddenPaste.contentEditable = true;
  hiddenPaste.focus();
}

function waitToPaste() 
{ 
  setTimeout ('convertPaste()', 100);
}

function convertPaste () 
{
  var html = hiddenPaste.innerHTML;
  
  // strip very bad HTML that IE may add after paste.  most of this occurs when
  // someone is pasting hand-coded HTML and IE performs its auto-completion for
  // URLs so that the result is something very ugly like:
  // &lt;img src="<A href='http://p/">http://p/</a'>&gt;foo&lt;/a</A>
  html = RemoveLinksWithinTags(html);
  var horridAnchorStartPattern = new RegExp("<A href=[^<]+<[\\/]?a'>", 'gi');
  var horridAnchorEndPattern = new RegExp("\\&lt;\\/a<\\/A>", 'gi');
  var html = html.replace(horridAnchorStartPattern, '');
  var html = html.replace(horridAnchorEndPattern, '&lt;/a');
  html = StripHTMLExceptLinks(html);
  
  // get rid of line feeds
  html = html.replace(/\r/g, '');
  // compress repeated line breaks
  html = html.replace(/\n{2,}/g, '\n');
  // convert line breaks
  html = html.replace(/\n/g, "<br />");
  
  // paste into the editor at the last cursor position
  currentEditorSelection.pasteHTML(html);
  currentEditorSelection.select();
}

function cleanPaste () 
// - Get the contents (formatted as Text) of the Windows' clipboard, replace all "&nbsp;" with " "
// and put it back into the clipboard 
{
  var content = window.clipboardData.getData('Text');
  if (content) 
  	content = content.replace(/\&nbsp;/gi, ' ');
  window.clipboardData.clearData();
  window.clipboardData.setData('Text', content);
}

function StripHTMLExceptLinks (html) 
// - Remove all html tags except anchor tags from the given html
{
  // make a private encoding pattern for tag delimiters
  var strTag = '~~~!#';		// - Random text to represent a start tag
  var endTag = '#!~~~';		// - Random text to represent an end tag
  var strTagPattern = new RegExp(strTag, 'gi');
  var endTagPattern = new RegExp(endTag, 'gi');
  
  // - Replace all instances of "<a . . .>" with "~~~!#a . . .#!~~~"
  html = html.replace(/<a ([^>]*)>/gi, strTag + 'a $1' + endTag);
  html = html.replace(/<\/a>/gi, strTag + '\/a' + endTag);
  
  // - Delete all html tags except the anchors (as they no longer look like tags)
  html = html.replace(/(<([^>]+)>)/gi, ""); 
  
  // - Restore the swapped out anchor tags
  html = html.replace(strTagPattern, '<');
  html = html.replace(endTagPattern, '>');
  
  return html;
}



function initVisualEditor() 
// - Sets up the Visual Editor
{
  	if (Detect.IE_5_5_newer() || Detect.MOZILLA()) 
  	{ 
  		new VisualEditor().make();

		// - If Moz, put some content in to keep it happy
    	if (VisEd.frameDoc.body.innerHTML == "" && Detect.MOZILLA())
      	VisEd.frameDoc.body.innerHTML = IFRAME_INIT_MESSAGE;
  	} 
	else if (Detect.SAFARI() || Detect.OPERA()) 
    	alert ("Sorry, neither Safari nor Opera are supported by this editor");
		
}

document.onkeypress = function(e) 
// - Handle key presses outside of the WYSIWYG Editor
{ 
  	var e = getEvent(e);
  
  	setKeysetByEvent(e); 
  
	if (CTRL_T) 
		togglePreview();
		
  	// - Stop new tab from opening in Mozilla
  	if (Detect.MOZILLA() && CTRL_T) 
    	e.preventDefault();

  	return true;
}



// ===================================================================
// Form utilites (Posting page only)
// ===================================================================

/**
 * setFocus()
 *
 * Sets the focus to the first available form field of the editor.
 */
function setFocus()
{ 
  	// ensure that keypresses don't submit form or prevent tabbing
  	setPostingFormEvents();
  
  	var editor = d(VisEd.frameId);

   if (editor) 
	{
		if (Detect.IE_5_5_newer()) 
			editor.tabIndex = 1;

		VisEd.frame.contentWindow.focus();
	}
}

function setPostingFormEvents() 
{
// APPLY THIS TO ALL TEXT ENTRY FIELDS
//  	if (d("f-title"))
//    	d("f-title").onkeypress = OnPostingFormKeypress;
}

function OnPostingFormKeypress(e) 
{ 
  	var evt = getEvent(e);
  // prevent pressing Enter on a single-text-field form from submitting
  	if (getKey(evt) == RETURN) 
	{
    	if (Detect.IE()) 
			evt.returnValue = false;

		return false;
  }

	// Mozilla has a different way of focusing within designMode window objects.
  	if (Detect.MOZILLA() && VisEd != undefined) 
	{
    	var src = getEventSource(evt);
    	if (!isShiftKeyPressed(evt)) 
		{ 
			// allow for back tabbing
      	if (src.id == "f-title")
        		MozillaTabToFrameFix(evt);
    	}
  	}
}

// So that Firefox 0.7+ can tab to the IFRAME...
function MozillaTabToFrameFix(evt) 
{
  	setKeysetByEvent(evt);
  	if (TAB && VisEd.mode == VisEd.DESIGN_MODE) 
	{
    	var html = VisEd.frameDoc.body.innerHTML;
    	/*
     	* Mozilla needs the frame body to have some value before certain 
     	* operations can take place.
     	*/
    	if (html = "" || html == "<br>") 
      	VisEd.frameDoc.body.innerHTML = IFRAME_INIT_MESSAGE;
    	setVisEdFocus();
    	evt.preventDefault();
  	}
}

function savePostToWYSIMWYG(html) 
{
  	if (html) 
		setPost(html + getPost());
}

function showAdvFeatures ()
// - Show extra buttons for advanced users
{
	setCtrlBarElements (VisEd.NON_ADV_WYSIWYG_CTRLS, 'none');
	setCtrlBarElements (VisEd.ADV_WYSIWYG_CTRLS, 'block');	
	VisEd.ADV_CTRLS_ON = true;
}

function noAdvFeatures ()
// - Hide extra buttons for advanced users
{
	setCtrlBarElements (VisEd.NON_ADV_WYSIWYG_CTRLS, 'block');
	setCtrlBarElements (VisEd.ADV_WYSIWYG_CTRLS, 'none');	
	VisEd.ADV_CTRLS_ON = false;
}

function restoreDataFields() 
// - Restore Data Fields' visibility
{
	var div = document.getElementById("dataFields");

  	if (div == null)
		return;

  	div.style.display = "block";
}


function hideDataFields() 
// - Hides the Data Fields
{
  	var div = document.getElementById("dataFields");
  	if (div != null)
    	div.style.display = "none";
}

function loadEditor() 
// - Set up the Visual Editor
{
  	initVisualEditor();
	setFocus();
  	editorCleanup();
  	saveOrigFormValues();
}

