/*******************************************************************************
 * Copyright (c) 2000, 2018 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
 *     Lucas Bullen (Red Hat Inc.) - Bug 530664 - Debug Shell hint moved to content description
 *******************************************************************************/
package org.eclipse.jdt.internal.debug.ui.display;


import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.IHandler;
import org.eclipse.core.commands.operations.IUndoContext;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.jdt.debug.ui.IJavaDebugUIConstants;
import org.eclipse.jdt.internal.debug.ui.EvaluationContextManager;
import org.eclipse.jdt.internal.debug.ui.IJavaDebugHelpContextIds;
import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
import org.eclipse.jdt.internal.debug.ui.JDISourceViewer;
import org.eclipse.jdt.ui.PreferenceConstants;
import org.eclipse.jdt.ui.text.IJavaPartitions;
import org.eclipse.jdt.ui.text.JavaTextTools;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
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.ITextInputListener;
import org.eclipse.jface.text.ITextOperationTarget;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.IUndoManager;
import org.eclipse.jface.text.IUndoManagerExtension;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DragSource;
import org.eclipse.swt.dnd.DragSourceAdapter;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IPerspectiveDescriptor;
import org.eclipse.ui.IPerspectiveListener2;
import org.eclipse.ui.IViewReference;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.IWorkbenchCommandConstants;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.XMLMemento;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.console.actions.ClearOutputAction;
import org.eclipse.ui.handlers.IHandlerActivation;
import org.eclipse.ui.handlers.IHandlerService;
import org.eclipse.ui.operations.OperationHistoryActionHandler;
import org.eclipse.ui.operations.RedoActionHandler;
import org.eclipse.ui.operations.UndoActionHandler;
import org.eclipse.ui.part.ViewPart;
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 org.eclipse.ui.texteditor.IUpdate;
import org.eclipse.ui.themes.IThemeManager;

public class DisplayView extends ViewPart implements ITextInputListener, IPerspectiveListener2 {

	class DataDisplay implements IDataDisplay {
		/**
		 * @see IDataDisplay#clear()
		 */
		@Override
		public void clear() {
			IDocument document= fSourceViewer.getDocument();
			if (document != null) {
				document.set(""); //$NON-NLS-1$
			}
		}

		/**
		 * @see IDataDisplay#displayExpression(String)
		 */
		@Override
		public void displayExpression(String expression) {
			IDocument document= fSourceViewer.getDocument();
			int offset= document.getLength();
			try {
				// add a cariage return if needed.
				if (offset != document.getLineInformationOfOffset(offset).getOffset()) {
					expression= System.getProperty("line.separator") + expression.trim(); //$NON-NLS-1$
				}
				fSourceViewer.getDocument().replace(offset, 0, expression);
				fSourceViewer.setSelectedRange(offset + expression.length(), 0);
				fSourceViewer.revealRange(offset, expression.length());
			} catch (BadLocationException ble) {
				JDIDebugUIPlugin.log(ble);
			}
		}

		/**
		 * @see IDataDisplay#displayExpressionValue(String)
		 */
		@Override
		public void displayExpressionValue(String value) {
			value= System.getProperty("line.separator") + '\t' + value; //$NON-NLS-1$
			ITextSelection selection= (ITextSelection)fSourceViewer.getSelection();

			int offset= selection.getOffset() + selection.getLength();
			int length= value.length();
			try {
				fSourceViewer.getDocument().replace(offset, 0, value);
			} catch (BadLocationException ble) {
				JDIDebugUIPlugin.log(ble);
			}
			fSourceViewer.setSelectedRange(offset + length, 0);
			fSourceViewer.revealRange(offset, length);
		}
	}

	protected IDataDisplay fDataDisplay= new DataDisplay();
	protected IDocumentListener fDocumentListener= null;

	protected JDISourceViewer fSourceViewer;
	protected IAction fClearDisplayAction;
	protected DisplayViewAction fContentAssistAction;

	protected Map<String, IAction> fGlobalActions= new HashMap<>(4);
	protected List<String> fSelectionActions= new ArrayList<>(3);

	protected String fRestoredContents= null;
	/**
	 * This memento allows the Display view to save and restore state
	 * when it is closed and opened within a session. A different
	 * memento is supplied by the platform for persistance at
	 * workbench shutdown.
	 */
	private static IMemento fgMemento;
	private IHandlerActivation fHandlerActivation;

	/**
	 * @see ViewPart#createChild(IWorkbenchPartContainer)
	 */
	@Override
	public void createPartControl(Composite parent) {
		fSourceViewer= new JDISourceViewer(parent, null, SWT.V_SCROLL | SWT.H_SCROLL | SWT.MULTI | SWT.FULL_SELECTION | SWT.LEFT_TO_RIGHT);
		fSourceViewer.configure(new DisplayViewerConfiguration());
		fSourceViewer.getTextWidget().setFont(JFaceResources.getFont(PreferenceConstants.EDITOR_TEXT_FONT));
		IPropertyChangeListener fontListener = new IPropertyChangeListener() {
			@Override
			public void propertyChange(PropertyChangeEvent event) {
				if (PreferenceConstants.EDITOR_TEXT_FONT.equals(event.getProperty())) {
					final StyledText textWidget = fSourceViewer.getTextWidget();
					textWidget.getDisplay().asyncExec(() -> textWidget.setFont(JFaceResources.getFont(PreferenceConstants.EDITOR_TEXT_FONT)));
				}
			}
		};
		IThemeManager themeManager = getViewSite().getWorkbenchWindow().getWorkbench().getThemeManager();
		themeManager.addPropertyChangeListener(fontListener);
		fSourceViewer.getTextWidget().addDisposeListener(e -> themeManager.removePropertyChangeListener(fontListener));
		fSourceViewer.getSelectionProvider().addSelectionChangedListener(getSelectionChangedListener());
		fSourceViewer.setDocument(getRestoredDocument());
		fSourceViewer.addTextInputListener(this);
		fRestoredContents= null;
		createActions();
		createUndoRedoActions();
		initializeToolBar();
		this.setContentDescription(DisplayMessages.DisplayView_Content_Description);

		// create context menu
		MenuManager menuMgr = new MenuManager("#PopUp"); //$NON-NLS-1$
		menuMgr.setRemoveAllWhenShown(true);
		menuMgr.addMenuListener(new IMenuListener() {
			@Override
			public void menuAboutToShow(IMenuManager mgr) {
				fillContextMenu(mgr);
			}
		});

		Menu menu = menuMgr.createContextMenu(fSourceViewer.getTextWidget());
		fSourceViewer.getTextWidget().setMenu(menu);
		getSite().registerContextMenu(menuMgr, fSourceViewer.getSelectionProvider());

		getSite().setSelectionProvider(fSourceViewer.getSelectionProvider());
		PlatformUI.getWorkbench().getHelpSystem().setHelp(fSourceViewer.getTextWidget(), IJavaDebugHelpContextIds.DISPLAY_VIEW);
		getSite().getWorkbenchWindow().addPerspectiveListener(this);

		initDragAndDrop();
	}

	protected IDocument getRestoredDocument() {
		IDocument doc= null;
		if (fRestoredContents != null) {
			doc= new Document(fRestoredContents);
		} else {
			doc= new Document();
		}
		JavaTextTools tools= JDIDebugUIPlugin.getDefault().getJavaTextTools();
		tools.setupJavaDocumentPartitioner(doc, IJavaPartitions.JAVA_PARTITIONING);
		fDocumentListener= new IDocumentListener() {
			/**
			 * @see IDocumentListener#documentAboutToBeChanged(DocumentEvent)
			 */
			@Override
			public void documentAboutToBeChanged(DocumentEvent event) {
			}
			/**
			 * @see IDocumentListener#documentChanged(DocumentEvent)
			 */
			@Override
			public void documentChanged(DocumentEvent event) {
				updateAction(ActionFactory.FIND.getId());
			}
		};
		doc.addDocumentListener(fDocumentListener);

		return doc;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.IWorkbenchPart#setFocus()
	 */
	@Override
	public void setFocus() {
		if (fSourceViewer != null) {
			fSourceViewer.getControl().setFocus();
		}
	}

	/**
	 * Initialize the actions of this view
	 */
	protected void createActions() {

		fClearDisplayAction= new ClearOutputAction(fSourceViewer);

		IAction action= new DisplayViewAction(this, ITextOperationTarget.CUT);
		action.setText(DisplayMessages.DisplayView_Cut_label);
		action.setToolTipText(DisplayMessages.DisplayView_Cut_tooltip);
		action.setDescription(DisplayMessages.DisplayView_Cut_description);
		setGlobalAction(ActionFactory.CUT.getId(), action);

		action= new DisplayViewAction(this, ITextOperationTarget.COPY);
		action.setText(DisplayMessages.DisplayView_Copy_label);
		action.setToolTipText(DisplayMessages.DisplayView_Copy_tooltip);
		action.setDescription(DisplayMessages.DisplayView_Copy_description);
		setGlobalAction(ActionFactory.COPY.getId(), action);

		action= new DisplayViewAction(this, ITextOperationTarget.PASTE);
		action.setText(DisplayMessages.DisplayView_Paste_label);
		action.setToolTipText(DisplayMessages.DisplayView_Paste_tooltip);
		action.setDescription(DisplayMessages.DisplayView_Paste_Description);
		setGlobalAction(ActionFactory.PASTE.getId(), action);

		action= new DisplayViewAction(this, ITextOperationTarget.SELECT_ALL);
		action.setText(DisplayMessages.DisplayView_SelectAll_label);
		action.setToolTipText(DisplayMessages.DisplayView_SelectAll_tooltip);
		action.setDescription(DisplayMessages.DisplayView_SelectAll_description);
		setGlobalAction(ActionFactory.SELECT_ALL.getId(), action);

		//TODO: Still using "old" resource access
		ResourceBundle bundle= ResourceBundle.getBundle("org.eclipse.jdt.internal.debug.ui.display.DisplayResourceBundleMessages"); //$NON-NLS-1$
		FindReplaceAction findReplaceAction = new FindReplaceAction(bundle, "find_replace_action_", this); //$NON-NLS-1$
		findReplaceAction.setActionDefinitionId(IWorkbenchCommandConstants.EDIT_FIND_AND_REPLACE);
		setGlobalAction(ActionFactory.FIND.getId(), findReplaceAction);

		fSelectionActions.add(ActionFactory.CUT.getId());
		fSelectionActions.add(ActionFactory.COPY.getId());
		fSelectionActions.add(ActionFactory.PASTE.getId());

		fContentAssistAction= new DisplayViewAction(this, ISourceViewer.CONTENTASSIST_PROPOSALS);
		fContentAssistAction.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
		fContentAssistAction.setText(DisplayMessages.DisplayView_Co_ntent_Assist_Ctrl_Space_1);
		fContentAssistAction.setDescription(DisplayMessages.DisplayView_Content_Assist_2);
		fContentAssistAction.setToolTipText(DisplayMessages.DisplayView_Content_Assist_2);
		fContentAssistAction.setImageDescriptor(DebugUITools.getImageDescriptor(IDebugUIConstants.IMG_ELCL_CONTENT_ASSIST));
		fContentAssistAction.setHoverImageDescriptor(DebugUITools.getImageDescriptor(IDebugUIConstants.IMG_LCL_CONTENT_ASSIST));
		fContentAssistAction.setDisabledImageDescriptor(DebugUITools.getImageDescriptor(IDebugUIConstants.IMG_DLCL_CONTENT_ASSIST));
		getViewSite().getActionBars().updateActionBars();

		IHandler handler = new AbstractHandler() {
			@Override
			public Object execute(ExecutionEvent event) throws ExecutionException {
				fContentAssistAction.run();
				return null;
			}

		};

		IHandlerService handlerService = getSite().getService(IHandlerService.class);
		fHandlerActivation = handlerService.activateHandler(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS, handler);
	}

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

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

			// Create the redo action.
			OperationHistoryActionHandler redoAction= new RedoActionHandler(getSite(), undoContext);
			PlatformUI.getWorkbench().getHelpSystem().setHelp(redoAction, IAbstractTextEditorHelpContextIds.REDO_ACTION);
			redoAction.setActionDefinitionId(IWorkbenchCommandConstants.EDIT_REDO);
			setGlobalAction(ITextEditorActionConstants.REDO, redoAction);
		}
	}

	/**
	 * 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;
	}

	protected void setGlobalAction(String actionID, IAction action) {
		IActionBars actionBars = getViewSite().getActionBars();
		fGlobalActions.put(actionID, action);
		actionBars.setGlobalActionHandler(actionID, action);
	}

	/**
	 * Configures the toolBar.
	 */
	private void initializeToolBar() {
		IToolBarManager tbm = getViewSite().getActionBars().getToolBarManager();
		tbm.add(new Separator(IJavaDebugUIConstants.EVALUATION_GROUP));
		tbm.add(fClearDisplayAction);
		getViewSite().getActionBars().updateActionBars();
	}

	/**
	 * Adds the context menu actions for the display view.
	 */
	protected void fillContextMenu(IMenuManager menu) {

		if (fSourceViewer.getDocument() == null) {
			return;
		}
		menu.add(new Separator(IJavaDebugUIConstants.EVALUATION_GROUP));
		if (EvaluationContextManager.getEvaluationContext(this) != null) {
			menu.add(fContentAssistAction);
		}
		menu.add(new Separator());
		menu.add(fGlobalActions.get(ActionFactory.CUT.getId()));
		menu.add(fGlobalActions.get(ActionFactory.COPY.getId()));
		menu.add(fGlobalActions.get(ActionFactory.PASTE.getId()));
		menu.add(fGlobalActions.get(ActionFactory.SELECT_ALL.getId()));
		menu.add(new Separator());
		menu.add(fGlobalActions.get(ActionFactory.FIND.getId()));
		menu.add(fClearDisplayAction);
		menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.part.WorkbenchPart#getAdapter(Class)
	 */
	@SuppressWarnings("unchecked")
	@Override
	public <T> T getAdapter(Class<T> required) {

		if (ITextOperationTarget.class.equals(required)) {
			return (T) fSourceViewer.getTextOperationTarget();
		}

		if (IFindReplaceTarget.class.equals(required)) {
			return (T) fSourceViewer.getFindReplaceTarget();
		}

		if (IDataDisplay.class.equals(required)) {
			return (T) fDataDisplay;
		}
		if (ITextViewer.class.equals(required)) {
			return (T) fSourceViewer;
		}

		return super.getAdapter(required);
	}

	protected void updateActions() {
		Iterator<String> iterator = fSelectionActions.iterator();
		while (iterator.hasNext()) {
			IAction action = fGlobalActions.get(iterator.next());
			if (action instanceof IUpdate) {
				 ((IUpdate) action).update();
			}
		}
	}

	/**
	 * Saves the contents of the display view and the formatting.
	 *
	 * @see org.eclipse.ui.IViewPart#saveState(IMemento)
	 */
	@Override
	public void saveState(IMemento memento) {
		if (fSourceViewer != null) {
		    String contents= getContents();
		    if (contents != null) {
		        memento.putTextData(contents);
		    }
		} else if (fRestoredContents != null) {
			memento.putTextData(fRestoredContents);
		}
	}

	/**
	 * Restores the contents of the display view and the formatting.
	 *
	 * @see org.eclipse.ui.IViewPart#init(IViewSite, IMemento)
	 */
	@Override
	public void init(IViewSite site, IMemento memento) throws PartInitException {
		init(site);
		if (fgMemento != null) {
			memento= fgMemento;
		}
		if (memento != null) {
			fRestoredContents= memento.getTextData();
		}
	}

    /**
     * Initializes the drag and/or drop adapters for this view.
     *
     * @since 3.4
     */
    protected void initDragAndDrop() {
        // Drag only
    	DragSource ds = new DragSource(fSourceViewer.getTextWidget(), DND.DROP_COPY | DND.DROP_MOVE);
    	ds.setTransfer(new Transfer[] {TextTransfer.getInstance()});
    	ds.addDragListener(new DragSourceAdapter() {
        	@Override
			public void dragSetData(org.eclipse.swt.dnd.DragSourceEvent event) {
        		event.data = fSourceViewer.getTextWidget().getSelectionText();
        	}
        });
    }

	/**
	 * Returns the entire trimmed contents of the current document.
	 * If the contents are "empty" <code>null</code> is returned.
	 */
	private String getContents() {
	    if (fSourceViewer != null) {
			IDocument doc= fSourceViewer.getDocument();
			if (doc != null) {
				String contents= doc.get().trim();
				if (contents.length() > 0) {
				    return contents;
				}
			}
	    }
	    return null;
	}

	protected final ISelectionChangedListener getSelectionChangedListener() {
		return new ISelectionChangedListener() {
				@Override
				public void selectionChanged(SelectionChangedEvent event) {
					updateSelectionDependentActions();
				}
			};
	}

	protected void updateSelectionDependentActions() {
		Iterator<String> iterator= fSelectionActions.iterator();
		while (iterator.hasNext()) {
			updateAction(iterator.next());
		}
	}


	protected void updateAction(String actionId) {
		IAction action= fGlobalActions.get(actionId);
		if (action instanceof IUpdate) {
			((IUpdate) action).update();
		}
	}
	/**
	 * @see ITextInputListener#inputDocumentAboutToBeChanged(IDocument, IDocument)
	 */
	@Override
	public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) {
	}

	/**
	 * @see ITextInputListener#inputDocumentChanged(IDocument, IDocument)
	 */
	@Override
	public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
		oldInput.removeDocumentListener(fDocumentListener);
	}
	/* (non-Javadoc)
	 * @see org.eclipse.ui.IWorkbenchPart#dispose()
	 */
	@Override
	public void dispose() {
		getSite().getWorkbenchWindow().removePerspectiveListener(this);
		if (fSourceViewer != null) {
			fSourceViewer.dispose();
			fSourceViewer = null;
		}

		IHandlerService handlerService = getSite().getService(IHandlerService.class);
		handlerService.deactivateHandler(fHandlerActivation);

		super.dispose();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.IPerspectiveListener2#perspectiveChanged(org.eclipse.ui.IWorkbenchPage, org.eclipse.ui.IPerspectiveDescriptor, org.eclipse.ui.IWorkbenchPartReference, java.lang.String)
	 */
	@Override
	public void perspectiveChanged(IWorkbenchPage page, IPerspectiveDescriptor perspective, IWorkbenchPartReference partRef, String changeId) {
		if (partRef instanceof IViewReference && changeId.equals(IWorkbenchPage.CHANGE_VIEW_HIDE)) {
			String id = ((IViewReference) partRef).getId();
			if (id.equals(getViewSite().getId())) {
				// Display view closed. Persist contents.
			    String contents= getContents();
			    if (contents != null) {
				    fgMemento= XMLMemento.createWriteRoot("DisplayViewMemento"); //$NON-NLS-1$
				    fgMemento.putTextData(contents);
			    }
			}
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.IPerspectiveListener#perspectiveActivated(org.eclipse.ui.IWorkbenchPage, org.eclipse.ui.IPerspectiveDescriptor)
	 */
	@Override
	public void perspectiveActivated(IWorkbenchPage page, IPerspectiveDescriptor perspective) {
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.IPerspectiveListener#perspectiveChanged(org.eclipse.ui.IWorkbenchPage, org.eclipse.ui.IPerspectiveDescriptor, java.lang.String)
	 */
	@Override
	public void perspectiveChanged(IWorkbenchPage page, IPerspectiveDescriptor perspective, String changeId) {
	}

}
