//------------------------------------------------------------------------------
// 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;
	
	protected OperationHistoryActionHandler undoAction;
	
	protected OperationHistoryActionHandler redoAction;
	
	protected IEditorSite editorSite;

	/** The actions registered with the editor. */
	protected Map<String, IAction> fActions= new HashMap<String, IAction>(10);
	
	/** The verify key listener for activation code triggering. */
	protected ActivationCodeTrigger fActivationCodeTrigger= new ActivationCodeTrigger();
	
	/** The editor's action activation codes. */
	protected List fActivationCodes= new ArrayList(2);
	
	final IUndoManager undoManager= new TextViewerUndoManager(10);
	
	/**
	 * The key binding scopes of this editor.
	 * @since 2.1
	 */
	protected 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.  Must call init(..) before using this widget.
	 */
	public RichTextEditor() {
	}
	
	/**
	 * 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, null, editorSite);
	}

	/**
	 * 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, String basePath,
			IEditorSite editorSite) {
		init(parent, style, basePath, editorSite);
	}

	public void init(Composite parent, int style, String basePath,
			IEditorSite editorSite) {
		this.basePath = basePath;
		this.editorSite = editorSite;
		debug = RichTextPlugin.getDefault().isDebugging();
		logger = RichTextPlugin.getDefault().getLogger();
		initControl(parent, style);
	}
	
	public void init(Composite parent, int style, String basePath) {
		if (richText != null) {
			richText.init(parent, style, basePath);
		}
	}

	/**
	 * Initializes this editor.
	 * 
	 * @param parent
	 *            the parent composite
	 * @param style
	 *            the editor style
	 */
	protected void initControl(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) {
			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);
		
		createHTMLTab(folder, 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;
	}

	protected void createHTMLTab(CTabFolder folder, Composite htmlComposite) {
		htmlTab = new CTabItem(folder, SWT.NONE);
		htmlTab.setText(HTML_TAB_NAME);
		htmlTab.setToolTipText(RichTextResources.htmlTab_toolTipText); 
		htmlTab.setControl(htmlComposite);
	}

	
	protected 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 (isHTMLTabSelected()) {
			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 (isHTMLTabSelected()) {
			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
	 */
	protected void updateRichText(String text) {
		if (richText != null) {
			richText.setText(text);
			richText.checkModify();
		}
		sourceModified = false;
		if (tabFolder != null) {
			if (toolBar != null) {
				toolBar.updateToolBar(editable);
			}
		}
	}
	
	protected 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.
	 */
	protected 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.
	 */
	protected 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
	 */
	protected 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);
		}
	}
	
	protected 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
	 */
	protected 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
	 */
	protected 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. */
		protected boolean fIsInstalled= false;
		/**
		 * The key binding service to use.
		 * @since 2.0
		 */
		protected 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));
		}
	}

}
