//------------------------------------------------------------------------------
// 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.Iterator;

import org.eclipse.core.commands.ParameterizedCommand;
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.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.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.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.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.PlatformUI;
import org.eclipse.ui.keys.IBindingService;

/**
 * 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 StyledText sourceEdit;
	
	// Drop support
	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;

	// The modify listener for the sourceEdit control.
	protected ModifyListener sourceEditModifyListener = new ModifyListener() {
		public void modifyText(ModifyEvent e) {
			sourceModified = true;
			if (richText != null && richText instanceof RichText) {
				((RichText) richText).notifyModifyListeners();
			}
		}
	};

	// The deactivate listener for the sourceEdit control.
	protected Listener sourceEditDeactivateListener = new Listener() {
		public void handleEvent(Event event) {
			if (sourceModified) {
				updateRichText(sourceEdit.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) {
		this(parent, style, 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, String basePath) {
		this.basePath = basePath;
		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.setTopLeft((Control) toolBar);
			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);
	}

	/**
	 * 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) {
			if (tabFolder.getSelection() == richTextTab) {
				toolBar.updateToolBar(editable);
			}
		}
		if (richText != null) {
			richText.setEditable(editable);
		}
		if (sourceEdit != null) {
			sourceEdit.setEditable(editable);
			sourceEdit.getEditable();
		}
	}

	/**
	 * 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(sourceEdit.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 (sourceEdit != null) {
				sourceEdit.removeModifyListener(sourceEditModifyListener);
				sourceEdit.setText(getText());
				sourceEdit.addModifyListener(sourceEditModifyListener);
			}
		}
	}

	/*
	 * (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 = sourceEdit.getText();
			Point sel = sourceEdit.getSelectionRange();
			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 (sourceEdit != null) {
			sourceEdit.removeModifyListener(sourceEditModifyListener);
			sourceEdit.removeListener(SWT.Deactivate,
					sourceEditDeactivateListener);
			sourceEdit.removeKeyListener(sourceEditKeyListener);
			sourceEditModifyListener = null;
			sourceEditDeactivateListener = null;
			sourceEditKeyListener = 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 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 getListeners() {
		if (richText != null) {
			return richText.getListeners();
		}
		return null;
	}

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

			for (Iterator i = getModifyListeners(); i != null && i.hasNext();) {
				ModifyListener listener = (ModifyListener) 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());

		sourceEdit = new StyledText(htmlComposite, SWT.FLAT | SWT.MULTI
				| SWT.WRAP | SWT.V_SCROLL);
		sourceEdit.addModifyListener(sourceEditModifyListener);
		sourceEdit.addListener(SWT.Deactivate, sourceEditDeactivateListener);
		sourceEdit.addKeyListener(sourceEditKeyListener);
		contextMenu = new Menu(parent.getShell(), SWT.POP_UP);
		sourceEdit.setMenu(contextMenu);
		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)) {
					sourceEdit.removeModifyListener(sourceEditModifyListener);
					sourceEdit.setText(getText());
					sourceModified = false;
					sourceEdit.addModifyListener(sourceEditModifyListener);
					if (toolBar != null) {
						toolBar.updateToolBar(editable);
					}
					sourceEdit.setCaretOffset(richText.getSelected().getOffsetStart());
				} else {
					updateRichText(sourceEdit.getText());
					setModified(true);
					if (toolBar != null) {
						toolBar.updateToolBar(editable);
					}
				}
			}
		});
		fillToolBar(toolBar);

		folder.setSelection(0);

		return folder;
	}

	/**
	 * Returns the HTML source edit control.
	 * 
	 * @return a <code>StyleText</code> object.
	 */
	public StyledText getSourceEdit() {
		return sourceEdit;
	}

	/**
	 * 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 = sourceEdit.getText();
			Point sel = sourceEdit.getSelectionRange();
			int selStartIndex = sel.x;
			int selEndIndex = sel.x + sel.y - 1;
			String newHTML = oldHTML.substring(0, selStartIndex) + text
					+ oldHTML.substring(selEndIndex + 1);
			sourceEdit.removeModifyListener(sourceEditModifyListener);
			sourceEdit.setText(newHTML);
			sourceEdit.addModifyListener(sourceEditModifyListener);
			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 = sourceEdit.getText();
			Point sel = sourceEdit.getSelectionRange();
			int selStartIndex = sel.x;
			int selEndIndex = sel.x + sel.y - 1;
			String newHTML = oldHTML.substring(0, selStartIndex) + imageLink.toString()
					+ oldHTML.substring(selEndIndex + 1);
			sourceEdit.removeModifyListener(sourceEditModifyListener);
			sourceEdit.setText(newHTML);
			sourceEdit.addModifyListener(sourceEditModifyListener);
			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();
				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();
				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();
				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();
				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(sourceEdit, 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;
			         }
			     }
			     // 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);
	}

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

	public void setFindReplaceAction(FindReplaceAction findReplaceAction) {
		richText.setFindReplaceAction(findReplaceAction);
		richText.getFindReplaceAction().setRichText(this);
	}
}
