/*******************************************************************************
 * Copyright (c) 2009 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
//------------------------------------------------------------------------------
// Copyright (c) 2005, 2007 IBM Corporation and others.
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// which accompanies this distribution, and is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// Contributors:
// IBM Corporation - initial implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.richtext;

import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.commands.ParameterizedCommand;
import org.eclipse.core.commands.operations.IUndoContext;
import org.eclipse.epf.common.serviceability.Logger;
import org.eclipse.epf.richtext.actions.CopyAction;
import org.eclipse.epf.richtext.actions.CutAction;
import org.eclipse.epf.richtext.actions.FindReplaceAction;
import org.eclipse.epf.richtext.actions.PasteAction;
import org.eclipse.epf.richtext.actions.PastePlainTextAction;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.bindings.Binding;
import org.eclipse.jface.bindings.keys.KeySequence;
import org.eclipse.jface.bindings.keys.KeyStroke;
import org.eclipse.jface.bindings.keys.SWTKeySupport;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentListener;
import org.eclipse.jface.text.ITextViewerExtension;
import org.eclipse.jface.text.ITextViewerExtension6;
import org.eclipse.jface.text.IUndoManager;
import org.eclipse.jface.text.IUndoManagerExtension;
import org.eclipse.jface.text.TextViewer;
import org.eclipse.jface.text.TextViewerUndoManager;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.custom.VerifyKeyListener;
import org.eclipse.swt.custom.ViewForm;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DropTarget;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.DropTargetListener;
import org.eclipse.swt.dnd.HTMLTransfer;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.HelpListener;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.MenuEvent;
import org.eclipse.swt.events.MenuListener;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IKeyBindingService;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.keys.IBindingService;
import org.eclipse.ui.operations.OperationHistoryActionHandler;
import org.eclipse.ui.operations.RedoActionHandler;
import org.eclipse.ui.operations.UndoActionHandler;
import org.eclipse.ui.texteditor.IAbstractTextEditorHelpContextIds;
import org.eclipse.ui.texteditor.IReadOnlyDependent;
import org.eclipse.ui.texteditor.ITextEditorActionConstants;
import org.eclipse.ui.texteditor.IUpdate;
import org.eclipse.ui.texteditor.IWorkbenchActionDefinitionIds;

/**
 * The default rich text editor implementation.
 * <p>
 * The default rich text editor uses XHTML as the underlying markup language for
 * the rich text content. It is implemented using a <code>ViewForm</code>
 * control with a tool bar at the top, a tab folder that contains a
 * <code>RichText</code> control for entering the rich text content, and a tab
 * foler that contains a <code>StyleText</code> control for viewing and
 * modifying the XHTML representation of the rich text content.
 * 
 * @author Kelvin Low
 * @author Jeff Hardy
 * @since 1.0
 */
public class RichTextEditor implements IRichTextEditor {

	// The HTML tab name.
	protected static final String HTML_TAB_NAME = RichTextResources.htmlTab_text;

	// If true, log debugging info.
	protected boolean debug;

	// The plug-in logger.
	protected Logger logger;

	// The base path used for resolving links (<href>, <img>, etc.).
	protected String basePath;

	// The editor form.
	protected ViewForm form;

	// The editor tool bar.
	protected IRichTextToolBar toolBar;

	// The editor content.
	protected Composite content;

	// The editor tab folder.
	protected CTabFolder tabFolder;

	// The rich text tab
	protected CTabItem richTextTab;

	// The HTML source tab
	protected CTabItem htmlTab;

	// The embedded rich text control.
	protected IRichText richText;

	// The underlying HTML text editor.
	protected TextViewer sourceViewer;
	
	protected IDocument currentDoc;
	
	// Drop support
	protected DropTarget sourceEditDropTarget;

	// HTML editor's context menu
	protected Menu contextMenu;

	// Has the HTML source been modified?
	protected boolean sourceModified = false;

	// The editor's editable flag.
	protected boolean editable = true;
	
	private OperationHistoryActionHandler undoAction;
	
	private OperationHistoryActionHandler redoAction;
	
	private IEditorSite editorSite;

	/** The actions registered with the editor. */
	private Map<String, IAction> fActions= new HashMap<String, IAction>(10);
	
	/** The verify key listener for activation code triggering. */
	private ActivationCodeTrigger fActivationCodeTrigger= new ActivationCodeTrigger();
	
	/** The editor's action activation codes. */
	private List fActivationCodes= new ArrayList(2);
	
	final IUndoManager undoManager= new TextViewerUndoManager(10);
	
	/**
	 * The key binding scopes of this editor.
	 * @since 2.1
	 */
	private String[] fKeyBindingScopes;

	
	protected IDocumentListener sourceEditDocumentListener= new IDocumentListener() {
		public void documentAboutToBeChanged(DocumentEvent event) {
		}
		public void documentChanged(DocumentEvent event) {
			sourceModified = true;
			if (richText != null && richText instanceof RichText) {
				richText.notifyModifyListeners();
			}
		}
	};


	// The deactivate listener for the sourceEdit control.
	protected Listener sourceEditDeactivateListener = new Listener() {
		public void handleEvent(Event event) {
			if (sourceModified) {
				updateRichText(sourceViewer.getTextWidget().getText());
				setModified(true);
				sourceModified = false;
			}
		}
	};

	// The key listener for the sourceEdit control.
	protected KeyListener sourceEditKeyListener = new KeyListener() {
		public void keyPressed(KeyEvent e) {
			Object adapter = PlatformUI.getWorkbench().getAdapter(
					IBindingService.class);
			if (adapter != null && adapter instanceof IBindingService) {
				int accel = SWTKeySupport
						.convertEventToUnmodifiedAccelerator(e);
				KeyStroke stroke = SWTKeySupport
						.convertAcceleratorToKeyStroke(accel);
				KeySequence seq = KeySequence.getInstance(stroke);
				Binding bind = ((IBindingService) adapter).getPerfectMatch(seq);
				if (bind != null) {
					ParameterizedCommand command = bind
							.getParameterizedCommand();
					if (command != null) {
						String cmdId = command.getId();
						if (cmdId != null
								&& cmdId
										.equals("org.eclipse.ui.edit.findReplace")) { //$NON-NLS-1$
							richText.getFindReplaceAction().execute(RichTextEditor.this);
						}
					}
				}
			}
		}

		public void keyReleased(KeyEvent e) {
		}
	};

	/**
	 * Creates a new instance.
	 * 
	 * @param parent
	 *            the parent composite
	 * @param style
	 *            the editor style
	 */
	public RichTextEditor(Composite parent, int style, IEditorSite editorSite) {
		this(parent, style, editorSite, null);
	}

	/**
	 * Creates a new instance.
	 * 
	 * @param parent
	 *            the parent composite
	 * @param style
	 *            the editor style
	 * @param basePath
	 *            the base path used for resolving links
	 */
	public RichTextEditor(Composite parent, int style, IEditorSite editorSite, String basePath) {
		this.basePath = basePath;
		this.editorSite = editorSite;
		debug = RichTextPlugin.getDefault().isDebugging();
		logger = RichTextPlugin.getDefault().getLogger();
		init(parent, style);
	}

	/**
	 * Initializes this editor.
	 * 
	 * @param parent
	 *            the parent composite
	 * @param style
	 *            the editor style
	 */
	protected void init(Composite parent, int style) {
		try {
			form = new ViewForm(parent, style);
			form.marginHeight = 0;
			form.marginWidth = 0;

			toolBar = new RichTextToolBar(form, SWT.FLAT, this);

			content = new Composite(form, SWT.FLAT);
			GridLayout layout = new GridLayout();
			layout.marginHeight = 0;
			layout.marginWidth = 0;
			content.setLayout(layout);

			tabFolder = createEditorTabFolder(content, style);

			form.setTopCenter(((RichTextToolBar)toolBar).getToolbarMgr().getControl());
			form.setTopLeft(((RichTextToolBar)toolBar).getToolbarMgrCombo().getControl());
			form.setContent(content);
		} catch (Exception e) {
			logger.logError(e);
		}
	}

	/**
	 * Returns the form control.
	 * 
	 * @return the form control
	 */
	public Control getControl() {
		return form;
	}

	/**
	 * Returns the rich text control embedded within this editor.
	 */
	public IRichText getRichTextControl() {
		return richText;
	}

	/**
	 * Sets the layout data.
	 * 
	 * @param layoutData
	 *            the layout data to set
	 */
	public void setLayoutData(Object layoutData) {
		if (form != null) {
			form.setLayoutData(layoutData);
		}
	}

	/**
	 * Returns the layout data.
	 * 
	 * @return the editor's layout data
	 */
	public Object getLayoutData() {
		if (form != null) {
			return form.getLayoutData();
		}
		return null;
	}

	/**
	 * Sets focus to this editor.
	 */
	public void setFocus() {
		if (richText != null) {
			richText.setFocus();
		}
		setSelection(0);
		if (toolBar != null && tabFolder != null) {
			toolBar.updateToolBar(editable);
		}

	}

	/**
	 * Tells the control it does not have focus.
	 */
	public void setBlur() {
		if (richText != null) {
			richText.setBlur();
		}
	}
	
	/**
	 * Checks whether this editor has focus.
	 * 
	 * @return <code>true</code> if this editor has the user-interface focus
	 */
	public boolean hasFocus() {
		if (richText != null) {
			return richText.hasFocus();
		}
		return false;
	}

	/**
	 * Selects the Rich Text or HTML tab.
	 * 
	 * @param index
	 *            <code>0</code> for the Rich Text tab, <code>1</code> for
	 *            the HTML tab.
	 */
	public void setSelection(int index) {
		if (tabFolder != null) {
			tabFolder.setSelection(index);
		}
	}

	/**
	 * Returns the base path used for resolving text and image links.
	 * 
	 * @return the base path used for resolving links specified with <href>,
	 *         <img>, etc.
	 */
	public String getBasePath() {
		return basePath;
	}

	/**
	 * Returns the base URL of the rich text control whose content was last
	 * copied to the clipboard.
	 * 
	 * @return the base URL of a rich text control
	 */
	public URL getCopyURL() {
		if (richText != null) {
			return richText.getCopyURL();
		}
		return null;
	}

	/**
	 * Sets the base URL of the rich text control whose content was last copied
	 * to the clipboard.
	 */
	public void setCopyURL() {
		if (richText != null) {
			richText.setCopyURL();
		}
	}

	/**
	 * Returns the editable state.
	 * 
	 * @return <code>true</code> if the content can be edited
	 */
	public boolean getEditable() {
		return editable;
	}

	/**
	 * Sets the editable state.
	 * 
	 * @param editable
	 *            the editable state
	 */
	public void setEditable(boolean editable) {
		this.editable = editable;
		if (toolBar != null && tabFolder != null) {
			toolBar.updateToolBar(editable);
		}
		if (richText != null) {
			richText.setEditable(editable);
		}
		if (sourceViewer != null) {
			sourceViewer.setEditable(editable);
		}
	}

	/**
	 * Checks whether the content has been modified.
	 * 
	 * @return <code>true</code> if the content has been modified
	 */
	public boolean getModified() {
		if (richText != null) {
			return richText.getModified();
		}
		return false;
	}

	/**
	 * Sets the modified state.
	 * 
	 * @param modified
	 *            the modified state
	 */
	public void setModified(boolean modified) {
		if (richText != null) {
			richText.setModified(modified);
		}
	}

	/**
	 * Returns the rich text content.
	 * 
	 * @return the rich text content formatted in XHTML
	 */
	public String getText() {
		if (sourceModified) {
			setText(getSourceEdit().getText());
			setModified(true);
			sourceModified = false;
		}
		if (richText != null) {
			return richText.getText();
		}
		return ""; //$NON-NLS-1$
	}

	/**
	 * Sets the rich text content.
	 * 
	 * @param text
	 *            the rich text content in XHTML format
	 */
	public void setText(String text) {
		if (richText != null) {
			richText.setText(text);
		}
		sourceModified = false;
		if (tabFolder != null) {
			if (toolBar != null) {
				toolBar.updateToolBar(editable);
			}
			if (getSourceEdit() != null) {
				removeModifyListeners();
				currentDoc.set(text);
				addModifyListeners();
			}
		}
	}
	
	protected void addModifyListeners() {
		if (currentDoc != null) {
			currentDoc.addDocumentListener(sourceEditDocumentListener);
		}
	}

	protected void removeModifyListeners() {
		if (currentDoc != null) {
			currentDoc.removeDocumentListener(sourceEditDocumentListener);
		}
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.epf.richtext.IRichText#checkModify()
	 */
	public void checkModify() {
		richText.checkModify();
		if (sourceModified) {
			notifyModifyListeners();
		}
		if (debug) {
			printDebugMessage("checkModify", "modified=" + sourceModified); //$NON-NLS-1$ //$NON-NLS-2$	
		}
	}

	/**
	 * Restores the rich text content back to the initial value.
	 */
	public void restoreText() {
		if (richText != null) {
			richText.restoreText();
		}
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.epf.richtext.IRichText#getSelected()
	 */
	public RichTextSelection getSelected() {
		if (tabFolder.getSelection() == htmlTab) {
			String HTMLsource = getSourceEdit().getText();
			Point sel = sourceViewer.getSelectedRange();
			int selStartIndex = sel.x;
			int selEndIndex = sel.x + sel.y - 1;
			richText.getSelected().clear();
			richText.getSelected().setText(HTMLsource.substring(selStartIndex, selEndIndex + 1));
		}
		return richText.getSelected();
	}

	/**
	 * Returns an application specific property value.
	 * 
	 * @param key
	 *            the name of the property
	 * @return the value of the property or <code>null</code> if it has not
	 *         been set
	 */
	public Object getData(String key) {
		if (richText != null) {
			return richText.getData(key);
		}
		return null;
	}

	/**
	 * Sets an application specific property name and value.
	 * 
	 * @param key
	 *            the name of the property
	 * @param value
	 *            the new value for the property
	 */
	public void setData(String key, Object value) {
		if (richText != null) {
			richText.setData(key, value);
		}
	}

	/**
	 * Executes the given rich text command. The supported command strings are
	 * defined in <code>RichTextCommand<code>.
	 * 
	 * @param	command		a rich text command string
	 * @return	a status code returned by the executed command
	 */
	public int executeCommand(String command) {
		if (richText != null) {
			return richText.executeCommand(command);
		}
		return 0;
	}

	/**
	 * Executes the given rich text command with a single parameter. The
	 * supported command strings are defined in <code>RichTextCommand<code>.
	 * 
	 * @param	command		a rich text command string
	 * @param	param		a parameter for the command or <code>null</code>
	 * @return	a status code returned by the executed command
	 */
	public int executeCommand(String command, String param) {
		if (richText != null) {
			return richText.executeCommand(command, param);
		}
		return 0;
	}

	/**
	 * Executes the given rich text command with an array of parameters. The
	 * supported command strings are defined in <code>RichTextCommand<code>.
	 * 
	 * @param	command		a rich text command string
	 * @param	params		an array of parameters for the command or <code>null</code>
	 * @return	a status code returned by the executed command
	 */
	public int executeCommand(String command, String[] params) {
		if (richText != null) {
			return richText.executeCommand(command, params);
		}
		return 0;
	}

	/**
	 * Disposes the operating system resources allocated by this editor.
	 */
	public void dispose() {
		if (contextMenu != null && !contextMenu.isDisposed()) {
			contextMenu.dispose();
			contextMenu = null;
		}
		if (sourceEditDropTarget != null) {
			sourceEditDropTarget.dispose();
			sourceEditDropTarget = null;
		}
		if (fActivationCodeTrigger != null) {
			fActivationCodeTrigger.uninstall();
			fActivationCodeTrigger= null;
		}
		removeModifyListeners();
		if (getSourceEdit() != null) {
			getSourceEdit().removeListener(SWT.Deactivate,
					sourceEditDeactivateListener);
			getSourceEdit().removeKeyListener(sourceEditKeyListener);
			sourceEditDeactivateListener = null;
			sourceEditKeyListener = null;
		}
		
		if (sourceViewer != null) {
			sourceViewer= null;
		}

		if (fActions != null) {
			fActions.clear();
			fActions= null;
		}
		if (fActivationCodes != null) {
			fActivationCodes.clear();
			fActivationCodes= null;
		}

		if (richText != null) {
			richText.dispose();
			richText = null;
		}
	}

	/**
	 * Checks whether this control has been disposed.
	 * 
	 * @return <code>true</code> if this control is disposed successfully
	 */
	public boolean isDisposed() {
		if (richText != null) {
			return richText.isDisposed();
		}
		return true;
	}

	/**
	 * Returns the modify listeners attached to this editor.
	 * 
	 * @return an iterator for retrieving the modify listeners
	 */
	public Iterator<ModifyListener> getModifyListeners() {
		if (richText != null) {
			richText.getModifyListeners();
		}
		return null;
	}

	/**
	 * Adds a listener to the collection of listeners who will be notified when
	 * keys are pressed and released within this editor.
	 * 
	 * @param listener
	 *            the listener which should be notified
	 */
	public void addKeyListener(KeyListener listener) {
		if (richText != null) {
			richText.addKeyListener(listener);
		}
	}

	/**
	 * Removes a listener from the collection of listeners who will be notified
	 * when keys are pressed and released within this editor.
	 * 
	 * @param listener
	 *            the listener which should no longer be notified
	 */
	public void removeKeyListener(KeyListener listener) {
		if (richText != null) {
			richText.removeKeyListener(listener);
		}
	}

	/**
	 * Adds a listener to the collection of listeners who will be notified when
	 * the content of this editor is modified.
	 * 
	 * @param listener
	 *            the listener which should be notified
	 */
	public void addModifyListener(ModifyListener listener) {
		if (richText != null) {
			richText.addModifyListener(listener);
		}
	}

	/**
	 * Removes a listener from the collection of listeners who will be notified
	 * when the content of this editor is modified.
	 * 
	 * @param listener
	 *            the listener which should no longer be notified
	 */
	public void removeModifyListener(ModifyListener listener) {
		if (richText != null) {
			richText.removeModifyListener(listener);
		}
	}

	/**
	 * Adds the listener to the collection of listeners who will be notifed when
	 * this editor is disposed.
	 * 
	 * @param listener
	 *            the listener which should be notified
	 */
	public void addDisposeListener(DisposeListener listener) {
		if (richText != null) {
			richText.addDisposeListener(listener);
		}
	}

	/**
	 * Removes a listener from the collection of listeners who will be notified
	 * when this editor is disposed.
	 * 
	 * @param listener
	 *            the listener which should no longer be notified
	 */
	public void removeDisposeListener(DisposeListener listener) {
		if (richText != null) {
			richText.removeDisposeListener(listener);
		}
	}

	/**
	 * Adds a listener to the collection of listeners who will be notified when
	 * help events are generated for this editor.
	 * 
	 * @param listener
	 *            the listener which should be notified
	 */
	public void addHelpListener(HelpListener listener) {
		if (richText != null) {
			richText.addHelpListener(listener);
		}
	}

	/**
	 * Removes a listener from the collection of listeners who will be notified
	 * when help events are generated for this editor.
	 * 
	 * @param listener
	 *            the listener which should no longer be notified
	 */
	public void removeHelpListener(HelpListener listener) {
		if (richText != null) {
			richText.removeHelpListener(listener);
		}
	}

	/**
	 * Adds the listener to the collection of listeners who will be notifed when
	 * an event of the given type occurs within this editor.
	 * 
	 * @param eventType
	 *            the type of event to listen for
	 * @param listener
	 *            the listener which should be notified when the event occurs
	 */
	public void addListener(int eventType, Listener listener) {
		if (richText != null) {
			richText.addListener(eventType, listener);
		}
	}

	/**
	 * Removes the listener from the collection of listeners who will be notifed
	 * when an event of the given type occurs within this editor.
	 * 
	 * @param eventType
	 *            the type of event to listen for
	 * @param listener
	 *            the listener which should no longer be notified when the event
	 *            occurs
	 */
	public void removeListener(int eventType, Listener listener) {
		if (richText != null) {
			richText.removeListener(eventType, listener);
		}
	}

	/**
	 * Returns the event listeners attached to this editor.
	 * 
	 * @return an iterator for retrieving the event listeners attached to this
	 *         editor
	 */
	public Iterator<RichTextListener> getListeners() {
		if (richText != null) {
			return richText.getListeners();
		}
		return null;
	}

	/**
	 * Notifies the modify listeners that the rich text editor content has
	 * changed.
	 */
	public void notifyModifyListeners() {
		if (richText != null) {
			Event event = new Event();
			event.display = Display.getCurrent();
			event.widget = richText.getControl();

			for (Iterator<ModifyListener> i = getModifyListeners(); i != null && i.hasNext();) {
				ModifyListener listener = i.next();
				listener.modifyText(new ModifyEvent(event));
			}
		}
	}

	/**
	 * Fills the tool bar with action items.
	 * 
	 * @param toolBar
	 *            a tool bar contain rich text actions
	 */
	public void fillToolBar(IRichTextToolBar toolBar) {
	}

	/**
	 * Creates the underlying rich text control.
	 * 
	 * @param parent
	 *            the parent composite
	 * @param style
	 *            the style for the control
	 * @param basePath
	 *            the path used for resolving links
	 */
	protected IRichText createRichTextControl(Composite parent, int style,
			String basePath) {
		return new RichText(parent, style, basePath);
	}

	/**
	 * Creates the editor tab folder.
	 * 
	 * @param parent
	 *            the parent control
	 * @param style
	 *            the style for the control
	 * @return a new editor toolbar
	 */
	protected CTabFolder createEditorTabFolder(Composite parent, int style) {
		CTabFolder folder = new CTabFolder(parent, SWT.FLAT | SWT.BOTTOM);
		folder.setLayout(new GridLayout(1, true));
		folder.setLayoutData(new GridData(GridData.FILL_BOTH));

		Composite richTextComposite = new Composite(folder, SWT.FLAT);
		GridLayout richTextCompositeLayout = new GridLayout(1, false);
		richTextCompositeLayout.marginHeight = 0;
		richTextCompositeLayout.marginWidth = 0;
		richTextComposite.setLayout(richTextCompositeLayout);
		richTextComposite.setLayoutData(new GridData(GridData.FILL_BOTH));

		richText = createRichTextControl(richTextComposite, style, basePath);
		richText.setData(PROPERTY_NAME, this);
		richText.getFindReplaceAction().setRichText(this);

		richTextTab = new CTabItem(folder, SWT.FLAT);
		richTextTab.setText(RichTextResources.richTextTab_text);
		richTextTab.setToolTipText(RichTextResources.richTextTab_toolTipText);
		richTextTab.setControl(richTextComposite);

		Composite htmlComposite = new Composite(folder, SWT.FLAT);
		htmlComposite.setLayout(new FillLayout());

		sourceViewer = new TextViewer(htmlComposite, SWT.FLAT | SWT.MULTI
				| SWT.WRAP | SWT.V_SCROLL);
		sourceViewer.setUndoManager(undoManager);
		setDocument(null);
		addModifyListeners();
		getSourceEdit().addListener(SWT.Deactivate, sourceEditDeactivateListener);
		getSourceEdit().addKeyListener(sourceEditKeyListener);
		contextMenu = new Menu(parent.getShell(), SWT.POP_UP);
		getSourceEdit().setMenu(contextMenu);
		// FIXME! This opens up a can of worms, especially with DBCS characters.
		// See https://bugs.eclipse.org/bugs/show_bug.cgi?id=179432. 
		//addDropSupportToStyledText();
		fillContextMenu(contextMenu);
		
		
		htmlTab = new CTabItem(folder, SWT.NONE);
		htmlTab.setText(HTML_TAB_NAME);
		htmlTab.setToolTipText(RichTextResources.htmlTab_toolTipText); 
		htmlTab.setControl(htmlComposite);

		folder.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				CTabItem item = (CTabItem) event.item;
				if (item.getText().equals(HTML_TAB_NAME)) {
					removeModifyListeners();
					currentDoc.set(getText());
					sourceModified = false;
					addModifyListeners();
					if (toolBar != null) {
						toolBar.updateToolBar(editable);
					}
				} else {
					updateRichText(getSourceEdit().getText());
					setModified(true);
					if (toolBar != null) {
						toolBar.updateToolBar(editable);
					}
				}
			}
		});
		fillToolBar(toolBar);
		
		initializeActivationCodeTrigger();
		createActions();
		
		folder.setSelection(0);

		return folder;
	}

	
	private void setDocument(IDocument doc) {
		if (doc == null) {
			doc = new Document();
		}
		// clean up old doc
		undoManager.disconnect();
		IDocument oldDoc = sourceViewer.getDocument();
		if (oldDoc != null) {
			oldDoc.removeDocumentListener(sourceEditDocumentListener);
		}

		// hook up new doc
		currentDoc = doc;
		sourceViewer.setDocument(currentDoc);
		currentDoc.addDocumentListener(sourceEditDocumentListener);
		undoManager.connect(sourceViewer);
		if (undoAction != null) {
			undoAction.setContext(getUndoContext());
		}
		if (redoAction != null) {
			redoAction.setContext(getUndoContext());
		}
	}
	
	/**
	 * Returns the HTML source edit control.
	 * 
	 * @return a <code>StyleText</code> object.
	 */
	public StyledText getSourceEdit() {
		if (sourceViewer != null) {
			return sourceViewer.getTextWidget();
		}
		return null;
	}

	/**
	 * Inserts text at the selection (overwriting the selection).
	 */
	public void addHTML(String text) {
		if (text == null || text.length() == 0) 
			return;
		if (tabFolder.getSelection() == richTextTab) {
			executeCommand(RichTextCommand.ADD_HTML, text);
		} else if (tabFolder.getSelection() == htmlTab) {
			String oldHTML = getSourceEdit().getText();
			Point sel = sourceViewer.getSelectedRange();
			int selStartIndex = sel.x;
			int selEndIndex = sel.x + sel.y - 1;
			String newHTML = oldHTML.substring(0, selStartIndex) + text
					+ oldHTML.substring(selEndIndex + 1);
			removeModifyListeners();
			currentDoc.set(newHTML);
			addModifyListeners();
			updateRichText(newHTML);
		}
	}

	
	/**
	 * Inserts an image at the selection (overwriting the selection).
	 */
	public void addImage(String imageURL, String height, String width, String altTag) {
		if (tabFolder.getSelection() == richTextTab) {
			executeCommand(
					RichTextCommand.ADD_IMAGE,
					new String[] {
							imageURL,
							height, width, altTag });
		} else if (tabFolder.getSelection() == htmlTab) {
			StringBuffer imageLink = new StringBuffer();
			// order of these attributes is the same as JTidy'ed HTML
			imageLink.append("<img"); //$NON-NLS-1$
			if (height.length() > 0) {
				imageLink.append(" height=\"" + height + "\""); //$NON-NLS-1$ //$NON-NLS-2$
			}
			if (altTag.length() > 0) {
				imageLink.append(" alt=\"" + altTag + "\""); //$NON-NLS-1$ //$NON-NLS-2$
			}
			imageLink.append(" src=\"" + imageURL + "\""); //$NON-NLS-1$ //$NON-NLS-2$
			if (width.length() > 0) {
				imageLink.append(" width=\"" + width + "\""); //$NON-NLS-1$ //$NON-NLS-2$
			}
			imageLink.append(" />"); //$NON-NLS-1$
			String oldHTML = getSourceEdit().getText();
			Point sel = sourceViewer.getSelectedRange();
			int selStartIndex = sel.x;
			int selEndIndex = sel.x + sel.y - 1;
			String newHTML = oldHTML.substring(0, selStartIndex) + imageLink.toString()
					+ oldHTML.substring(selEndIndex + 1);
			removeModifyListeners();
			currentDoc.set(newHTML);
			addModifyListeners();
			updateRichText(newHTML);
		}
	}

	/**
	 * Checks whether the HTML tab is selected.
	 * 
	 * @return <code>true</code> if the HTML tab is selected.
	 */
	public boolean isHTMLTabSelected() {
		return (tabFolder.getSelection() == htmlTab);
	}

	/**
	 * Fills the context menu with menu items.
	 * 
	 * @param contextMenu
	 *            a context menu containing rich text actions
	 */
	protected void fillContextMenu(Menu contextMenu) {
		final MenuItem cutItem = new MenuItem(contextMenu, SWT.PUSH);
		cutItem.setText(RichTextResources.cutAction_text);
		cutItem.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				CutAction action = new CutAction(RichTextEditor.this);
				action.execute(RichTextEditor.this);
			}
		});
		final MenuItem copyItem = new MenuItem(contextMenu, SWT.PUSH);
		copyItem.setText(RichTextResources.copyAction_text); 
		copyItem.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				CopyAction action = new CopyAction(RichTextEditor.this);
				action.execute(RichTextEditor.this);
			}
		});
		final MenuItem pasteItem = new MenuItem(contextMenu, SWT.PUSH);
		pasteItem.setText(RichTextResources.pasteAction_text); 
		pasteItem.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				PasteAction action = new PasteAction(RichTextEditor.this);
				action.execute(RichTextEditor.this);
			}
		});
		
		final MenuItem pastePlainTextItem = new MenuItem(contextMenu, SWT.PUSH);
		pastePlainTextItem.setText(RichTextResources.pastePlainTextAction_text);
		pastePlainTextItem.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				PastePlainTextAction action = new PastePlainTextAction(RichTextEditor.this);
				action.execute(RichTextEditor.this);
			}
		});

		contextMenu.addMenuListener(new MenuListener() {
			public void menuHidden(MenuEvent e) {
			}

			public void menuShown(MenuEvent e) {
				String selectedText = getSelected().getText();
				boolean selection = selectedText.length() > 0;
				cutItem.setEnabled(editable && selection);
				copyItem.setEnabled(selection);
				pasteItem.setEnabled(editable);
				pastePlainTextItem.setEnabled(editable);
			}
		});
	}

	/**
	 * Updates the content of the rich text control without updating the HTML
	 * source editor.
	 * <p>
	 * This method should be called by the HTML source editor to sync up its
	 * content with the rich text control.
	 * 
	 * @param text
	 *            the rich text content in XHTML format
	 */
	private void updateRichText(String text) {
		if (richText != null) {
			richText.setText(text);
			richText.checkModify();
		}
		sourceModified = false;
		if (tabFolder != null) {
			if (toolBar != null) {
				toolBar.updateToolBar(editable);
			}
		}
	}
	
	private void addDropSupportToStyledText() {
		// this function based heavily on the example at:
		// http://www.eclipse.org/articles/Article-SWT-DND/DND-in-SWT.html
		
		 	// Allow data to be copied to the drop target
			int operations = DND.DROP_MOVE |  DND.DROP_COPY | DND.DROP_DEFAULT;
			sourceEditDropTarget = new DropTarget(getSourceEdit(), operations);
		 
			// Receive data in Text or HTML format
			final TextTransfer textTransfer = TextTransfer.getInstance();
			final HTMLTransfer htmlTransfer = HTMLTransfer.getInstance();
			Transfer[] types = new Transfer[] {htmlTransfer, textTransfer};
			sourceEditDropTarget.setTransfer(types);
			 
			sourceEditDropTarget.addDropListener(new DropTargetListener() {
			  public void dragEnter(DropTargetEvent event) {
			     if (event.detail == DND.DROP_DEFAULT) {
			         if ((event.operations & DND.DROP_COPY) != 0) {
			             event.detail = DND.DROP_COPY;
			         } else {
			             event.detail = DND.DROP_NONE;
			         }
			     }
			     if (!getEditable()) {
		             event.detail = DND.DROP_NONE;
			     }
			     // will accept text but prefer to have HTML dropped
			     for (int i = 0; i < event.dataTypes.length; i++) {
			         if (htmlTransfer.isSupportedType(event.dataTypes[i])){
			             event.currentDataType = event.dataTypes[i];
			             break;
			         }
			     }
			   }
			   public void dragOver(DropTargetEvent event) {
			        event.feedback = DND.FEEDBACK_SELECT | DND.FEEDBACK_INSERT_AFTER | DND.FEEDBACK_SCROLL;
			    }
			    public void dragOperationChanged(DropTargetEvent event) {
			        if (event.detail == DND.DROP_DEFAULT) {
			            if ((event.operations & DND.DROP_COPY) != 0) {
			                event.detail = DND.DROP_COPY;
			            } else {
			                event.detail = DND.DROP_NONE;
			            }
			        }
			    }
			    public void dragLeave(DropTargetEvent event) {
			    }
			    public void dropAccept(DropTargetEvent event) {
			    }
			    public void drop(DropTargetEvent event) {
			        if (textTransfer.isSupportedType(event.currentDataType) || 
			        		htmlTransfer.isSupportedType(event.currentDataType)) {
			            String text = (String)event.data;
			            addHTML(text);
			        }
			    }
			});
	}
	
	/**
	 * Displays the given debug message to the console.
	 */
	private void printDebugMessage(String method, String msg, String text) {
		StringBuffer strBuf = new StringBuffer();
		strBuf.append("RichTextEditor[").append(richText.getControl().handle).append(']') //$NON-NLS-1$
				.append('.').append(method);
		if (msg != null && msg.length() > 0) {
			strBuf.append(": ").append(msg); //$NON-NLS-1$
		}
		if (text != null && text.length() > 0) {
			strBuf.append('\n').append(text);
		}
		System.out.println(strBuf);
	}

	/**
	 * Displays the given debug message to the console.
	 */
	private void printDebugMessage(String method, String msg) {
		printDebugMessage(method, msg, null);
	}
	
	public FindReplaceAction getFindReplaceAction() {
		return richText.getFindReplaceAction();
	}

	public void setFindReplaceAction(FindReplaceAction findReplaceAction) {
		if (richText != null) {
			richText.setFindReplaceAction(findReplaceAction);
			richText.getFindReplaceAction().setRichText(this);

		}
	}
	
	public void setInitialText(String text) {
		if (richText != null) {
			richText.setInitialText(text);
		}
		if (getSourceEdit() != null) {
			removeModifyListeners();
			setDocument(new Document(text));
			addModifyListeners();
		}

	}
	
	
	/**
	 * from org.eclipse.ui.texteditor.AbstractTextEditor#getUndoContext()
	 * Returns this editor's viewer's undo manager undo context.
	 *
	 * @return the undo context or <code>null</code> if not available
	 * @since 3.1
	 */
	private IUndoContext getUndoContext() {
		if (sourceViewer instanceof ITextViewerExtension6) {
			IUndoManager undoManager= ((ITextViewerExtension6)sourceViewer).getUndoManager();
			if (undoManager instanceof IUndoManagerExtension)
				return ((IUndoManagerExtension)undoManager).getUndoContext();
		}
		return null;
	}
	
	protected void createActions() {
		createUndoRedoActions();
		// select all
		Action selectAllAction = new Action() {
			@Override
			public void run() {
				getSourceEdit().selectAll();
			}
		};
		selectAllAction.setActionDefinitionId(IWorkbenchActionDefinitionIds.SELECT_ALL);
		registerAction(ActionFactory.SELECT_ALL.getId(), selectAllAction);
	}

	/*
	 * from org.eclipse.ui.texteditor.AbstractTextEditor#createUndoRedoActions()
	 */
	protected void createUndoRedoActions() {
		IUndoContext undoContext= getUndoContext();
		if (undoContext != null) {
			// Use actions provided by global undo/redo
			
			// Create the undo action
			undoAction= new UndoActionHandler(getEditorSite(), undoContext);
			PlatformUI.getWorkbench().getHelpSystem().setHelp(undoAction, IAbstractTextEditorHelpContextIds.UNDO_ACTION);
			undoAction.setActionDefinitionId(IWorkbenchActionDefinitionIds.UNDO);
			registerAction(ITextEditorActionConstants.UNDO, undoAction);

			// Create the redo action.
			redoAction= new RedoActionHandler(getEditorSite(), undoContext);
			PlatformUI.getWorkbench().getHelpSystem().setHelp(redoAction, IAbstractTextEditorHelpContextIds.REDO_ACTION);
			redoAction.setActionDefinitionId(IWorkbenchActionDefinitionIds.REDO);
			registerAction(ITextEditorActionConstants.REDO, redoAction);
		}
	}
	
	private IEditorSite getEditorSite() {
		return editorSite;
	}


	/**
	 * Registers the given undo/redo action under the given ID and
	 * ensures that previously installed actions get disposed. It
	 * also takes care of re-registering the new action with the
	 * global action handler.
	 * 
	 * @param actionId	the action id under which to register the action
	 * @param action	the action to register
	 * @since 3.1
	 */
	private void registerAction(String actionId, IAction action) {
		IAction oldAction= getAction(actionId);
		if (oldAction instanceof OperationHistoryActionHandler)
			((OperationHistoryActionHandler)oldAction).dispose();

		setAction(actionId, action);
		
		IActionBars actionBars= getEditorSite().getActionBars();
		if (actionBars != null)
			actionBars.setGlobalActionHandler(actionId, action);
	}

	
	/*
	 * @see ITextEditor#getAction(String)
	 */
	public IAction getAction(String actionID) {
		assert actionID != null;
		IAction action= (IAction) fActions.get(actionID);

//		if (action == null) {
//			action= findContributedAction(actionID);
//			if (action != null)
//				setAction(actionID, action);
//		}

		return action;
	}

	/*
	 * @see ITextEditor#setAction(String, IAction)
	 */
	public void setAction(String actionID, IAction action) {
		assert actionID != null;
		if (action == null) {
			action= (IAction) fActions.remove(actionID);
			if (action != null)
				fActivationCodeTrigger.unregisterActionFromKeyActivation(action);
		} else {
			fActions.put(actionID, action);
			fActivationCodeTrigger.registerActionForKeyActivation(action);
		}
	}
	
	/**
	 * Initializes the activation code trigger.
	 *
	 * @since 2.1
	 */
	private void initializeActivationCodeTrigger() {
		fActivationCodeTrigger.install();
		fActivationCodeTrigger.setScopes(fKeyBindingScopes);
	}

	/**
	 * Internal key verify listener for triggering action activation codes.
	 */
	class ActivationCodeTrigger implements VerifyKeyListener {

		/** Indicates whether this trigger has been installed. */
		private boolean fIsInstalled= false;
		/**
		 * The key binding service to use.
		 * @since 2.0
		 */
		private IKeyBindingService fKeyBindingService;
		
		/*
		 * @see VerifyKeyListener#verifyKey(org.eclipse.swt.events.VerifyEvent)
		 */
		public void verifyKey(VerifyEvent event) {

			ActionActivationCode code= null;
			int size= fActivationCodes.size();
			for (int i= 0; i < size; i++) {
				code= (ActionActivationCode) fActivationCodes.get(i);
				if (code.matches(event)) {
					IAction action= getAction(code.fActionId);
					if (action != null) {

						if (action instanceof IUpdate)
							((IUpdate) action).update();

						if (!action.isEnabled() && action instanceof IReadOnlyDependent) {
							IReadOnlyDependent dependent= (IReadOnlyDependent) action;
							boolean writable= dependent.isEnabled(true);
							if (writable) {
								event.doit= false;
								return;
							}
						} else if (action.isEnabled()) {
							event.doit= false;
							action.run();
							return;
						}
					}
				}
			}
		}

		/**
		 * Installs this trigger on the editor's text widget.
		 * @since 2.0
		 */
		public void install() {
			if (!fIsInstalled) {

				if (sourceViewer instanceof ITextViewerExtension) {
					ITextViewerExtension e= (ITextViewerExtension) sourceViewer;
					e.prependVerifyKeyListener(this);
				} else {
					StyledText text= sourceViewer.getTextWidget();
					text.addVerifyKeyListener(this);
				}

				fKeyBindingService= getEditorSite().getKeyBindingService();
				fIsInstalled= true;
			}
		}

		/**
		 * Uninstalls this trigger from the editor's text widget.
		 * @since 2.0
		 */
		public void uninstall() {
			if (fIsInstalled) {

				if (sourceViewer instanceof ITextViewerExtension) {
					ITextViewerExtension e= (ITextViewerExtension) sourceViewer;
					e.removeVerifyKeyListener(this);
				} else if (sourceViewer != null) {
					StyledText text= sourceViewer.getTextWidget();
					if (text != null && !text.isDisposed())
						text.removeVerifyKeyListener(fActivationCodeTrigger);
				}

				fIsInstalled= false;
				fKeyBindingService= null;
			}
		}

		/**
		 * Registers the given action for key activation.
		 * @param action the action to be registered
		 * @since 2.0
		 */
		public void registerActionForKeyActivation(IAction action) {
			if (action.getActionDefinitionId() != null)
				fKeyBindingService.registerAction(action);
		}

		/**
		 * The given action is no longer available for key activation
		 * @param action the action to be unregistered
		 * @since 2.0
		 */
		public void unregisterActionFromKeyActivation(IAction action) {
			if (action.getActionDefinitionId() != null)
				fKeyBindingService.unregisterAction(action);
		}

		/**
		 * Sets the key binding scopes for this editor.
		 * @param keyBindingScopes the key binding scopes
		 * @since 2.1
		 */
		public void setScopes(String[] keyBindingScopes) {
			if (keyBindingScopes != null && keyBindingScopes.length > 0)
				fKeyBindingService.setScopes(keyBindingScopes);
		}
	}
	
	/**
	 * Representation of action activation codes.
	 */
	static class ActionActivationCode {

		/** The action id. */
		public String fActionId;
		/** The character. */
		public char fCharacter;
		/** The key code. */
		public int fKeyCode= -1;
		/** The state mask. */
		public int fStateMask= SWT.DEFAULT;

		/**
		 * Creates a new action activation code for the given action id.
		 * @param actionId the action id
		 */
		public ActionActivationCode(String actionId) {
			fActionId= actionId;
		}

		/**
		 * Returns <code>true</code> if this activation code matches the given verify event.
		 * @param event the event to test for matching
		 * @return whether this activation code matches <code>event</code>
		 */
		public boolean matches(VerifyEvent event) {
			return (event.character == fCharacter &&
						(fKeyCode == -1 || event.keyCode == fKeyCode) &&
						(fStateMask == SWT.DEFAULT || event.stateMask == fStateMask));
		}
	}

}
