/*******************************************************************************
 * Copyright (c) 2005, 2008 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
 *******************************************************************************/
package org.eclipse.ui.keys;

import java.io.IOException;
import java.util.Collection;
import java.util.Map;

import org.eclipse.core.commands.ParameterizedCommand;
import org.eclipse.jface.bindings.Binding;
import org.eclipse.jface.bindings.IBindingManagerListener;
import org.eclipse.jface.bindings.Scheme;
import org.eclipse.jface.bindings.TriggerSequence;
import org.eclipse.ui.commands.ICommandService;
import org.eclipse.ui.services.IDisposable;

/**
 * <p>
 * Provides services related to the binding architecture (e.g., keyboard
 * shortcuts) within the workbench. This service can be used to access the
 * currently active bindings, as well as the current state of the binding
 * architecture.
 * </p>
 * <p>
 * This service can be acquired from your service locator:
 * <pre>
 * 	IBindingService service = (IBindingService) getSite().getService(IBindingService.class);
 * </pre>
 * <ul>
 * <li>This service is available globally.</li>
 * </ul>
 * </p>
 *
 * @noimplement This interface is not intended to be implemented by clients.
 * @noextend This interface is not intended to be extended by clients.
 *
 * @since 1.1
 */
public interface IBindingService extends IDisposable {

	/**
	 * The default default value for the active scheme id. This value can be
	 * overridden using the "plugin_customization.ini" file. The
	 * <code>BindingPersistence</code> code needs to know this value so it can
	 * try to decide if someone overrode the default.
	 */
	public static final String DEFAULT_DEFAULT_ACTIVE_SCHEME_ID = "org.eclipse.ui.defaultAcceleratorConfiguration"; //$NON-NLS-1$

	/**
	 * <p>
	 * Adds a listener to this binding service. The listener will be notified
	 * when the set of defined schemes or bindings changes. This can be used to
	 * track the global appearance and disappearance of bindings.
	 * </p>
	 * <p>
	 * This method completes in amortized constant time (<code>O(1)</code>).
	 * </p>
	 *
	 * @param listener
	 *            The listener to attach; must not be <code>null</code>.
	 *
	 * @since 3.5
	 */
	public void addBindingManagerListener(IBindingManagerListener listener);

	/**
	 * <p>
	 * Removes a listener from this binding service.
	 * </p>
	 * <p>
	 * This method completes in amortized <code>O(1)</code>.
	 * </p>
	 *
	 * @param listener
	 *            The listener to be removed; must not be <code>null</code>.
	 *
	 * @since 3.5
	 */
	public void removeBindingManagerListener(IBindingManagerListener listener);

	/**
	 * Gets the active bindings for a given parameterized command.
	 *
	 * @param parameterizedCommand
	 *            The fully-parameterized command for which the active bindings
	 *            should be found; must not be <code>null</code>.
	 * @return The array of all active bindings for the given command. This
	 *         collection may be empty, but it is never <code>null</code>.
	 */
	public TriggerSequence[] getActiveBindingsFor(
			ParameterizedCommand parameterizedCommand);

	/**
	 * Gets the active bindings for a given command identifier. It is assumed
	 * that the command has no parameters.
	 *
	 * @param commandId
	 *            The id of the command for which the active bindings should be
	 *            found; must not be <code>null</code>.
	 * @return The array of all active bindings for the given command. This
	 *         collection may be empty, but it is never <code>null</code>.
	 */
	public TriggerSequence[] getActiveBindingsFor(String commandId);

	/**
	 * Returns the currently active scheme.
	 *
	 * @return The currently active scheme. This value may (in certain rare
	 *         circumstances) be <code>null</code>.
	 */
	public Scheme getActiveScheme();

	/**
	 * Gets the best active binding for a command. The best binding is the one
	 * that would be most appropriate to show in a menu. Bindings which belong
	 * to a child scheme are given preference over those in a parent scheme.
	 * Bindings which belong to a particular locale or platform are given
	 * preference over those that do not. The rest of the calculation is based
	 * most on various concepts of "length", as well as giving some modifier
	 * keys preference (e.g., <code>Alt</code> is less likely to appear than
	 * <code>Ctrl</code>).
	 *
	 * @param command
	 *            The command for which the best active binding should be
	 *            retrieved; must not be <code>null</code>.
	 * @return The trigger sequence for the best binding; may be
	 *         <code>null</code> if no bindings are active for the given
	 *         command.
	 * @since 3.4
	 */
	public TriggerSequence getBestActiveBindingFor(ParameterizedCommand command);

	/**
	 * Gets the best active binding for a command. The best binding is the one
	 * that would be most appropriate to show in a menu. Bindings which belong
	 * to a child scheme are given preference over those in a parent scheme.
	 * Bindings which belong to a particular locale or platform are given
	 * preference over those that do not. The rest of the calculaton is based
	 * most on various concepts of "length", as well as giving some modifier
	 * keys preference (e.g., <code>Alt</code> is less likely to appear than
	 * <code>Ctrl</code>).
	 *
	 * @param commandId
	 *            The identifier of the command for which the best active
	 *            binding should be retrieved; must not be <code>null</code>.
	 * @return The trigger sequence for the best binding; may be
	 *         <code>null</code> if no bindings are active for the given
	 *         command.
	 * @since 3.2
	 * @see #getBestActiveBindingFor(ParameterizedCommand)
	 */
	public TriggerSequence getBestActiveBindingFor(String commandId);

	/**
	 * Gets the formatted string representing the best active binding for a
	 * command. The best binding is the one that would be most appropriate to
	 * show in a menu. Bindings which belong to a child scheme are given
	 * preference over those in a parent scheme. The rest of the calculaton is
	 * based most on various concepts of "length", as well as giving some
	 * modifier keys preference (e.g., <code>Alt</code> is less likely to
	 * appear than <code>Ctrl</code>).
	 *
	 * @param commandId
	 *            The identifier of the command for which the best active
	 *            binding should be retrieved; must not be <code>null</code>.
	 * @return The formatted string for the best binding; may be
	 *         <code>null</code> if no bindings are active for the given
	 *         command.
	 * @since 3.2
	 * @see #getBestActiveBindingFor(ParameterizedCommand)
	 */
	public String getBestActiveBindingFormattedFor(String commandId);

	/**
	 * Returns the current set of bindings.
	 *
	 * @return The current array of bindings (<code>Binding</code>).
	 */
	public Binding[] getBindings();

	/**
	 * Returns the current state of the key binding buffer. This will contain
	 * all of the keys currently awaiting processing. If the system is currently
	 * executing a command (as a result of a key press), then this will contain
	 * the trigger sequence used to execute the command. If the key binding
	 * architecture has seen part of multi-key binding, then this will contain
	 * the part that it has seen. Otherwise, this will return nothing.
	 *
	 * @return The trigger sequence indicating the current state of the key
	 *         binding buffer; never <code>null</code>, but may be empty if
	 *         there is nothing in the buffer.
	 * @since 3.2
	 */
	public TriggerSequence getBuffer();

	/**
	 * Returns the default scheme identifier for the currently running
	 * application.
	 *
	 * @return The default scheme identifier (<code>String</code>); never
	 *         <code>null</code>, but may be empty or point to an undefined
	 *         scheme.
	 */
	public String getDefaultSchemeId();

	/**
	 * Returns the array of defined schemes in the workbench.
	 *
	 * @return The array of schemes (<code>Scheme</code>) that are defined;
	 *         it may be <code>null</code>, and it may be empty.
	 */
	public Scheme[] getDefinedSchemes();

	/**
	 * Returns the currently active locale.
	 *
	 * @return The current locale.
	 */
	public String getLocale();

	/**
	 * Returns all of the possible bindings that start with the given trigger
	 * (but are not equal to the given trigger).
	 *
	 * @param trigger
	 *            The prefix to look for; must not be <code>null</code>.
	 * @return A map of triggers (<code>TriggerSequence</code>) to bindings (<code>Binding</code>).
	 *         This map may be empty, but it is never <code>null</code>.
	 */
	public Map getPartialMatches(TriggerSequence trigger);

	/**
	 * Returns the command identifier for the active binding matching this
	 * trigger, if any.
	 *
	 * @param trigger
	 *            The trigger to match; may be <code>null</code>.
	 * @return The binding that matches, if any; <code>null</code> otherwise.
	 */
	public Binding getPerfectMatch(TriggerSequence trigger);

	/**
	 * Returns the currently active platform.
	 *
	 * @return The current platform.
	 */
	public String getPlatform();

	/**
	 * Retrieves the scheme with the given identifier. If no such scheme exists,
	 * then an undefined scheme with the given id is created.
	 *
	 * @param schemeId
	 *            The identifier to find; must not be <code>null</code>.
	 * @return A scheme with the given identifier, either defined or undefined.
	 */
	public Scheme getScheme(String schemeId);

	/**
	 * Tests whether the global key binding architecture is currently active.
	 *
	 * @return <code>true</code> if the key bindings are active;
	 *         <code>false</code> otherwise.
	 */
	public boolean isKeyFilterEnabled();

	/**
	 * Returns whether the given trigger sequence is a partial match for the
	 * given sequence.
	 *
	 * @param trigger
	 *            The sequence which should be the prefix for some binding;
	 *            should not be <code>null</code>.
	 * @return <code>true</code> if the trigger can be found in the active
	 *         bindings; <code>false</code> otherwise.
	 */
	public boolean isPartialMatch(TriggerSequence trigger);

	/**
	 * Returns whether the given trigger sequence is a perfect match for the
	 * given sequence.
	 *
	 * @param trigger
	 *            The sequence which should match exactly; should not be
	 *            <code>null</code>.
	 * @return <code>true</code> if the trigger can be found in the active
	 *         bindings; <code>false</code> otherwise.
	 */
	public boolean isPerfectMatch(TriggerSequence trigger);

	/**
	 * Opens the key assistant dialog positioned near the key binding entry in
	 * the status bar.
	 */
	public void openKeyAssistDialog();

	/**
	 * <p>
	 * Reads the binding information from the registry and the preferences. This
	 * will overwrite any of the existing information in the binding service.
	 * This method is intended to be called during start-up. When this method
	 * completes, this binding service will reflect the current state of the
	 * registry and preference store.
	 * </p>
	 *
	 * @param commandService
	 *            Ignored.
	 */
	public void readRegistryAndPreferences(ICommandService commandService);

	/**
	 * <p>
	 * Writes the given active scheme and bindings to the preference store. Only
	 * the bindings that are of the <code>Binding.USER</code> type will be
	 * written; the others will be ignored. This should only be used by
	 * applications trying to persist user preferences. If you are trying to
	 * change the active scheme as an RCP application, then you should be using
	 * the <code>plugin_customization.ini</code> file. If you are trying to
	 * switch between groups of bindings dynamically, you should be using
	 * contexts.
	 * </p>
	 * <p>
	 * This method also updates the active scheme and bindings in the system to
	 * match those written to the preference store.
	 * </p>
	 *
	 * @param activeScheme
	 *            The scheme which should be persisted; may be <code>null</code>.
	 * @param bindings
	 *            The bindings which should be persisted; may be
	 *            <code>null</code>.
	 * @throws IOException
	 *             If something goes wrong while writing to the preference
	 *             store.
	 * @see org.eclipse.ui.IWorkbenchPreferenceConstants
	 * @see org.eclipse.ui.contexts.IContextService
	 */
	public void savePreferences(Scheme activeScheme, Binding[] bindings)
			throws IOException;

	/**
	 * <p>
	 * Enables or disables the global key binding architecture. The architecture
	 * should be enabled by default.
	 * </p>
	 * <p>
	 * When enabled, keyboard shortcuts are active, and that key events can
	 * trigger commands. This also means that widgets may not see all key events
	 * (as they might be trapped as a keyboard shortcut).
	 * </p>
	 * <p>
	 * When disabled, no key events will trapped as keyboard shortcuts, and that
	 * no commands can be triggered by keyboard events. (Exception: it is
	 * possible that someone listening for key events on a widget could trigger
	 * a command.)
	 * </p>
	 *
	 * @param enabled
	 *            Whether the key filter should be enabled.
	 */
	public void setKeyFilterEnabled(boolean enabled);

	/**
	 * Provides the current conflicts in the keybindings for the given
	 * TriggerSequence as a {@link Collection} of {@link Binding}
	 *
	 * @param sequence The sequence for which conflict info is required
	 *
	 * @return Collection of Bindings. If no conflicts,
	 *         then returns a <code>null</code>
	 * @since 3.5
	 */
	public Collection getConflictsFor(TriggerSequence sequence);
}
