/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.ui.internal;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.jface.action.IAction;
import org.eclipse.ui.IKeyBindingService;
import org.eclipse.ui.INestableKeyBindingService;
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.IWorkbenchSite;
import org.eclipse.ui.commands.ActionHandler;
import org.eclipse.ui.commands.HandlerSubmission;
import org.eclipse.ui.commands.IHandler;
import org.eclipse.ui.commands.Priority;
import org.eclipse.ui.contexts.EnabledSubmission;

/**
 * This service provides a nestable implementation of a key binding service.
 * This class is provided for backwards compatibility only, and might be removed
 * in the future. All of the functionality is the class can be duplicated by
 * using the commands and contexts API.
 * 
 * @since 2.0
 */
final class KeyBindingService implements INestableKeyBindingService {

    /**
     * The currently active nested service, if any. If there are no nested
     * services or none of them are active, then this value is <code>null</code>.
     */
    private IKeyBindingService activeService = null;

    /**
     * Whether this key binding service has been disposed.  A disposed key
     * binding service should not be used again.
     */
    private boolean disposed;

    /**
     * The set of context identifiers enabled in this key binding service (not
     * counting any nested services). This set may be empty, but it is never
     * <code>null</code>.
     */
    private Set enabledContextIds = Collections.EMPTY_SET;

    /**
     * The list of context submissions indicating the enabled state of the
     * context. This does not include those from nested services. This list may
     * be empty, but it is never <code>null</code>.
     */
    private List enabledSubmissions = new ArrayList();

    /**
     * The map of handler submissions, sorted by command identifiers. This does
     * not include those from nested services. This map may be empty, but it is
     * never <code>null</code>.
     */
    private Map handlerSubmissionsByCommandId = new HashMap();

    /**
     * The context submissions from the currently active nested service. This
     * value is <code>null</code> if there is no currently active nested
     * service.
     */
    private List nestedEnabledSubmissions = null;

    /**
     * The handler submissions from the currently active nested service. This
     * value is <code>null</code> if there is no currently active handler
     * service.
     */
    private List nestedHandlerSubmissions = null;

    /**
     * The map of workbench part sites to nested key binding services. This map
     * may be empty, but is never <code>null</code>.
     */
    private final Map nestedServices = new HashMap();

    /**
     * The parent for this key binding service; <code>null</code> if there is
     * no parent. If there is a parent, then this means that it should not do a
     * "live" update of its contexts or handlers, but should make a call to the
     * parent instead.
     */
    private final KeyBindingService parent;

    /**
     * The site within the workbench at which this service is provided. This
     * value should not be <code>null</code>.
     */
    private IWorkbenchPartSite workbenchPartSite;

    /**
     * Constructs a new instance of <code>KeyBindingService</code> on a given
     * workbench site. This instance is not nested.
     * 
     * @param workbenchPartSite
     *            The site for which this service will be responsible; should
     *            not be <code>null</code>.
     */
    KeyBindingService(IWorkbenchPartSite workbenchPartSite) {
        this(workbenchPartSite, null);
    }

    /**
     * Constructs a new instance of <code>KeyBindingService</code> on a given
     * workbench site.
     * 
     * @param workbenchPartSite
     *            The site for which this service will be responsible; should
     *            not be <code>null</code>.
     * @param parent
     *            The parent key binding service, if any; <code>null</code> if
     *            none.
     */
    KeyBindingService(IWorkbenchPartSite workbenchPartSite,
            KeyBindingService parent) {
        this.workbenchPartSite = workbenchPartSite;
        this.parent = parent;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.INestableKeyBindingService#activateKeyBindingService(org.eclipse.ui.IWorkbenchSite)
     */
    public boolean activateKeyBindingService(IWorkbenchSite nestedSite) {
        if (disposed) return false;

        // Check if we should do a deactivation.
        if (nestedSite == null) {
            // We should do a deactivation, if there is one active.
            if (activeService == null) {
                // There is no active service. Do no work.
                return false;
            } else {
                // Deactivate the currently active nested service.
                deactivateNestedService();
                return true;
            }
        }

        // Attempt to activate a service.
        final IKeyBindingService service = (IKeyBindingService) nestedServices
                .get(nestedSite);
        if (service == null) { return false; }

        if (service == activeService) {
        // The service is already active.
        return false; }

        deactivateNestedService();
        activateNestedService(service);
        return true;
    }

    /**
     * Activates the given service without worrying about the currently active
     * service. This goes through the work of adding all of the nested context
     * ids as enabled submissions.
     * 
     * @param service
     *            The service to become active; if <code>null</code>, then
     *            the reference to the active service is set to
     *            <code>null</code> but nothing else happens.
     */
    private final void activateNestedService(final IKeyBindingService service) {
        if (disposed) return;

        /*
         * If I have a parent, and I'm the active service, then deactivate so
         * that I can make changes.
         */
        boolean active = false;
        boolean haveParent = (parent != null);
        if (haveParent) {
            active = (parent.activeService == this);
            if (active) {
                parent.deactivateNestedService();
            }
        }

        // Update the active service.
        activeService = service;

        // Check to see that the service isn't null.
        if (service == null) { return; }

        if (haveParent) {
            if (active) {
                parent.activateNestedService(this);
            }

        } else if (activeService instanceof KeyBindingService) {
            // I have no parent, so I can make the changes myself.
            final KeyBindingService nestedService = (KeyBindingService) activeService;

            // Update the contexts.
            nestedEnabledSubmissions = nestedService.getEnabledSubmissions();
            normalizeSites(nestedEnabledSubmissions);
            Workbench.getInstance().getContextSupport().addEnabledSubmissions(
                    nestedEnabledSubmissions);

            // Update the handlers.
            nestedHandlerSubmissions = nestedService.getHandlerSubmissions();
            normalizeSites(nestedHandlerSubmissions);
            Workbench.getInstance().getCommandSupport().addHandlerSubmissions(
                    nestedHandlerSubmissions);
        }
    }

    /**
     * Deactives the currently active service. This nulls out the reference, and
     * removes all the enabled submissions for the nested service.
     */
    private final void deactivateNestedService() {
        if (disposed) return;

        // Don't do anything if there is no active service.
        if (activeService == null) { return; }

        // Check to see if there is a parent.
        boolean active = false;
        if (parent != null) {
            // Check if I'm the active service.
            if (parent.activeService == this) {
                active = true;
                // Deactivate myself so I can make changes.
                parent.deactivateNestedService();
            }

        } else if (activeService instanceof KeyBindingService) {
            // Remove all the nested context ids.
            Workbench.getInstance().getContextSupport()
                    .removeEnabledSubmissions(nestedEnabledSubmissions);

            /*
             * Remove all of the nested handler submissions. The handlers here
             * weren't created by this instance (but by the nest instance), and
             * hence can't be disposed here.
             */ 
            Workbench.getInstance().getCommandSupport()
                    .removeHandlerSubmissions(nestedHandlerSubmissions);

        }

        // Clear our reference to the active service.
        activeService = null;

        // If necessary, let my parent know that changes have occurred.
        if (active) {
            parent.activateNestedService(this);
        }
    }

    /**
     * Disposes this key binding service. This clears out all of the submissions
     * held by this service, and its nested services.
     */
    public void dispose() {
        if (!disposed) {
            deactivateNestedService();
            disposed = true;

            Workbench
                    .getInstance()
                    .getContextSupport()
                    .removeEnabledSubmissions(new ArrayList(enabledSubmissions));
            enabledSubmissions.clear();
            
            /*
             * Each removed handler submission, must dispose its corresponding
             * handler -- as these handlers only exist inside of this class.
             */
            final List submissions = new ArrayList(
                    handlerSubmissionsByCommandId.values());
            final Iterator submissionItr = submissions.iterator();
            while (submissionItr.hasNext()) {
                ((HandlerSubmission) submissionItr.next()).getHandler()
                        .dispose();
            }
            Workbench.getInstance().getCommandSupport()
                    .removeHandlerSubmissions(submissions);
            handlerSubmissionsByCommandId.clear();

            for (Iterator iterator = nestedServices.values().iterator(); iterator
                    .hasNext();) {
                KeyBindingService keyBindingService = (KeyBindingService) iterator
                        .next();
                keyBindingService.dispose();
            }

            nestedEnabledSubmissions = null;
            nestedHandlerSubmissions = null;
            nestedServices.clear();
        }
    }

    /**
     * Gets a copy of all the enabled submissions in the nesting chain.
     * 
     * @return All of the nested enabled submissions -- including the ones from
     *         this service. This list may be empty, but is never
     *         <code>null</code>.
     */
    private final List getEnabledSubmissions() {
        if (disposed) return null;

        final List submissions = new ArrayList(enabledSubmissions);
        if (activeService instanceof KeyBindingService) {
            final KeyBindingService nestedService = (KeyBindingService) activeService;
            submissions.addAll(nestedService.getEnabledSubmissions());
        }
        return submissions;
    }

    /**
     * Gets a copy of all the handler submissions in the nesting chain.
     * 
     * @return All of the nested handler submissions -- including the ones from
     *         this service. This list may be empty, but is never
     *         <code>null</code>.
     */
    private final List getHandlerSubmissions() {
        if (disposed) return null;

        final List submissions = new ArrayList(handlerSubmissionsByCommandId
                .values());
        if (activeService instanceof KeyBindingService) {
            final KeyBindingService nestedService = (KeyBindingService) activeService;
            submissions.addAll(nestedService.getHandlerSubmissions());
        }
        return submissions;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.INestableKeyBindingService#getKeyBindingService(org.eclipse.ui.IWorkbenchSite)
     */
    public IKeyBindingService getKeyBindingService(IWorkbenchSite nestedSite) {
        if (disposed) return null;

        if (nestedSite == null) { return null; }

        IKeyBindingService service = (IKeyBindingService) nestedServices
                .get(nestedSite);
        if (service == null) {
            // TODO the INestedKeyBindingService API should be based on
            // IWorkbenchPartSite..
            if (nestedSite instanceof IWorkbenchPartSite)
                service = new KeyBindingService(
                        (IWorkbenchPartSite) nestedSite, this);
            else
                service = new KeyBindingService(null, this);

            nestedServices.put(nestedSite, service);
        }

        return service;
    }

    public String[] getScopes() {
        if (disposed) return null;

        // Get the nested scopes, if any.
        final String[] nestedScopes;
        if (activeService == null) {
            nestedScopes = null;
        } else {
            nestedScopes = activeService.getScopes();
        }

        // Build the list of active scopes
        final Set activeScopes = new HashSet();
        activeScopes.addAll(enabledContextIds);
        if (nestedScopes != null) {
            for (int i = 0; i < nestedScopes.length; i++) {
                activeScopes.add(nestedScopes[i]);
            }
        }

        return (String[]) activeScopes.toArray(new String[activeScopes.size()]);
    }

    /**
     * Replaces the active workbench site with this service's active workbench
     * site. This ensures that the context manager will recognize the context as
     * active. Note: this method modifies the list in place; it is
     * <em>destructive</em>.
     * 
     * @param submissionsToModify
     *            The submissions list to modify; must not be <code>null</code>,
     *            but may be empty.
     */
    private final void normalizeSites(final List submissionsToModify) {
        if (disposed) return;

        final int size = submissionsToModify.size();
        for (int i = 0; i < size; i++) {
            final Object submission = submissionsToModify.get(i);
            final Object replacementSubmission;

            if (submission instanceof EnabledSubmission) {
                final EnabledSubmission enabledSubmission = (EnabledSubmission) submission;
                if (!workbenchPartSite.equals(enabledSubmission
                        .getActiveWorkbenchPartSite())) {
                    replacementSubmission = new EnabledSubmission(
                            null, enabledSubmission.getActiveShell(),
                            workbenchPartSite, enabledSubmission.getContextId());
                } else {
                    replacementSubmission = enabledSubmission;
                }

            } else if (submission instanceof HandlerSubmission) {
                final HandlerSubmission handlerSubmission = (HandlerSubmission) submission;
                if (!workbenchPartSite.equals(handlerSubmission
                        .getActiveWorkbenchPartSite())) {
                    replacementSubmission = new HandlerSubmission(null,
                            handlerSubmission.getActiveShell(),
                            workbenchPartSite,
                            handlerSubmission.getCommandId(), handlerSubmission
                                    .getHandler(), handlerSubmission
                                    .getPriority());
                } else {
                    replacementSubmission = handlerSubmission;
                }

            } else {
                replacementSubmission = submission;
            }

            submissionsToModify.set(i, replacementSubmission);
        }

    }

    public void registerAction(IAction action) {
        if (disposed) return;

        unregisterAction(action);
        String commandId = action.getActionDefinitionId();
        if (commandId != null) {
            /*
             * If I have a parent and I'm active, de-activate myself while
             * making changes.
             */
            boolean active = false;
            if ((parent != null) && (parent.activeService == this)) {
                active = true;
                parent.deactivateNestedService();
            }

            // Create the new submission
            IHandler handler = new ActionHandler(action);
            HandlerSubmission handlerSubmission = new HandlerSubmission(null,
                    null, workbenchPartSite, commandId, handler,
                    Priority.MEDIUM);
            handlerSubmissionsByCommandId.put(commandId, handlerSubmission);

            // Either submit the new handler myself, or simply re-activate.
            if (parent != null) {
                if (active) {
                    parent.activateNestedService(this);
                }
            } else {
                Workbench.getInstance().getCommandSupport()
                        .addHandlerSubmission(handlerSubmission);
            }
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.INestableKeyBindingService#removeKeyBindingService(org.eclipse.ui.IWorkbenchSite)
     */
    public boolean removeKeyBindingService(IWorkbenchSite nestedSite) {
        if (disposed) return false;

        final IKeyBindingService service = (IKeyBindingService) nestedServices
                .remove(nestedSite);
        if (service == null) { return false; }

        if (service.equals(activeService)) {
            deactivateNestedService();
        }

        return true;
    }

    public void setScopes(String[] scopes) {
        if (disposed) return;

        // Either deactivate myself, or remove the previous submissions myself.
        boolean active = false;
        if ((parent != null) && (parent.activeService == this)) {
            active = true;
            parent.deactivateNestedService();
        } else {
            Workbench.getInstance().getContextSupport()
                    .removeEnabledSubmissions(enabledSubmissions);
        }
        enabledSubmissions.clear();

        // Determine the new list of submissions.
        enabledContextIds = new HashSet(Arrays.asList(scopes));
        for (Iterator iterator = enabledContextIds.iterator(); iterator
                .hasNext();) {
            String contextId = (String) iterator.next();
            enabledSubmissions.add(new EnabledSubmission(null, null,
                    workbenchPartSite, contextId));
        }

        // Submit the new contexts myself, or simply re-active myself.
        if (parent != null) {
            if (active) {
                parent.activateNestedService(this);
            }
        } else {
            Workbench.getInstance().getContextSupport().addEnabledSubmissions(
                    enabledSubmissions);
        }
    }

    public void unregisterAction(IAction action) {
        if (disposed) return;

        String commandId = action.getActionDefinitionId();

        if (commandId != null) {
            // Deactivate this service while making changes.
            boolean active = false;
            if ((parent != null) && (parent.activeService == this)) {
                active = true;
                parent.deactivateNestedService();
            }

            // Remove the current submission, if any.
            HandlerSubmission handlerSubmission = (HandlerSubmission) handlerSubmissionsByCommandId
                    .remove(commandId);

            /*
             * Either activate this service again, or remove the submission
             * myself.
             */
            if (handlerSubmission != null) {
                if (parent != null) {
                    if (active) {
                        parent.activateNestedService(this);
                    }
                } else {
                    Workbench.getInstance().getCommandSupport()
                            .removeHandlerSubmission(handlerSubmission);
                    handlerSubmission.getHandler().dispose();
                }
            }
        }
    }
}