/*******************************************************************************
 * Copyright (c) 2000, 2015 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
 *     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:
 * <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>
 * </p>
 * @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();
	}
}
