/*******************************************************************************
 * Copyright (c) 2004, 2009 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.internal.keys;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import org.eclipse.core.commands.Command;
import org.eclipse.core.commands.ParameterizedCommand;
import org.eclipse.core.commands.common.CommandException;
import org.eclipse.core.commands.common.NotDefinedException;
import org.eclipse.e4.ui.bindings.keys.KeyBindingDispatcher;
import org.eclipse.jface.bindings.Binding;
import org.eclipse.jface.bindings.TriggerSequence;
import org.eclipse.jface.bindings.keys.KeySequence;
import org.eclipse.jface.bindings.keys.KeyStroke;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.PopupDialog;
import org.eclipse.jface.preference.PreferenceDialog;
import org.eclipse.jface.window.Window;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchCommandConstants;
import org.eclipse.ui.activities.IActivityManager;
import org.eclipse.ui.commands.ICommandService;
import org.eclipse.ui.contexts.IContextService;
import org.eclipse.ui.dialogs.PreferencesUtil;
import org.eclipse.ui.internal.WorkbenchPlugin;
import org.eclipse.ui.keys.IBindingService;

/**
 * <p>
 * A dialog displaying a list of key bindings. The dialog will execute a command
 * if it is selected.
 * </p>
 * <p>
 * The methods on this class are not thread-safe and must be run from the UI
 * thread.
 * </p>
 * 
 * @since 3.1
 */
final class KeyAssistDialog extends PopupDialog {

	/**
	 * The data key for the binding stored on an SWT widget. The key is a
	 * fully-qualified name, but in reverse order. This is so that the equals
	 * method will detect misses faster.
	 */
	private static final String BINDING_KEY = "Binding.bindings.jface.eclipse.org"; //$NON-NLS-1$

	/**
	 * The value of <code>previousWidth</code> to set if there is no
	 * remembered width.
	 */
	private static final int NO_REMEMBERED_WIDTH = -1;

	/**
	 * The activity manager for the associated workbench.
	 */
	private final IActivityManager activityManager;

	/**
	 * The binding service for the associated workbench.
	 */
	private final IBindingService bindingService;

	/**
	 * The binding that was selected when the key assist dialog last closed.
	 * This is only remembered until <code>clearRememberedState()</code> is
	 * called.
	 */
	private Binding binding = null;

	/**
	 * The ordered list of command identifiers corresponding to the table.
	 */
	private final List bindings = new ArrayList();

	/**
	 * The command service for the associated workbench.
	 */
	private final ICommandService commandService;

	/**
	 * The table containing of the possible completions. This value is
	 * <code>null</code> until the dialog is created.
	 */
	private Table completionsTable = null;

	/**
	 * Whether this dialog is currently holding some remembered state.
	 */
	private boolean hasRememberedState = false;

	/**
	 * The key binding state for the associated workbench.
	 */
	private final KeyBindingState keyBindingState;

	/**
	 * The width of the shell when it was previously open. This is only
	 * remembered until <code>clearRememberedState()</code> is called.
	 */
	private int previousWidth = NO_REMEMBERED_WIDTH;

	/**
	 * The key binding listener for the associated workbench.
	 */
	private final KeyBindingDispatcher workbenchKeyboard;

	/**
	 * A sorted map of conflicts to be used when the dialog pops up.
	 * 
	 * @since 3.3
	 */
	private SortedMap conflictMatches;

	/**
	 * Constructs a new instance of <code>KeyAssistDialog</code>. When the
	 * dialog is first constructed, it contains no widgets. The dialog is first
	 * created with no parent. If a parent is required, call
	 * <code>setParentShell()</code>. Also, between uses, it might be
	 * necessary to call <code>setParentShell()</code> as well.
	 * 
	 * @param workbench
	 *            The workbench in which this dialog is created; must not be
	 *            <code>null</code>.
	 * @param associatedKeyboard
	 *            The key binding listener for the workbench; must not be
	 *            <code>null</code>.
	 * @param associatedState
	 *            The key binding state associated with the workbench; must not
	 *            be <code>null</code>.
	 */
	KeyAssistDialog(final IWorkbench workbench,
 final KeyBindingDispatcher associatedKeyboard,
			final KeyBindingState associatedState) {
		super((Shell) null, PopupDialog.INFOPOPUP_SHELLSTYLE, true, false,
				false, false, null, null);

		this.activityManager = workbench.getActivitySupport()
				.getActivityManager();
		this.bindingService = (IBindingService) workbench
				.getService(IBindingService.class);
		this.commandService = (ICommandService) workbench
				.getService(ICommandService.class);
		this.keyBindingState = associatedState;
		this.workbenchKeyboard = associatedKeyboard;

		this.setInfoText(getKeySequenceString());
	}

	/**
	 * Clears out the remembered state of the key assist dialog. This includes
	 * its width, as well as the selected binding.
	 */
	final void clearRememberedState() {
		previousWidth = NO_REMEMBERED_WIDTH;
		binding = null;
		hasRememberedState = false;
	}

	/**
	 * Closes this shell, but first remembers some state of the dialog. This way
	 * it will have a response if asked to open the dialog again or if asked to
	 * open the keys preference page. This does not remember the internal state.
	 * 
	 * @return Whether the shell was already closed.
	 */
	public final boolean close() {
		return close(false);
	}

	/**
	 * Closes this shell, but first remembers some state of the dialog. This way
	 * it will have a response if asked to open the dialog again or if asked to
	 * open the keys preference page.
	 * 
	 * @param rememberState
	 *            Whether the internal state should be remembered.
	 * @return Whether the shell was already closed.
	 */
	public final boolean close(final boolean rememberState) {
		return close(rememberState, true);
	}

	/**
	 * Closes this shell, but first remembers some state of the dialog. This way
	 * it will have a response if asked to open the dialog again or if asked to
	 * open the keys preference page.
	 * 
	 * @param rememberState
	 *            Whether the internal state should be remembered.
	 * @param resetState
	 *            Whether the state should be reset.
	 * @return Whether the shell was already closed.
	 */
	private final boolean close(final boolean rememberState,
			final boolean resetState) {
		final Shell shell = getShell();
		if (rememberState) {
			// Remember the previous width.
			final int widthToRemember;
			if ((shell != null) && (!shell.isDisposed())) {
				widthToRemember = getShell().getSize().x;
			} else {
				widthToRemember = NO_REMEMBERED_WIDTH;
			}

			// Remember the selected command name and key sequence.
			final Binding bindingToRemember;
			if ((completionsTable != null) && (!completionsTable.isDisposed())) {
				final int selectedIndex = completionsTable.getSelectionIndex();
				if (selectedIndex != -1) {
					final TableItem selectedItem = completionsTable
							.getItem(selectedIndex);
					bindingToRemember = (Binding) selectedItem
							.getData(BINDING_KEY);
				} else {
					bindingToRemember = null;
				}
			} else {
				bindingToRemember = null;
			}

			rememberState(widthToRemember, bindingToRemember);
			completionsTable = null;
		}

		if (resetState) {
			keyBindingState.reset();
		}
		return super.close();
	}

	/**
	 * Sets the position for the dialog based on the position of the workbench
	 * window. The dialog is flush with the bottom right corner of the workbench
	 * window. However, the dialog will not appear outside of the display's
	 * client area.
	 * 
	 * @param size
	 *            The final size of the dialog; must not be <code>null</code>.
	 */
	private final void configureLocation(final Point size) {
		final Shell shell = getShell();

		final Shell workbenchWindowShell = keyBindingState
				.getAssociatedWindow().getShell();
		final int xCoord;
		final int yCoord;
		if (workbenchWindowShell != null) {
			/*
			 * Position the shell at the bottom right corner of the workbench
			 * window
			 */
			final Rectangle workbenchWindowBounds = workbenchWindowShell
					.getBounds();
			xCoord = workbenchWindowBounds.x + workbenchWindowBounds.width
					- size.x - 10;
			yCoord = workbenchWindowBounds.y + workbenchWindowBounds.height
					- size.y - 10;

		} else {
			xCoord = 0;
			yCoord = 0;

		}
		final Rectangle bounds = new Rectangle(xCoord, yCoord, size.x, size.y);
		shell.setBounds(getConstrainedShellBounds(bounds));
	}

	/**
	 * Sets the size for the dialog based on its previous size. The width of the
	 * dialog is its previous width, if it exists. Otherwise, it is simply the
	 * packed width of the dialog. The maximum width is 40% of the workbench
	 * window's width. The dialog's height is the packed height of the dialog to
	 * a maximum of half the height of the workbench window.
	 * 
	 * @return The size of the dialog
	 */
	private final Point configureSize() {
		final Shell shell = getShell();

		// Get the packed size of the shell.
		shell.pack();
		final Point size = shell.getSize();

		// Use the previous width if appropriate.
		if ((previousWidth != NO_REMEMBERED_WIDTH) && (previousWidth > size.x)) {
			size.x = previousWidth;
		}

		// Enforce maximum sizing.
		final Shell workbenchWindowShell = keyBindingState
				.getAssociatedWindow().getShell();
		if (workbenchWindowShell != null) {
			final Point workbenchWindowSize = workbenchWindowShell.getSize();
			final int maxWidth = workbenchWindowSize.x * 2 / 5;
			final int maxHeight = workbenchWindowSize.y / 2;
			if (size.x > maxWidth) {
				size.x = maxWidth;
			}
			if (size.y > maxHeight) {
				size.y = maxHeight;
			}
		}

		// Set the size for the shell.
		shell.setSize(size);
		return size;
	}

	/**
	 * Returns a string representing the key sequence used to open this dialog.
	 * 
	 * @return the string describing the key sequence, or <code>null</code> if
	 *         it cannot be determined.
	 */
	private String getKeySequenceString() {
		final Command command = commandService
				.getCommand(IWorkbenchCommandConstants.WINDOW_SHOW_KEY_ASSIST);
		final TriggerSequence[] keyBindings = bindingService
				.getActiveBindingsFor(new ParameterizedCommand(command, null));
		final int keyBindingsCount = keyBindings.length;
		final KeySequence currentState = keyBindingState.getCurrentSequence();
		final int prefixSize = currentState.getKeyStrokes().length;

		// Try to find the first possible matching key binding.
		KeySequence keySequence = null;
		for (int i = 0; i < keyBindingsCount; i++) {
			keySequence = (KeySequence) keyBindings[i];

			// Now just double-check to make sure the key is still possible.
			if (prefixSize > 0) {
				if (keySequence.startsWith(currentState, false)) {
					/*
					 * Okay, so we have a partial match. Replace the key binding
					 * with the required suffix completion.
					 */
					final KeyStroke[] oldKeyStrokes = keySequence
							.getKeyStrokes();
					final int newSize = oldKeyStrokes.length - prefixSize;
					final KeyStroke[] newKeyStrokes = new KeyStroke[newSize];
					System.arraycopy(oldKeyStrokes, prefixSize, newKeyStrokes,
							0, newSize);
					keySequence = KeySequence.getInstance(newKeyStrokes);
					break;
				}

				/*
				 * The prefix doesn't match, so null out the key binding and try
				 * again.
				 */
				keySequence = null;
				continue;

			}

			// There is no prefix, so just grab the first.
			break;
		}
		if (keySequence == null) {
			return null; // couldn't find a suitable key binding
		}

		return NLS.bind(KeyAssistMessages.openPreferencePage, keySequence
				.format());
	}

	/**
	 * Creates the content area for the key assistant. This creates a table and
	 * places it inside the composite. The composite will contain a list of all
	 * the key bindings.
	 * 
	 * @param parent
	 *            The parent composite to contain the dialog area; must not be
	 *            <code>null</code>.
	 */
	protected final Control createDialogArea(final Composite parent) {
		// First, register the shell type with the context support
		registerShellType();

		// Create a composite for the dialog area.
		final Composite composite = new Composite(parent, SWT.NONE);
		final GridLayout compositeLayout = new GridLayout();
		compositeLayout.marginHeight = 0;
		compositeLayout.marginWidth = 0;
		composite.setLayout(compositeLayout);
		composite.setLayoutData(new GridData(GridData.FILL_BOTH));
		composite.setBackground(parent.getBackground());

		// Layout the partial matches.
		final SortedMap partialMatches;
		if (conflictMatches != null) {
			partialMatches = conflictMatches;
			conflictMatches = null;
		} else {
			partialMatches = getPartialMatches();
		}

		if (partialMatches.isEmpty()) {
			createEmptyDialogArea(composite);
		} else {
			createTableDialogArea(composite, partialMatches);
		}
		return composite;
	}

	/**
	 * Creates an empty dialog area with a simple message saying there were no
	 * matches. This is used if no partial matches could be found. This should
	 * not really ever happen, but might be possible if the commands are
	 * changing while waiting for this dialog to open.
	 * 
	 * @param parent
	 *            The parent composite for the dialog area; must not be
	 *            <code>null</code>.
	 */
	private final void createEmptyDialogArea(final Composite parent) {
		final Label noMatchesLabel = new Label(parent, SWT.NULL);
		noMatchesLabel.setText(KeyAssistMessages.NoMatches_Message);
		noMatchesLabel.setLayoutData(new GridData(GridData.FILL_BOTH));
		noMatchesLabel.setBackground(parent.getBackground());
	}

	/**
	 * Creates a dialog area with a table of the partial matches for the current
	 * key binding state. The table will be either the minimum width, or
	 * <code>previousWidth</code> if it is not
	 * <code>NO_REMEMBERED_WIDTH</code>.
	 * 
	 * @param parent
	 *            The parent composite for the dialog area; must not be
	 *            <code>null</code>.
	 * @param partialMatches
	 *            The lexicographically sorted map of partial matches for the
	 *            current state; must not be <code>null</code> or empty.
	 */
	private final void createTableDialogArea(final Composite parent,
			final SortedMap partialMatches) {
		// Layout the table.
		completionsTable = new Table(parent, SWT.FULL_SELECTION | SWT.SINGLE);
		final GridData gridData = new GridData(GridData.FILL_BOTH);
		completionsTable.setLayoutData(gridData);
		completionsTable.setBackground(parent.getBackground());
		completionsTable.setLinesVisible(true);

		// Initialize the columns and rows.
		bindings.clear();
		final TableColumn columnCommandName = new TableColumn(completionsTable,
				SWT.LEFT, 0);
		final TableColumn columnKeySequence = new TableColumn(completionsTable,
				SWT.LEFT, 1);
		final Iterator itemsItr = partialMatches.entrySet().iterator();
		while (itemsItr.hasNext()) {
			final Map.Entry entry = (Map.Entry) itemsItr.next();
			final String sequence = (String) entry.getValue();
			final Binding binding = (Binding) entry.getKey();
			final ParameterizedCommand command = binding
					.getParameterizedCommand();
			try {
				final String[] text = { command.getName(), sequence };
				final TableItem item = new TableItem(completionsTable, SWT.NULL);
				item.setText(text);
				item.setData(BINDING_KEY, binding);
				bindings.add(binding);
			} catch (NotDefinedException e) {
				// Not much to do, but this shouldn't really happen.
			}
		}

		Dialog.applyDialogFont(parent);
		columnKeySequence.pack();
		if (previousWidth != NO_REMEMBERED_WIDTH) {
			columnKeySequence.setWidth(previousWidth);
		}
		columnCommandName.pack();
		if (completionsTable.getItems().length > 0) {
			completionsTable.setSelection(0);
		}

		/*
		 * If you double-click on the table, it should execute the selected
		 * command.
		 */
		completionsTable.addListener(SWT.DefaultSelection, new Listener() {
			public final void handleEvent(final Event event) {
				executeKeyBinding(event);
			}
		});
	}

	/**
	 * Edits the remembered selection in the preference dialog.
	 */
	private final void editKeyBinding() {
		// Create a preference dialog on the keys preference page.
		final String keysPageId = "org.eclipse.ui.preferencePages.Keys"; //$NON-NLS-1$
		final PreferenceDialog dialog = PreferencesUtil
				.createPreferenceDialogOn(getShell(), keysPageId, null, binding);

		/*
		 * Forget the remembered state (so we don't get stuck editing
		 * preferences).
		 */
		clearRememberedState();

		// Open the dialog (blocking).
		dialog.open();
	}

	/**
	 * Handles the default selection event on the table of possible completions.
	 * This attempts to execute the given command.
	 */
	private final void executeKeyBinding(final Event trigger) {
		// Try to execute the corresponding command.
		final int selectionIndex = completionsTable.getSelectionIndex();
		if (selectionIndex >= 0) {
			final Binding binding = (Binding) bindings.get(selectionIndex);
			try {
				// workbenchKeyboard.updateShellKludge(null);
				workbenchKeyboard.executeCommand(binding.getParameterizedCommand(), trigger);
			} catch (final CommandException e) {
				WorkbenchPlugin.log(binding.getParameterizedCommand().toString(), e);
			}
		}
	}

	/**
	 * Gets the list of key bindings that are partial matches to the current key
	 * binding state.
	 * 
	 * @return A sorted map of key sequences (KeySequence) to command identifier
	 *         (String) representing the list of enabled commands that could
	 *         possibly complete the current key sequence.
	 */
	private final SortedMap getPartialMatches() {
		// Put all partial matches into the matches into the map.
		final Map partialMatches = bindingService
				.getPartialMatches(keyBindingState.getCurrentSequence());

		// Create a sorted map that sorts based on lexicographical order.
		final SortedMap sortedMatches = new TreeMap(new Comparator() {
			public final int compare(final Object a, final Object b) {
				final Binding bindingA = (Binding) a;
				final Binding bindingB = (Binding) b;
				final ParameterizedCommand commandA = bindingA
						.getParameterizedCommand();
				final ParameterizedCommand commandB = bindingB
						.getParameterizedCommand();
				try {
					return commandA.getName().compareTo(commandB.getName());
				} catch (final NotDefinedException e) {
					// should not happen
					return 0;
				}
			}
		});

		/*
		 * Remove those partial matches for which either the command is not
		 * identified or the activity manager believes the command is not
		 * enabled.
		 */
		final Iterator partialMatchItr = partialMatches.entrySet().iterator();
		while (partialMatchItr.hasNext()) {
			final Map.Entry entry = (Map.Entry) partialMatchItr.next();
			final Binding binding = (Binding) entry.getValue();
			final Command command = binding.getParameterizedCommand()
					.getCommand();
			if (command.isDefined()
					&& activityManager.getIdentifier(command.getId())
							.isEnabled()) {
				TriggerSequence bestActiveBindingFor = bindingService.getBestActiveBindingFor(binding.getParameterizedCommand());
				sortedMatches.put(binding, bestActiveBindingFor==null?null:bestActiveBindingFor.format());
			}
		}

		return sortedMatches;

	}

	/**
	 * Returns whether the dialog is currently holding some remembered state.
	 * 
	 * @return <code>true</code> if the dialog has remembered state;
	 *         <code>false</code> otherwise.
	 */
	private final boolean hasRememberedState() {
		return hasRememberedState;
	}

	/**
	 * Opens this dialog. This method can be called multiple times on the same
	 * dialog. This only opens the dialog if there is no remembered state; if
	 * there is remembered state, then it tries to open the preference page
	 * instead.
	 * 
	 * @return The return code from this dialog.
	 */
	public final int open() {
		// If there is remember state, open the preference page.
		if (hasRememberedState()) {
			editKeyBinding();
			clearRememberedState();
			return Window.OK;
		}

		// If the dialog is already open, dispose the shell and recreate it.
		final Shell shell = getShell();
		if (shell != null) {
			close(false, false);
		}
		create();

		// Configure the size and location.
		final Point size = configureSize();
		configureLocation(size);

		// Call the super method.
		return super.open();
	}

	/**
	 * Opens this dialog with the list of bindings for the user to select from.
	 * 
	 * @return The return code from this dialog.
	 * @since 3.3
	 */
	public final int open(Collection bindings) {
		conflictMatches = new TreeMap(new Comparator() {
			public final int compare(final Object a, final Object b) {
				final Binding bindingA = (Binding) a;
				final Binding bindingB = (Binding) b;
				final ParameterizedCommand commandA = bindingA
						.getParameterizedCommand();
				final ParameterizedCommand commandB = bindingB
						.getParameterizedCommand();
				try {
					return commandA.getName().compareTo(commandB.getName());
				} catch (final NotDefinedException e) {
					// should not happen
					return 0;
				}
			}
		});
		Iterator i = bindings.iterator();
		while (i.hasNext()) {
			Binding b = (Binding) i.next();
			TriggerSequence bestActiveBindingFor = bindingService.getBestActiveBindingFor(b.getParameterizedCommand());
			conflictMatches.put(b, bestActiveBindingFor==null?null:bestActiveBindingFor.format());
		}

		// If the dialog is already open, dispose the shell and recreate it.
		final Shell shell = getShell();
		if (shell != null) {
			close(false, false);
		}
		create();

		// Configure the size and location.
		final Point size = configureSize();
		configureLocation(size);

		// Call the super method.
		return super.open();
	}

	/**
	 * Registers the shell as the same type as its parent with the context
	 * support. This ensures that it does not modify the current state of the
	 * application.
	 */
	private final void registerShellType() {
		final Shell shell = getShell();
		final IContextService contextService = (IContextService) keyBindingState
				.getAssociatedWindow().getWorkbench().getService(
						IContextService.class);
		contextService.registerShell(shell, contextService
				.getShellType((Shell) shell.getParent()));
	}

	/**
	 * Remembers the current state of this dialog.
	 * 
	 * @param previousWidth
	 *            The previous width of the dialog.
	 * @param binding
	 *            The binding to remember, may be <code>null</code> if none.
	 */
	private final void rememberState(final int previousWidth,
			final Binding binding) {
		this.previousWidth = previousWidth;
		this.binding = binding;
		hasRememberedState = true;
	}

	/**
	 * Exposing this within the keys package.
	 * 
	 * @param newParentShell
	 *            The new parent shell; this value may be <code>null</code> if
	 *            there is to be no parent.
	 */
	protected final void setParentShell(final Shell newParentShell) {
		super.setParentShell(newParentShell);
	}
}
