/*******************************************************************************
 *  Copyright (c) 2006, 2017 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
 *     QNX Software Systems - Mikhail Khodjaiants - Registers View (Bug 53640)
 *     Wind River - Anton Leherbauer - Fix selection provider (Bug 254442)
 *     Patrick Chuong (Texas Instruments) - Improve usability of the breakpoint view (Bug 238956)
 *******************************************************************************/
package org.eclipse.debug.internal.ui.views.variables.details;

import java.util.Iterator;
import java.util.ResourceBundle;

import org.eclipse.core.commands.operations.IUndoContext;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.core.model.IDebugElement;
import org.eclipse.debug.core.model.IExpression;
import org.eclipse.debug.core.model.IValue;
import org.eclipse.debug.core.model.IVariable;
import org.eclipse.debug.internal.core.IInternalDebugCoreConstants;
import org.eclipse.debug.internal.ui.DebugPluginImages;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.internal.ui.IDebugHelpContextIds;
import org.eclipse.debug.internal.ui.LazyModelPresentation;
import org.eclipse.debug.internal.ui.VariablesViewModelPresentation;
import org.eclipse.debug.internal.ui.actions.variables.details.DetailPaneAssignValueAction;
import org.eclipse.debug.internal.ui.actions.variables.details.DetailPaneMaxLengthAction;
import org.eclipse.debug.internal.ui.actions.variables.details.DetailPaneWordWrapAction;
import org.eclipse.debug.internal.ui.breakpoints.provisional.IBreakpointContainer;
import org.eclipse.debug.internal.ui.preferences.IDebugPreferenceConstants;
import org.eclipse.debug.internal.ui.views.variables.IndexedValuePartition;
import org.eclipse.debug.ui.IDebugModelPresentation;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.debug.ui.IDebugView;
import org.eclipse.debug.ui.IDetailPane2;
import org.eclipse.debug.ui.IValueDetailListener;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IStatusLineManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.action.StatusLineContributionItem;
import org.eclipse.jface.commands.ActionHandler;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.text.BadLocationException;
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.IFindReplaceTarget;
import org.eclipse.jface.text.ITextOperationTarget;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.IUndoManager;
import org.eclipse.jface.text.IUndoManagerExtension;
import org.eclipse.jface.text.WhitespaceCharacterPainter;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.jface.text.source.SourceViewerConfiguration;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.IWorkbenchCommandConstants;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.console.actions.TextViewerAction;
import org.eclipse.ui.editors.text.EditorsUI;
import org.eclipse.ui.handlers.IHandlerActivation;
import org.eclipse.ui.handlers.IHandlerService;
import org.eclipse.ui.model.IWorkbenchAdapter;
import org.eclipse.ui.operations.OperationHistoryActionHandler;
import org.eclipse.ui.operations.RedoActionHandler;
import org.eclipse.ui.operations.UndoActionHandler;
import org.eclipse.ui.progress.WorkbenchJob;
import org.eclipse.ui.texteditor.AbstractTextEditor;
import org.eclipse.ui.texteditor.FindReplaceAction;
import org.eclipse.ui.texteditor.IAbstractTextEditorHelpContextIds;
import org.eclipse.ui.texteditor.ITextEditorActionConstants;
import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;

import com.ibm.icu.text.MessageFormat;

/**
 * This detail pane uses a source viewer to display detailed information about the current
 * selection.  It incorporates a large number of actions into its context menu.  It is the
 * default detail pane.
 *
 * @see DefaultDetailPaneFactory
 * @since 3.3
 *
 */
public class DefaultDetailPane extends AbstractDetailPane implements IDetailPane2, IAdaptable, IPropertyChangeListener{

	/**
	 * These are the IDs for the actions in the context menu
	 */
	protected static final String DETAIL_COPY_ACTION = ActionFactory.COPY.getId() + ".SourceDetailPane"; //$NON-NLS-1$
	protected static final String DETAIL_SELECT_ALL_ACTION = IDebugView.SELECT_ALL_ACTION + ".SourceDetailPane"; //$NON-NLS-1$
	protected static final String DETAIL_PASTE_ACTION = ActionFactory.PASTE.getId();
	protected static final String DETAIL_CUT_ACTION = ActionFactory.CUT.getId();

	protected static final String DETAIL_FIND_REPLACE_TEXT_ACTION = "FindReplaceText"; //$NON-NLS-1$
	protected static final String DETAIL_CONTENT_ASSIST_ACTION = "ContentAssist"; //$NON-NLS-1$
	protected static final String DETAIL_ASSIGN_VALUE_ACTION = "AssignValue"; //$NON-NLS-1$

	protected static final String DETAIL_WORD_WRAP_ACTION = IDebugPreferenceConstants.PREF_DETAIL_PANE_WORD_WRAP;
	protected static final String DETAIL_MAX_LENGTH_ACTION = "MaxLength"; //$NON-NLS-1$

	/**
	 * The ID, name and description of this pane are stored in constants so that the class
	 * does not have to be instantiated to access them.
	 */
	public static final String ID = DetailMessages.DefaultDetailPane_0;
	public static final String NAME = DetailMessages.DefaultDetailPane_1;
	public static final String DESCRIPTION = DetailMessages.DefaultDetailPane_57;

	/**
	 * Data structure for the position label value.
	 */
	private static class PositionLabelValue {

		public int fValue;

		@Override
		public String toString() {
			return String.valueOf(fValue);
		}
	}

	/**
	 * Internal interface for a cursor listener. I.e. aggregation
	 * of mouse and key listener.
	 * @since 3.0
	 */
	interface ICursorListener extends MouseListener, KeyListener {
	}

	/**
	 * Job to compute the details for a selection
	 */
	class DetailJob extends Job implements IValueDetailListener {

		private IStructuredSelection fElements;
		private IDebugModelPresentation fModel;
		private boolean fFirst = true;
		// whether a result was collected
		private boolean fComputed = false;
		private IProgressMonitor fMonitor;

		public DetailJob(IStructuredSelection elements, IDebugModelPresentation model) {
			super("compute variable details"); //$NON-NLS-1$
			setSystem(true);
			fElements = elements;
			fModel = model;
		}

		/* (non-Javadoc)
		 * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
		 */
		@Override
		protected IStatus run(IProgressMonitor monitor) {
			fMonitor = monitor;
			Iterator<?> iterator = fElements.iterator();
			String message = null;
			while (iterator.hasNext()) {
				if (monitor.isCanceled()) {
					break;
				}
				Object element = iterator.next();
				IValue val = null;
				if (element instanceof IVariable) {
					try {
						val = ((IVariable)element).getValue();
					} catch (DebugException e) {
						detailComputed(null, e.getStatus().getMessage());
					}
				} else if (element instanceof IExpression) {
					val = ((IExpression)element).getValue();
				} else if (element instanceof IBreakpoint) {
					IBreakpoint bp = (IBreakpoint) element;
					message = bp.getMarker().getAttribute(IMarker.MESSAGE, ""); //$NON-NLS-1$
				} else if (element instanceof IBreakpointContainer) {
					IBreakpointContainer c = (IBreakpointContainer) element;
		            IAdaptable category = c.getCategory();
		            if (category != null) {
			            IWorkbenchAdapter adapter = category.getAdapter(IWorkbenchAdapter.class);
			            if (adapter != null) {
			                message = adapter.getLabel(category);
			            } else {
			            	message = c.getOrganizer().getLabel();
			            }
		            }
				}
				// When selecting a index partition, clear the pane
				if (val instanceof IndexedValuePartition) {
					detailComputed(null, IInternalDebugCoreConstants.EMPTY_STRING);
					val = null;
				}
				if (element instanceof String) {
					message = (String) element;
				}
				if (val != null && !monitor.isCanceled()) {
					fModel.computeDetail(val, this);
					synchronized (this) {
						try {
							// wait for a max of 30 seconds for result, then cancel
							wait(30000);
							if (!fComputed) {
								fMonitor.setCanceled(true);
							}
						} catch (InterruptedException e) {
							break;
						}
					}
				}
			}
			// If no details were computed for the selected variable, clear the pane
			// or use the message, if the variable was a java.lang.String
			if (!fComputed){
				if (message == null) {
					detailComputed(null,IInternalDebugCoreConstants.EMPTY_STRING);
				} else {
					detailComputed(null, message);
				}
			}
			return Status.OK_STATUS;
		}

		/* (non-Javadoc)
		 * @see org.eclipse.core.runtime.jobs.Job#canceling()
		 */
		@Override
		protected void canceling() {
			super.canceling();
			synchronized (this) {
				notifyAll();
			}
		}

		/* (non-Javadoc)
		 * @see org.eclipse.debug.ui.IValueDetailListener#detailComputed(org.eclipse.debug.core.model.IValue, java.lang.String)
		 */
		@Override
		public void detailComputed(IValue value, final String result) {
			synchronized (this) {
				fComputed = true;
			}
			String valueString = result;
			if (valueString == null){
				try{
					valueString = value.getValueString();
				} catch (DebugException e){
					valueString = e.getMessage();
				}
			}
			final String detail = (valueString != null) ? valueString : DetailMessages.DefaultDetailPane_3;
			if (!fMonitor.isCanceled()) {
				WorkbenchJob append = new WorkbenchJob("append details") { //$NON-NLS-1$
					@Override
					public IStatus runInUIThread(IProgressMonitor monitor) {
						if (!fMonitor.isCanceled()) {
							String insert = detail;
							int length = 0;
							if (!fFirst) {
								length = getDetailDocument().getLength();
							}
							if (length > 0) {
								insert = "\n" + result; //$NON-NLS-1$
							}
							try {
								int max = DebugUIPlugin.getDefault().getPreferenceStore().getInt(IDebugUIConstants.PREF_MAX_DETAIL_LENGTH);
								if (max > 0 && insert.length() > max) {
									insert = insert.substring(0, max) + "..."; //$NON-NLS-1$
								}
								int topIndex = -1;
								StyledText styledText = fSourceViewer.getTextWidget();
								Point selection = null;
								// keep scrolling state in details pane in case
								// of longer string over multiple lines
								if (containsLineDelimiter(insert)) {
									int ti = styledText.getTopIndex();
									if (ti == 0) {
										int caretOffset = styledText.getCaretOffset();
										String topStr = styledText.getText().substring(0, caretOffset);
										if (insert.length() > caretOffset) {
											String newTopStr = insert.substring(0, caretOffset);
											// only when string from start to
											// caretOffset has not changed
											if (topStr.equals(newTopStr)) {
												topIndex = ti;
												selection = styledText.getSelection();
											}
										}
									} else if (ti > 0) {
										int topOffset = styledText.getOffsetAtLine(ti);
										String topStr = styledText.getText().substring(0, topOffset);
										if (insert.length() > topOffset) {
											String newTopStr = insert.substring(0, topOffset);
											// only when string from start to
											// topIndex has not changed
											if (topStr.equals(newTopStr)) {
												topIndex = ti;
												selection = styledText.getSelection();
											}
										}
									}
								}
								IDocument detailDoc = getDetailDocument();
								if (fFirst) {
									if (insert.equals(detailDoc.get())) {
										topIndex = -1; // source not modified,
														// no need to set the
														// document
									} else {
										detailDoc.set(insert);
									}
									fFirst = false;
								} else {
									detailDoc.replace(length, 0, insert);
								}
								if (topIndex > -1) {
									styledText.setTopIndex(topIndex);
									if (selection != null) {
										styledText.setSelection(selection);
									}
								}
							} catch (BadLocationException e) {
								DebugUIPlugin.log(e);
							}
						}
						return Status.OK_STATUS;
					}

					private boolean containsLineDelimiter(String str) {
						if (str.contains("\n") || str.contains("\r")) { //$NON-NLS-1$ //$NON-NLS-2$
							return true;
						}
						return false;
					}
				};
				append.setSystem(true);
				append.schedule();
			}
			synchronized (this) {
				notifyAll();
			}

		}

	}

	/**
	 * The model presentation used to produce the string details for a
	 * selected variable.
	 */
	private VariablesViewModelPresentation fModelPresentation;
	private String fDebugModelIdentifier;

	/**
	 * Controls the status line while the details area has focus.
	 * Displays the current cursor position in the text (line:character).
	 */
	private StatusLineContributionItem fStatusLineItem;

	/**
	 * The source viewer in which the computed string detail
	 * of selected variables will be displayed.
	 */
	private SourceViewer fSourceViewer;

	/**
	 * The last selection displayed in the source viewer.
	 */
	private IStructuredSelection fLastDisplayed = null;

	/**
	 * Flag used to track whether source viewer has focus.  It helps avoid
	 * resetting global actions incorrectly.
	 */
	private boolean fHasFocus = false;

	/**
	 * Variables used to create the detailed information for a selection
	 */
	private IDocument fDetailDocument;
	private DetailJob fDetailJob = null;
	private final String fPositionLabelPattern = DetailMessages.DefaultDetailPane_56;
	private final PositionLabelValue fLineLabel = new PositionLabelValue();
	private final PositionLabelValue fColumnLabel = new PositionLabelValue();
	private final Object[] fPositionLabelPatternArguments = new Object[] {
			fLineLabel, fColumnLabel };
	private ICursorListener fCursorListener;

	/**
	 * Handler activation object so that we can use the global content assist command
	 * and properly deactivate it later.
	 */
	private IHandlerActivation fContentAssistActivation;
	private IPropertyChangeListener fPreferenceStorePropertyChangeListener;
	private WhitespaceCharacterPainter fWhiteSpacePainter;

	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.IDetailPane#createControl(org.eclipse.swt.widgets.Composite)
	 */
	@Override
	public Control createControl(Composite parent) {

		fModelPresentation = new VariablesViewModelPresentation();

		createSourceViewer(parent);

		if (isInView()){
			createViewSpecificComponents();
			createActions();
			DebugUIPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(this);
			JFaceResources.getFontRegistry().addListener(this);
		}

		return fSourceViewer.getControl();
	}

	/**
	 * Creates the source viewer in the given parent composite
	 *
	 * @param parent Parent composite to create the source viewer in
	 */
	private void createSourceViewer(Composite parent) {

		// Create & configure a SourceViewer
		fSourceViewer = new SourceViewer(parent, null, SWT.V_SCROLL | SWT.H_SCROLL);
		fSourceViewer.setDocument(getDetailDocument());
		fSourceViewer.getTextWidget().setFont(JFaceResources.getFont(IDebugUIConstants.PREF_DETAIL_PANE_FONT));
		fSourceViewer.getTextWidget().setWordWrap(DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IDebugPreferenceConstants.PREF_DETAIL_PANE_WORD_WRAP));
		fSourceViewer.setEditable(false);
		PlatformUI.getWorkbench().getHelpSystem().setHelp(fSourceViewer.getTextWidget(), IDebugHelpContextIds.DETAIL_PANE);
		Control control = fSourceViewer.getControl();
		GridData gd = new GridData(GridData.FILL_BOTH);
		control.setLayoutData(gd);
		toggleWhitespaceCharacterPainter();
		installWhitespacePreferenceListener();
	}

	private void installWhitespacePreferenceListener() {
		IPreferenceStore store = EditorsUI.getPreferenceStore();
		fPreferenceStorePropertyChangeListener = new IPropertyChangeListener() {

			@Override
			public void propertyChange(PropertyChangeEvent event) {
				String property = event.getProperty();
				if (AbstractTextEditor.PREFERENCE_SHOW_WHITESPACE_CHARACTERS.equals(property)) {
					toggleWhitespaceCharacterPainter();
				}
			}
		};
		store.addPropertyChangeListener(fPreferenceStorePropertyChangeListener);
	}

	private void removePreferenceListener() {
		if (fPreferenceStorePropertyChangeListener != null) {
			IPreferenceStore store = EditorsUI.getPreferenceStore();
			store.removePropertyChangeListener(fPreferenceStorePropertyChangeListener);
			fPreferenceStorePropertyChangeListener = null;
		}
	}

	private void disposeWhitespaceCharacterPainter() {
		if (fWhiteSpacePainter != null) {
			fSourceViewer.removePainter(fWhiteSpacePainter);
			fWhiteSpacePainter.dispose();
			fWhiteSpacePainter = null;
		}
	}

	private void toggleWhitespaceCharacterPainter() {
		if (fSourceViewer == null || fSourceViewer.getTextWidget() == null) {
			return;
		}
		IPreferenceStore store = EditorsUI.getPreferenceStore();
		boolean checked = store.getBoolean(AbstractTextEditor.PREFERENCE_SHOW_WHITESPACE_CHARACTERS);
		if (checked) {
			fWhiteSpacePainter = new WhitespaceCharacterPainter(fSourceViewer);
			fSourceViewer.addPainter(fWhiteSpacePainter);
		} else {
			if (fWhiteSpacePainter != null) {
				fSourceViewer.removePainter(fWhiteSpacePainter);
				fWhiteSpacePainter = null;
			}
		}
	}

	/**
	 * Creates listeners and other components that should only be added to the
	 * source viewer when this detail pane is inside a view.
	 */
	private void createViewSpecificComponents(){

		// Add a document listener so actions get updated when the document changes
		getDetailDocument().addDocumentListener(new IDocumentListener() {
			@Override
			public void documentAboutToBeChanged(DocumentEvent event) {}
			@Override
			public void documentChanged(DocumentEvent event) {
				updateSelectionDependentActions();
			}
		});

		// Add the selection listener so selection dependent actions get updated.
		fSourceViewer.getSelectionProvider().addSelectionChangedListener(new ISelectionChangedListener() {
			@Override
			public void selectionChanged(SelectionChangedEvent event) {
				updateSelectionDependentActions();
			}
		});

		// Add a focus listener to update actions when details area gains focus
		fSourceViewer.getControl().addFocusListener(new FocusAdapter() {
			@Override
			public void focusGained(FocusEvent e) {
				setGlobalAction(IDebugView.SELECT_ALL_ACTION, getAction(DETAIL_SELECT_ALL_ACTION));
				setGlobalAction(IDebugView.CUT_ACTION, getAction(DETAIL_CUT_ACTION));
				setGlobalAction(IDebugView.COPY_ACTION, getAction(DETAIL_COPY_ACTION));
				setGlobalAction(IDebugView.PASTE_ACTION, getAction(DETAIL_PASTE_ACTION));
				setGlobalAction(IDebugView.FIND_ACTION, getAction(DETAIL_FIND_REPLACE_TEXT_ACTION));
				IAction action = getAction(DETAIL_ASSIGN_VALUE_ACTION);
				setGlobalAction(action.getActionDefinitionId(), action);
				action = getAction(DETAIL_CONTENT_ASSIST_ACTION);
				setGlobalAction(action.getActionDefinitionId(),action);

				getViewSite().getActionBars().updateActionBars();

				updateAction(DETAIL_FIND_REPLACE_TEXT_ACTION);
				fHasFocus = true;
			}

			@Override
			public void focusLost(FocusEvent e) {
				setGlobalAction(IDebugView.SELECT_ALL_ACTION, null);
				setGlobalAction(IDebugView.CUT_ACTION, null);
				setGlobalAction(IDebugView.COPY_ACTION, null);
				setGlobalAction(IDebugView.PASTE_ACTION, null);
				setGlobalAction(IDebugView.FIND_ACTION, null);
				setGlobalAction(getAction(DETAIL_ASSIGN_VALUE_ACTION).getActionDefinitionId(), null);
				setGlobalAction(getAction(DETAIL_CONTENT_ASSIST_ACTION).getActionDefinitionId(), null);

				getViewSite().getActionBars().updateActionBars();
				fHasFocus = false;
			}
		});

		// disposed controls don't get a FocusOut event, make sure all actions
		// have been deactivated
		fSourceViewer.getControl().addDisposeListener(new DisposeListener() {
			@Override
			public void widgetDisposed(DisposeEvent e) {
				if (fHasFocus) {
					setGlobalAction(IDebugView.SELECT_ALL_ACTION, null);
					setGlobalAction(IDebugView.CUT_ACTION, null);
					setGlobalAction(IDebugView.COPY_ACTION, null);
					setGlobalAction(IDebugView.PASTE_ACTION, null);
					setGlobalAction(IDebugView.FIND_ACTION, null);
					setGlobalAction(getAction(DETAIL_ASSIGN_VALUE_ACTION)
							.getActionDefinitionId(), null);
					setGlobalAction(getAction(DETAIL_CONTENT_ASSIST_ACTION)
							.getActionDefinitionId(), null);
				}
			}
		});

		// Create a status line item displaying the current cursor location
		fStatusLineItem = new StatusLineContributionItem("ModeContributionItem"); //$NON-NLS-1$
		IStatusLineManager manager= getViewSite().getActionBars().getStatusLineManager();
		manager.add(fStatusLineItem);
		fSourceViewer.getTextWidget().addMouseListener(getCursorListener());
		fSourceViewer.getTextWidget().addKeyListener(getCursorListener());

		// Add a context menu to the detail area
		createDetailContextMenu(fSourceViewer.getTextWidget());

	}

	/**
	 * Creates the actions to add to the context menu
	 */
	private void createActions() {
		TextViewerAction textAction= new TextViewerAction(fSourceViewer, ISourceViewer.CONTENTASSIST_PROPOSALS);
		textAction.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
		textAction.configureAction(DetailMessages.DefaultDetailPane_Co_ntent_Assist_3, IInternalDebugCoreConstants.EMPTY_STRING,IInternalDebugCoreConstants.EMPTY_STRING);
		textAction.setImageDescriptor(DebugPluginImages.getImageDescriptor(IDebugUIConstants.IMG_ELCL_CONTENT_ASSIST));
		textAction.setHoverImageDescriptor(DebugPluginImages.getImageDescriptor(IDebugUIConstants.IMG_LCL_CONTENT_ASSIST));
		textAction.setDisabledImageDescriptor(DebugPluginImages.getImageDescriptor(IDebugUIConstants.IMG_DLCL_CONTENT_ASSIST));
		PlatformUI.getWorkbench().getHelpSystem().setHelp(textAction, IDebugHelpContextIds.DETAIL_PANE_CONTENT_ASSIST_ACTION);
		ActionHandler actionHandler = new ActionHandler(textAction);
        IHandlerService handlerService = getViewSite().getService(IHandlerService.class);
        fContentAssistActivation = handlerService.activateHandler(textAction.getActionDefinitionId(), actionHandler);
        setAction(DETAIL_CONTENT_ASSIST_ACTION, textAction);

		textAction= new TextViewerAction(fSourceViewer, ITextOperationTarget.SELECT_ALL);
		textAction.configureAction(DetailMessages.DefaultDetailPane_Select__All_5, IInternalDebugCoreConstants.EMPTY_STRING,IInternalDebugCoreConstants.EMPTY_STRING);
		textAction.setActionDefinitionId(IWorkbenchCommandConstants.EDIT_SELECT_ALL);
		PlatformUI.getWorkbench().getHelpSystem().setHelp(textAction, IDebugHelpContextIds.DETAIL_PANE_SELECT_ALL_ACTION);
		setAction(DETAIL_SELECT_ALL_ACTION, textAction);

		textAction= new TextViewerAction(fSourceViewer, ITextOperationTarget.COPY);
		textAction.configureAction(DetailMessages.DefaultDetailPane__Copy_8, IInternalDebugCoreConstants.EMPTY_STRING,IInternalDebugCoreConstants.EMPTY_STRING);
		textAction.setActionDefinitionId(IWorkbenchCommandConstants.EDIT_COPY);
		PlatformUI.getWorkbench().getHelpSystem().setHelp(textAction, IDebugHelpContextIds.DETAIL_PANE_COPY_ACTION);
		setAction(DETAIL_COPY_ACTION, textAction);

		textAction= new TextViewerAction(fSourceViewer, ITextOperationTarget.CUT);
		textAction.configureAction(DetailMessages.DefaultDetailPane_Cu_t_11, IInternalDebugCoreConstants.EMPTY_STRING,IInternalDebugCoreConstants.EMPTY_STRING);
		textAction.setActionDefinitionId(IWorkbenchCommandConstants.EDIT_CUT);
		PlatformUI.getWorkbench().getHelpSystem().setHelp(textAction, IDebugHelpContextIds.DETAIL_PANE_CUT_ACTION);
		setAction(DETAIL_CUT_ACTION, textAction);

		textAction= new TextViewerAction(fSourceViewer, ITextOperationTarget.PASTE);
		textAction.configureAction(DetailMessages.DefaultDetailPane__Paste_14, IInternalDebugCoreConstants.EMPTY_STRING,IInternalDebugCoreConstants.EMPTY_STRING);
		textAction.setActionDefinitionId(IWorkbenchCommandConstants.EDIT_PASTE);
		PlatformUI.getWorkbench().getHelpSystem().setHelp(textAction, IDebugHelpContextIds.DETAIL_PANE_PASTE_ACTION);
		setAction(ActionFactory.PASTE.getId(), textAction);

		setSelectionDependantAction(DETAIL_COPY_ACTION);
		setSelectionDependantAction(DETAIL_CUT_ACTION);
		setSelectionDependantAction(DETAIL_PASTE_ACTION);

		// TODO: Still using "old" resource access, find/replace won't work in popup dialogs
		ResourceBundle bundle= ResourceBundle.getBundle("org.eclipse.debug.internal.ui.views.variables.VariablesViewResourceBundleMessages"); //$NON-NLS-1$
		IAction action = new FindReplaceAction(bundle, "find_replace_action_", getWorkbenchPartSite().getShell(), new FindReplaceTargetWrapper(fSourceViewer.getFindReplaceTarget())); //$NON-NLS-1$
		action.setActionDefinitionId(IWorkbenchCommandConstants.EDIT_FIND_AND_REPLACE);
		PlatformUI.getWorkbench().getHelpSystem().setHelp(action, IDebugHelpContextIds.DETAIL_PANE_FIND_REPLACE_ACTION);
		setAction(DETAIL_FIND_REPLACE_TEXT_ACTION, action);

		updateSelectionDependentActions();

		action = new DetailPaneWordWrapAction(fSourceViewer);
		setAction(DETAIL_WORD_WRAP_ACTION, action);

		action = new DetailPaneMaxLengthAction(fSourceViewer.getControl().getShell());
		setAction(DETAIL_MAX_LENGTH_ACTION,action);

		action = new DetailPaneAssignValueAction(fSourceViewer,getViewSite());
		setAction(DETAIL_ASSIGN_VALUE_ACTION, action);
	}

	/**
	 * Create the context menu particular to the detail pane.  Note that anyone
	 * wishing to contribute an action to this menu must use
	 * <code>IDebugUIConstants.VARIABLE_VIEW_DETAIL_ID</code> as the
	 * <code>targetID</code> in the extension XML.
	 * @param menuControl the control to create the context menu on
	 */
	protected void createDetailContextMenu(Control menuControl) {
		MenuManager menuMgr= new MenuManager();
		menuMgr.setRemoveAllWhenShown(true);
		menuMgr.addMenuListener(new IMenuListener() {
			@Override
			public void menuAboutToShow(IMenuManager mgr) {
				fillDetailContextMenu(mgr);
			}
		});
		Menu menu= menuMgr.createContextMenu(menuControl);
		menuControl.setMenu(menu);

		getViewSite().registerContextMenu(IDebugUIConstants.VARIABLE_VIEW_DETAIL_ID, menuMgr, fSourceViewer.getSelectionProvider());

	}

	/**
	* Adds items to the detail pane's context menu including any extension defined
	* actions.
	*
	* @param menu The menu to add the item to.
	*/
	protected void fillDetailContextMenu(IMenuManager menu) {

		menu.add(new Separator(IDebugUIConstants.VARIABLE_GROUP));
		if (isInView()){
			menu.add(getAction(DETAIL_ASSIGN_VALUE_ACTION));
			menu.add(getAction(DETAIL_CONTENT_ASSIST_ACTION));
		}
		menu.add(new Separator());
		menu.add(getAction(DETAIL_CUT_ACTION));
		menu.add(getAction(DETAIL_COPY_ACTION));
		menu.add(getAction(DETAIL_PASTE_ACTION));
		menu.add(getAction(DETAIL_SELECT_ALL_ACTION));
		menu.add(new Separator("FIND")); //$NON-NLS-1$
		if (isInView()){
			menu.add(getAction(DETAIL_FIND_REPLACE_TEXT_ACTION));
		}
		menu.add(new Separator());
		menu.add(getAction(DETAIL_WORD_WRAP_ACTION));
		menu.add(getAction(DETAIL_MAX_LENGTH_ACTION));
		menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));

	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.IDetailPane#display(org.eclipse.jface.viewers.IStructuredSelection)
	 */
	@Override
	public void display(IStructuredSelection selection) {

		if (selection == null){
			clearSourceViewer();
			return;
		}

		fLastDisplayed = selection;
		if (isInView()){
			fSourceViewer.setEditable(true);
		}

		if (selection.isEmpty()){
			clearSourceViewer();
			return;
		}

		Object firstElement = selection.getFirstElement();
		if (firstElement != null && firstElement instanceof IDebugElement) {
			String modelID = ((IDebugElement)firstElement).getModelIdentifier();
			setDebugModel(modelID);
		}

		if (isInView()){
			IAction assignAction = getAction(DETAIL_ASSIGN_VALUE_ACTION);
			if (assignAction instanceof DetailPaneAssignValueAction){
				((DetailPaneAssignValueAction)assignAction).updateCurrentVariable(selection);
			}
		}

        synchronized (this) {
        	if (fDetailJob != null) {
        		fDetailJob.cancel();
        	}
			fDetailJob = new DetailJob(selection,fModelPresentation);
			fDetailJob.schedule();
        }

	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.IDetailPane#setFocus()
	 */
	@Override
	public boolean setFocus(){
		if (fSourceViewer != null){
			fSourceViewer.getTextWidget().setFocus();
			return true;
		}
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.internal.ui.views.variables.details.AbstractDetailPane#dispose()
	 */
	@Override
	public void dispose(){
		if (fDetailJob != null) {
			fDetailJob.cancel();
		}
		if (fModelPresentation != null) {
			fModelPresentation.dispose();
		}
		fDebugModelIdentifier = null; // Setting this to null makes sure the source viewer is reconfigured with the model presentation after disposal
		if (fSourceViewer != null && fSourceViewer.getControl() != null) {
			removePreferenceListener();
			disposeWhitespaceCharacterPainter();
			fSourceViewer.getControl().dispose();
		}

		if (isInView()){
			IAction action = getAction(DETAIL_ASSIGN_VALUE_ACTION);
			if (action != null){
				((DetailPaneAssignValueAction)action).dispose();
			}
			if (fContentAssistActivation != null){
				IHandlerService service = getViewSite().getService(IHandlerService.class);
		        service.deactivateHandler(fContentAssistActivation);
		        fContentAssistActivation = null;
			}

			disposeUndoRedoAction(ITextEditorActionConstants.UNDO);
			disposeUndoRedoAction(ITextEditorActionConstants.REDO);

			getViewSite().getActionBars().getStatusLineManager().remove(fStatusLineItem);

			DebugUIPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(this);
			JFaceResources.getFontRegistry().removeListener(this);
		}

		super.dispose();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.IDetailPane#getDescription()
	 */
	@Override
	public String getDescription() {
		return DESCRIPTION;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.IDetailPane#getID()
	 */
	@Override
	public String getID() {
		return ID;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.IDetailPane#getName()
	 */
	@Override
	public String getName() {
		return NAME;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
	 */
	@SuppressWarnings("unchecked")
	@Override
	public <T> T getAdapter(Class<T> required) {
		if (IFindReplaceTarget.class.equals(required)) {
			return (T) fSourceViewer.getFindReplaceTarget();
		}
		if (ITextViewer.class.equals(required)) {
			return (T) fSourceViewer;
		}
		return null;
	}

	/**
	 * Lazily instantiate and return a Document for the detail pane text viewer.
	 * @return the singleton {@link Document} for this detail pane
	 */
	protected IDocument getDetailDocument() {
		if (fDetailDocument == null) {
			fDetailDocument = new Document();
		}
		return fDetailDocument;
	}

	/**
	 * Clears the source viewer, removes all text.
	 */
	protected void clearSourceViewer(){
		if (fDetailJob != null) {
			fDetailJob.cancel();
		}
		fLastDisplayed = null;
		fDetailDocument.set(IInternalDebugCoreConstants.EMPTY_STRING);
		fSourceViewer.setEditable(false);
	}

	/**
	 * Configures the details viewer for the debug model
	 * currently being displayed
	 */
	protected void configureDetailsViewer() {
		LazyModelPresentation mp = (LazyModelPresentation)fModelPresentation.getPresentation(getDebugModel());
		SourceViewerConfiguration svc = null;
		if (mp != null) {
			try {
				svc = mp.newDetailsViewerConfiguration();
			} catch (CoreException e) {
				DebugUIPlugin.errorDialog(fSourceViewer.getControl().getShell(), DetailMessages.DefaultDetailPane_Error_1, DetailMessages.DefaultDetailPane_2, e);
			}
		}

	    if (svc == null) {
			svc = new SourceViewerConfiguration();
			fSourceViewer.setEditable(false);
		}
	    fSourceViewer.unconfigure();
	    fSourceViewer.configure(svc);
		//update actions that depend on the configuration of the source viewer

		if (isInView()){
			updateAction(DETAIL_ASSIGN_VALUE_ACTION);
			updateAction(DETAIL_CONTENT_ASSIST_ACTION);
		}

		if (isInView()){
			createUndoRedoActions();
		}
	}

	/**
	 * @return The formatted string describing cursor position
	 */
	protected String getCursorPosition() {

		if (fSourceViewer == null) {
			return IInternalDebugCoreConstants.EMPTY_STRING;
		}

		StyledText styledText= fSourceViewer.getTextWidget();
		int caret= styledText.getCaretOffset();
		IDocument document= fSourceViewer.getDocument();

		if (document == null) {
			return IInternalDebugCoreConstants.EMPTY_STRING;
		}

		try {

			int line= document.getLineOfOffset(caret);

			int lineOffset= document.getLineOffset(line);
			int tabWidth= styledText.getTabs();
			int column= 0;
			for (int i= lineOffset; i < caret; i++) {
				if ('\t' == document.getChar(i)) {
					column += tabWidth - (tabWidth == 0 ? 0 : column % tabWidth);
				} else {
					column++;
				}
			}

			fLineLabel.fValue= line + 1;
			fColumnLabel.fValue= column + 1;
			return MessageFormat.format(fPositionLabelPattern, fPositionLabelPatternArguments);

		} catch (BadLocationException x) {
			return IInternalDebugCoreConstants.EMPTY_STRING;
		}
	}

	/**
	 * Returns this view's "cursor" listener to be installed on the view's
	 * associated details viewer. This listener is listening to key and mouse button events.
	 * It triggers the updating of the status line.
	 *
	 * @return the listener
	 */
	private ICursorListener getCursorListener() {
		if (fCursorListener == null) {
			fCursorListener= new ICursorListener() {

				@Override
				public void keyPressed(KeyEvent e) {
					fStatusLineItem.setText(getCursorPosition());
				}

				@Override
				public void keyReleased(KeyEvent e) {
				}

				@Override
				public void mouseDoubleClick(MouseEvent e) {
				}

				@Override
				public void mouseDown(MouseEvent e) {
				}

				@Override
				public void mouseUp(MouseEvent e) {
					fStatusLineItem.setText(getCursorPosition());
				}
			};
		}
		return fCursorListener;
	}

	/**
	 * Returns the identifier of the debug model being displayed
	 * in this view, or <code>null</code> if none.
	 *
	 * @return debug model identifier
	 */
	protected String getDebugModel() {
		return fDebugModelIdentifier;
	}

	/**
	 * Sets the identifier of the debug model being displayed
	 * in this view, or <code>null</code> if none.
	 *
	 * @param id debug model identifier of the type of debug
	 *  elements being displayed in this view
	 */
	protected void setDebugModel(String id) {
		if (id != fDebugModelIdentifier) {
			fDebugModelIdentifier = id;
			configureDetailsViewer();
		}
	}

	/**
	 * Creates this editor's undo/re-do actions.
	 * <p>
	 * Subclasses may override or extend.</p>
	 *
	 * @since 3.2
	 */
	protected void createUndoRedoActions() {
		disposeUndoRedoAction(ITextEditorActionConstants.UNDO);
		disposeUndoRedoAction(ITextEditorActionConstants.REDO);
		IUndoContext undoContext= getUndoContext();
		if (undoContext != null) {
			// Use actions provided by global undo/re-do

			// Create the undo action
			OperationHistoryActionHandler undoAction= new UndoActionHandler(getViewSite(), undoContext);
			PlatformUI.getWorkbench().getHelpSystem().setHelp(undoAction, IAbstractTextEditorHelpContextIds.UNDO_ACTION);
			undoAction.setActionDefinitionId(IWorkbenchCommandConstants.EDIT_UNDO);
			setAction(ITextEditorActionConstants.UNDO, undoAction);
			setGlobalAction(ITextEditorActionConstants.UNDO, undoAction);

			// Create the re-do action.
			OperationHistoryActionHandler redoAction= new RedoActionHandler(getViewSite(), undoContext);
			PlatformUI.getWorkbench().getHelpSystem().setHelp(redoAction, IAbstractTextEditorHelpContextIds.REDO_ACTION);
			redoAction.setActionDefinitionId(IWorkbenchCommandConstants.EDIT_REDO);
			setAction(ITextEditorActionConstants.REDO, redoAction);
			setGlobalAction(ITextEditorActionConstants.REDO, redoAction);

			getViewSite().getActionBars().updateActionBars();
		}
	}

	/**
	 * Disposes of the action with the specified ID
	 *
	 * @param actionId the ID of the action to disposed
	 */
	protected void disposeUndoRedoAction(String actionId) {
		OperationHistoryActionHandler action = (OperationHistoryActionHandler) getAction(actionId);
		if (action != null) {
			action.dispose();
			setAction(actionId, null);
		}
	}

	/**
	 * Returns this editor's viewer's undo manager undo context.
	 *
	 * @return the undo context or <code>null</code> if not available
	 * @since 3.2
	 */
	private IUndoContext getUndoContext() {
		IUndoManager undoManager= fSourceViewer.getUndoManager();
		if (undoManager instanceof IUndoManagerExtension) {
			return ((IUndoManagerExtension)undoManager).getUndoContext();
		}
		return null;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
	 */
	@Override
	public void propertyChange(PropertyChangeEvent event) {
		String propertyName= event.getProperty();
		if (propertyName.equals(IDebugUIConstants.PREF_DETAIL_PANE_FONT)) {
			fSourceViewer.getTextWidget().setFont(JFaceResources.getFont(IDebugUIConstants.PREF_DETAIL_PANE_FONT));
		} else if (propertyName.equals(IDebugUIConstants.PREF_MAX_DETAIL_LENGTH)) {
			display(fLastDisplayed);
		} else if (propertyName.equals(IDebugPreferenceConstants.PREF_DETAIL_PANE_WORD_WRAP)) {
			fSourceViewer.getTextWidget().setWordWrap(DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IDebugPreferenceConstants.PREF_DETAIL_PANE_WORD_WRAP));
			getAction(DETAIL_WORD_WRAP_ACTION).setChecked(DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IDebugPreferenceConstants.PREF_DETAIL_PANE_WORD_WRAP));
		}

	}

	/**
	 * Wrapper class that wraps around an IFindReplaceTarget.  Allows the detail pane to scroll
	 * to text selected by the find/replace action.  The source viewer treats the text as a single
	 * line, even when the text is wrapped onto several lines so the viewer will not scroll properly
	 * on it's own.  See bug 178106.
	 */
	class FindReplaceTargetWrapper implements IFindReplaceTarget{

		private IFindReplaceTarget fTarget;

		/**
		 * Constructor
		 *
		 * @param target find/replace target this class will wrap around.
		 */
		public FindReplaceTargetWrapper(IFindReplaceTarget target){
			fTarget = target;
		}

		/* (non-Javadoc)
		 * @see org.eclipse.jface.text.IFindReplaceTarget#canPerformFind()
		 */
		@Override
		public boolean canPerformFind() {
			return fTarget.canPerformFind();
		}

		/* (non-Javadoc)
		 * @see org.eclipse.jface.text.IFindReplaceTarget#findAndSelect(int, java.lang.String, boolean, boolean, boolean)
		 */
		@Override
		public int findAndSelect(int widgetOffset, String findString, boolean searchForward, boolean caseSensitive, boolean wholeWord) {
			int position = fTarget.findAndSelect(widgetOffset, findString, searchForward, caseSensitive, wholeWord);
			// Explicitly tell the widget to show the selection because the viewer thinks the text is all on one line, even if wrapping is turned on.
			if (fSourceViewer != null){
				StyledText text = fSourceViewer.getTextWidget();
				if(text != null && !text.isDisposed()) {
					text.showSelection();
				}
			}
			return position;
		}

		/* (non-Javadoc)
		 * @see org.eclipse.jface.text.IFindReplaceTarget#getSelection()
		 */
		@Override
		public Point getSelection() {
			return fTarget.getSelection();
		}

		/* (non-Javadoc)
		 * @see org.eclipse.jface.text.IFindReplaceTarget#getSelectionText()
		 */
		@Override
		public String getSelectionText() {
			return fTarget.getSelectionText();
		}

		/* (non-Javadoc)
		 * @see org.eclipse.jface.text.IFindReplaceTarget#isEditable()
		 */
		@Override
		public boolean isEditable() {
			return fTarget.isEditable();
		}

		/* (non-Javadoc)
		 * @see org.eclipse.jface.text.IFindReplaceTarget#replaceSelection(java.lang.String)
		 */
		@Override
		public void replaceSelection(String text) {
			fTarget.replaceSelection(text);
		}
	}

	/*
	 * @see org.eclipse.debug.ui.IDetailPane2#getSelectionProvider()
	 */
	@Override
	public ISelectionProvider getSelectionProvider() {
		return fSourceViewer.getSelectionProvider();
	}
}
