/*******************************************************************************
 * Copyright (c) 2000, 2015 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Tom Eicher (Avaloq Evolution AG) - block selection mode
 *******************************************************************************/

package org.eclipse.ui.texteditor;


import java.util.HashMap;
import java.util.Map;

import org.eclipse.core.runtime.Assert;

import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IContributionItem;
import org.eclipse.jface.action.IContributionManager;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IStatusLineManager;
import org.eclipse.jface.action.Separator;

import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.part.EditorActionBarContributor;


/**
 * Manages the installation and removal of global actions for the same type of
 * editors.
 * <p>
 * If instantiated and used as-is, this contributor connects to all of the
 * workbench defined global editor actions the corresponding actions of the
 * current editor. It also adds addition actions for searching and navigation
 * (go to line) as well as a set of status fields.
 * </p>
 * <p>
 * Subclasses may override the following methods:
 * </p>
 * <ul>
 * <li><code>contributeToMenu</code> - extend to contribute to menu</li>
 * <li><code>contributeToToolBar</code> - reimplement to contribute to tool
 * bar</li>
 * <li><code>contributeToStatusLine</code> - reimplement to contribute to status
 * line</li>
 * <li><code>setActiveEditor</code> - extend to react to editor changes</li>
 * </ul>
 * 
 * @see org.eclipse.ui.texteditor.ITextEditorActionConstants
 */
public class BasicTextEditorActionContributor extends EditorActionBarContributor {


	/** The global actions to be connected with editor actions */
	private final static String[] ACTIONS= {
		ITextEditorActionConstants.UNDO,
		ITextEditorActionConstants.REDO,
		ITextEditorActionConstants.CUT,
		ITextEditorActionConstants.COPY,
		ITextEditorActionConstants.PASTE,
		ITextEditorActionConstants.DELETE,
		ITextEditorActionConstants.SELECT_ALL,
		ITextEditorActionConstants.FIND,
		ITextEditorActionConstants.PRINT,
		ITextEditorActionConstants.PROPERTIES,
		ITextEditorActionConstants.REVERT
	};

	/**
	 * Status field definition.
	 * @since 3.0
	 */
	private static class StatusFieldDef {

		private String category;
		private String actionId;
		private boolean visible;
		private int widthInChars;

		private StatusFieldDef(String category, String actionId, boolean visible, int widthInChars) {
			Assert.isNotNull(category);
			this.category= category;
			this.actionId= actionId;
			this.visible= visible;
			this.widthInChars= widthInChars;
		}
	}

	/**
	 * The status fields to be set to the editor
	 * @since 3.0
	 */
	private final static StatusFieldDef[] STATUS_FIELD_DEFS= {
		new StatusFieldDef(ITextEditorActionConstants.STATUS_CATEGORY_FIND_FIELD, null, false, EditorMessages.Editor_FindIncremental_reverse_name.length() + 15),
		new StatusFieldDef(ITextEditorActionConstants.STATUS_CATEGORY_ELEMENT_STATE, null, true, StatusLineContributionItem.DEFAULT_WIDTH_IN_CHARS + 1),
		new StatusFieldDef(ITextEditorActionConstants.STATUS_CATEGORY_INPUT_MODE, ITextEditorActionDefinitionIds.TOGGLE_OVERWRITE, true, StatusLineContributionItem.DEFAULT_WIDTH_IN_CHARS),
		new StatusFieldDef(ITextEditorActionConstants.STATUS_CATEGORY_INPUT_POSITION, ITextEditorActionConstants.GOTO_LINE, true, StatusLineContributionItem.DEFAULT_WIDTH_IN_CHARS)
	};

	/**
	 * The active editor part.
	 */
	private IEditorPart fActiveEditorPart;
	/**
	 * The find next action.
	 * @since 2.0
	 */
	private RetargetTextEditorAction fFindNext;
	/**
	 * The find previous action.
	 * @since 2.0
	 */
	private RetargetTextEditorAction fFindPrevious;
	/**
	 * The incremental find action.
	 * @since 2.0
	 */
	private RetargetTextEditorAction fIncrementalFind;
	/**
	 * The reverse incremental find action.
	 * @since 2.1
	 */
	private RetargetTextEditorAction fIncrementalFindReverse;
	/**
	 * The go to line action.
	 */
	private RetargetTextEditorAction fGotoLine;
	/**
	 * The word completion action.
	 * @since 3.1
	 */
	private RetargetTextEditorAction fHippieCompletion;
	/**
	 * The map of status fields.
	 * @since 2.0
	 */
	private Map<StatusFieldDef, StatusLineContributionItem> fStatusFields;


	/**
	 * Creates an empty editor action bar contributor. The action bars are
	 * furnished later via the <code>init</code> method.
	 *
	 * @see org.eclipse.ui.IEditorActionBarContributor#init(org.eclipse.ui.IActionBars, org.eclipse.ui.IWorkbenchPage)
	 */
	public BasicTextEditorActionContributor() {

		fFindNext= new RetargetTextEditorAction(EditorMessages.getBundleForConstructedKeys(), "Editor.FindNext."); //$NON-NLS-1$
		fFindNext.setActionDefinitionId(IWorkbenchActionDefinitionIds.FIND_NEXT);
		fFindPrevious= new RetargetTextEditorAction(EditorMessages.getBundleForConstructedKeys(), "Editor.FindPrevious."); //$NON-NLS-1$
		fFindPrevious.setActionDefinitionId(IWorkbenchActionDefinitionIds.FIND_PREVIOUS);
		fIncrementalFind= new RetargetTextEditorAction(EditorMessages.getBundleForConstructedKeys(), "Editor.FindIncremental."); //$NON-NLS-1$
		fIncrementalFind.setActionDefinitionId(IWorkbenchActionDefinitionIds.FIND_INCREMENTAL);
		fIncrementalFindReverse= new RetargetTextEditorAction(EditorMessages.getBundleForConstructedKeys(), "Editor.FindIncrementalReverse."); //$NON-NLS-1$
		fIncrementalFindReverse.setActionDefinitionId(IWorkbenchActionDefinitionIds.FIND_INCREMENTAL_REVERSE);
		fGotoLine= new RetargetTextEditorAction(EditorMessages.getBundleForConstructedKeys(), "Editor.GotoLine."); //$NON-NLS-1$
		fGotoLine.setActionDefinitionId(ITextEditorActionDefinitionIds.LINE_GOTO);
		fHippieCompletion= new RetargetTextEditorAction(EditorMessages.getBundleForConstructedKeys(), "Editor.HippieCompletion."); //$NON-NLS-1$
		fHippieCompletion.setActionDefinitionId(ITextEditorActionDefinitionIds.HIPPIE_COMPLETION);

		fStatusFields= new HashMap<>(3);
		for (int i= 0; i < STATUS_FIELD_DEFS.length; i++) {
			StatusFieldDef fieldDef= STATUS_FIELD_DEFS[i];
			fStatusFields.put(fieldDef, new StatusLineContributionItem(fieldDef.category, fieldDef.visible, fieldDef.widthInChars));
		}
	}

	/**
	 * Returns the active editor part.
	 *
	 * @return the active editor part
	 */
	protected final IEditorPart getActiveEditorPart() {
		return fActiveEditorPart;
	}

	/**
	 * Returns the action registered with the given text editor.
	 *
	 * @param editor the editor, or <code>null</code>
	 * @param actionId the action id
	 * @return the action, or <code>null</code> if none
	 */
	protected final IAction getAction(ITextEditor editor, String actionId) {
		return (editor == null || actionId == null ? null : editor.getAction(actionId));
	}

	/**
	 * The method installs the global action handlers for the given text editor.
	 * <p>
	 * This method cannot be overridden by subclasses.</p>
	 *
	 * @param part the active editor part
	 * @since 2.0
	 */
	private void doSetActiveEditor(IEditorPart part) {

		if (fActiveEditorPart == part)
			return;

		if (fActiveEditorPart instanceof ITextEditorExtension) {
			ITextEditorExtension extension= (ITextEditorExtension) fActiveEditorPart;
			for (int i= 0; i < STATUS_FIELD_DEFS.length; i++)
				extension.setStatusField(null, STATUS_FIELD_DEFS[i].category);
		}

		fActiveEditorPart= part;
		ITextEditor editor= (part instanceof ITextEditor) ? (ITextEditor) part : null;

		IActionBars actionBars= getActionBars();
		for (int i= 0; i < ACTIONS.length; i++)
			actionBars.setGlobalActionHandler(ACTIONS[i], getAction(editor, ACTIONS[i]));
		actionBars.setGlobalActionHandler(ITextEditorActionDefinitionIds.SHOW_WHITESPACE_CHARACTERS, getAction(editor, ITextEditorActionConstants.SHOW_WHITESPACE_CHARACTERS));
		actionBars.setGlobalActionHandler(ITextEditorActionDefinitionIds.BLOCK_SELECTION_MODE, getAction(editor, ITextEditorActionConstants.BLOCK_SELECTION_MODE));
		if (editor instanceof AbstractTextEditor && ((AbstractTextEditor)editor).isWordWrapSupported())
			actionBars.setGlobalActionHandler(ITextEditorActionDefinitionIds.WORD_WRAP, getAction(editor, ITextEditorActionConstants.WORD_WRAP));

		fFindNext.setAction(getAction(editor, ITextEditorActionConstants.FIND_NEXT));
		fFindPrevious.setAction(getAction(editor, ITextEditorActionConstants.FIND_PREVIOUS));
		fIncrementalFind.setAction(getAction(editor, ITextEditorActionConstants.FIND_INCREMENTAL));
		fIncrementalFindReverse.setAction(getAction(editor, ITextEditorActionConstants.FIND_INCREMENTAL_REVERSE));
		fGotoLine.setAction(getAction(editor, ITextEditorActionConstants.GOTO_LINE));
		fHippieCompletion.setAction(getAction(editor, ITextEditorActionConstants.HIPPIE_COMPLETION));

		for (int i= 0; i < STATUS_FIELD_DEFS.length; i++) {
			if (fActiveEditorPart instanceof ITextEditorExtension) {
				StatusLineContributionItem statusField= fStatusFields.get(STATUS_FIELD_DEFS[i]);
				statusField.setActionHandler(getAction(editor, STATUS_FIELD_DEFS[i].actionId));
				ITextEditorExtension extension= (ITextEditorExtension) fActiveEditorPart;
				extension.setStatusField(statusField, STATUS_FIELD_DEFS[i].category);
			}
		}
	}

	/**
	 * The <code>BasicTextEditorActionContributor</code> implementation of this
	 * <code>IEditorActionBarContributor</code> method installs the global
	 * action handler for the given text editor by calling a private helper
	 * method.
	 * <p>
	 * Subclasses may extend.</p>
	 *
	 * @param part {@inheritDoc}
	 */
	@Override
	public void setActiveEditor(IEditorPart part) {
		doSetActiveEditor(part);
	}

	@Override
	public void contributeToMenu(IMenuManager menu) {

		IMenuManager editMenu= menu.findMenuUsingPath(IWorkbenchActionConstants.M_EDIT);
		if (editMenu != null) {
			editMenu.prependToGroup(IWorkbenchActionConstants.FIND_EXT, fIncrementalFindReverse);
			editMenu.prependToGroup(IWorkbenchActionConstants.FIND_EXT, fIncrementalFind);
			editMenu.prependToGroup(IWorkbenchActionConstants.FIND_EXT, fFindPrevious);
			editMenu.prependToGroup(IWorkbenchActionConstants.FIND_EXT, fFindNext);

			addOrInsert(editMenu, new Separator(ITextEditorActionConstants.GROUP_OPEN));
			addOrInsert(editMenu, new Separator(ITextEditorActionConstants.GROUP_INFORMATION));
			addOrInsert(editMenu, new Separator(ITextEditorActionConstants.GROUP_ASSIST));
			addOrInsert(editMenu, new Separator(ITextEditorActionConstants.GROUP_GENERATE));
			addOrInsert(editMenu, new Separator(IWorkbenchActionConstants.MB_ADDITIONS));

			editMenu.appendToGroup(ITextEditorActionConstants.GROUP_ASSIST, fHippieCompletion);
		}

		IMenuManager navigateMenu= menu.findMenuUsingPath(IWorkbenchActionConstants.M_NAVIGATE);
		if (navigateMenu != null) {
			navigateMenu.appendToGroup(IWorkbenchActionConstants.MB_ADDITIONS, fGotoLine);
		}
	}

	/**
	 * The <code>item</code> is {@link IContributionManager#add(IContributionItem) added} to
	 * <code>menu</code> if no item with the same id currently exists. If there already is an
	 * contribution item with the same id, the new item gets
	 * {@link IContributionManager#insertAfter(String, IContributionItem) inserted after} it.
	 *
	 * @param menu the contribution manager
	 * @param item the contribution item
	 * @since 3.2
	 */
	private void addOrInsert(IContributionManager menu, IContributionItem item) {
		String id= item.getId();
		if (menu.find(id) == null)
			menu.add(item);
		else
			menu.insertAfter(id, item);
	}

	@Override
	public void contributeToStatusLine(IStatusLineManager statusLineManager) {
		super.contributeToStatusLine(statusLineManager);
		for (int i= 0; i < STATUS_FIELD_DEFS.length; i++)
			statusLineManager.add(fStatusFields.get(STATUS_FIELD_DEFS[i]));
	}

	@Override
	public void dispose() {
		doSetActiveEditor(null);
		super.dispose();
	}
}
