/*******************************************************************************
 * Copyright (c) 2000, 2005 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.actions;

import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.ContributionItem;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IContributionItem;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.ui.IPerspectiveDescriptor;
import org.eclipse.ui.IPerspectiveRegistry;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.activities.WorkbenchActivityHelper;
import org.eclipse.ui.internal.WorkbenchMessages;
import org.eclipse.ui.internal.dialogs.SelectPerspectiveDialog;

/**
 * A menu for perspective selection.  
 * <p>
 * A <code>PerspectiveMenu</code> is used to populate a menu with
 * perspective shortcut items.  If the user selects one of these items 
 * an action is performed for the selected perspective.
 * </p><p>
 * The visible perspective items within the menu are dynamic and reflect the
 * available set generated by each subclass. The default available set consists
 * of the perspective shortcut list of the current perspective.
 * </p><p>
 * This class is abstract.  Subclasses must implement the <code>run</code> method,
 * which performs a specialized action for the selected perspective.
 * </p>
 */
public abstract class PerspectiveMenu extends ContributionItem {
    private IPerspectiveRegistry reg;

    private IWorkbenchWindow window;

    private boolean showActive = false;

    private boolean dirty = true;

    private IMenuListener menuListener = new IMenuListener() {
        public void menuAboutToShow(IMenuManager manager) {
            manager.markDirty();
            dirty = true;
        }
    };

    private Comparator comparator = new Comparator() {
        private Collator collator = Collator.getInstance();

        public int compare(Object ob1, Object ob2) {
            IPerspectiveDescriptor d1 = (IPerspectiveDescriptor) ob1;
            IPerspectiveDescriptor d2 = (IPerspectiveDescriptor) ob2;
            return collator.compare(d1.getLabel(), d2.getLabel());
        }
    };

    /**
     * The translatable message to show when there are no perspectives.
     * 
     * @since 3.1
     */
    private static final String NO_TARGETS_MSG = WorkbenchMessages.Workbench_showInNoPerspectives;

    /**
     * The map of perspective identifiers (String) to actions
     * (OpenPerspectiveAction). This map may be empty, but it is never
     * <code>null</code>.
     * 
     * @since 3.1
     */
    private Map actions = new HashMap();

    /**
     * The action for that allows the user to choose any perspective to open.
     * 
     * @since 3.1
     */
    private Action openOtherAction = new Action(WorkbenchMessages.PerspectiveMenu_otherItem) {
        public final void runWithEvent(final Event event) {
            runOther(new SelectionEvent(event));
        }
    };


    /**
     * Constructs a new instance of <code>PerspectiveMenu</code>.  
     *
     * @param window the window containing this menu
     * @param id the menu id
     */
    public PerspectiveMenu(IWorkbenchWindow window, String id) {
        super(id);
        this.window = window;
        reg = window.getWorkbench().getPerspectiveRegistry();
		openOtherAction
				.setActionDefinitionId("org.eclipse.ui.perspectives.showPerspective"); //$NON-NLS-1$
    }

    /*
     * (non-Javadoc) Fills the menu with perspective items.
     */
    public void fill(Menu menu, int index) {
        if (getParent() instanceof MenuManager) {
			((MenuManager) getParent()).addMenuListener(menuListener);
		}

        if (!dirty) {
			return;
		}

        final MenuManager manager = new MenuManager();
        fillMenu(manager);
        final IContributionItem items[] = manager.getItems();
        if (items.length == 0) {
            MenuItem item = new MenuItem(menu, SWT.NONE, index++);
            item.setText(NO_TARGETS_MSG);
            item.setEnabled(false);
        } else {
            for (int i = 0; i < items.length; i++) {
                items[i].fill(menu, index++);
            }
        }
        dirty = false;
    }

    /**
     * Fills the given menu manager with all the open perspective actions
     * appropriate for the currently active perspective. Filtering is applied to
     * the actions based on the activities and capabilities mechanism.
     * 
     * @param manager
     *            The menu manager that should receive the menu items; must not
     *            be <code>null</code>.
     * @since 3.1
     */
    private final void fillMenu(final MenuManager manager) {
        // Clear out the manager so that we have a blank slate.
        manager.removeAll();

        // Collect and sort perspective descriptors.
        final List persps = getPerspectiveItems();
        Collections.sort(persps, comparator);

        /*
         * Convert the perspective descriptors to actions, and filter out
         * actions using the activity/capability mechanism.
         */
        final List actions = new ArrayList(persps.size());
        for (Iterator i = persps.iterator(); i.hasNext();) {
            final IPerspectiveDescriptor descriptor = (IPerspectiveDescriptor) i
                    .next();
            final IAction action = getAction(descriptor.getId());
            if (action != null) {
                if (WorkbenchActivityHelper.filterItem(action)) {
					continue;
				}
                actions.add(action);
            }
        }

        // Go through and add each of the actions to the menu manager.
        for (Iterator i = actions.iterator(); i.hasNext();) {
            manager.add((IAction) i.next());
        }

        // Add a separator and then "Other..."
        if (actions.size() > 0) {
            manager.add(new Separator());
        }
        manager.add(openOtherAction);
    }

    /**
     * Returns the action for the given perspective id. This is a lazy cache. If
     * the action does not already exist, then it is created. If there is no
     * perspective with the given identifier, then the action is not created.
     * 
     * @param id
     *            The identifier of the perspective for which the action should
     *            be retrieved.
     * @return The action for the given identifier; or <code>null</code> if
     *         there is no perspective with the given identifier.
     * @since 3.1
     */
    private final IAction getAction(final String id) {
        IAction action = (IAction) actions.get(id);
        if (action == null) {
            IPerspectiveDescriptor descriptor = reg.findPerspectiveWithId(id);
            if (descriptor != null) {
                action = new OpenPerspectiveAction(window, descriptor, this);
                action.setActionDefinitionId(id);
                actions.put(id, action);
            }
        }
        return action;
    }

    /* (non-Javadoc)
     * Returns the perspective shortcut items for the active perspective.
     * 
     * @return a list of <code>IPerspectiveDescriptor</code> items
     */
    private ArrayList getPerspectiveShortcuts() {
        ArrayList list = new ArrayList();

        IWorkbenchPage page = window.getActivePage();
        if (page == null) {
			return list;
		}

        String[] ids = page.getPerspectiveShortcuts();

        for (int i = 0; i < ids.length; i++) {
            IPerspectiveDescriptor desc = reg.findPerspectiveWithId(ids[i]);
            if (desc != null && !list.contains(desc)) {
                if (WorkbenchActivityHelper.filterItem(desc)) {
					continue;
				}
                list.add(desc);
            }
        }

        return list;
    }

    /**
     * Returns the available list of perspectives to display in the menu.
     * <p>
     * By default, the list contains the perspective shortcuts
     * for the current perspective.
     * </p><p>
     * Subclasses can override this method to return a different list.
     * </p>
     * 
     * @return an <code>ArrayList<code> of perspective items <code>IPerspectiveDescriptor</code>
     */
    protected ArrayList getPerspectiveItems() {
        /* Allow the user to see all the perspectives they have 
         * selected via Customize Perspective. Bugzilla bug #23445 */
        ArrayList shortcuts = getPerspectiveShortcuts();
        ArrayList list = new ArrayList(shortcuts.size());

        // Add perspective shortcuts from the active perspective
        int size = shortcuts.size();
        for (int i = 0; i < size; i++) {
            if (!list.contains(shortcuts.get(i))) {
                list.add(shortcuts.get(i));
            }
        }

        return list;
    }

    /**
     * Returns whether the menu item representing the active perspective
     * will have a check mark.
     *
     * @return <code>true</code> if a check mark is shown, <code>false</code> otherwise
     */
    protected boolean getShowActive() {
        return showActive;
    }

    /**
     * Returns the window for this menu.
     *
     * @return the window 
     */
    protected IWorkbenchWindow getWindow() {
        return window;
    }

    /* (non-Javadoc)
     * Returns whether this menu is dynamic.
     */
    public boolean isDirty() {
        return dirty;
    }

    /* (non-Javadoc)
     * Returns whether this menu is dynamic.
     */
    public boolean isDynamic() {
        return true;
    }

    /**
     * Runs an action for a particular perspective.  The behavior of the
     * action is defined by the subclass.
     *
     * @param desc the selected perspective
     */
    protected abstract void run(IPerspectiveDescriptor desc);

    /**
     * Runs an action for a particular perspective. The behavior of the action
     * is defined by the subclass. By default, this just calls
     * <code>run(IPerspectiveDescriptor)</code>.
     * 
     * @param desc
     *            the selected perspective
     * @param event
     *            SelectionEvent - the event send along with the selection
     *            callback
     */
    protected void run(IPerspectiveDescriptor desc, SelectionEvent event) {
        //Do a run without the event by default
        run(desc);
    }

    /* (non-Javadoc)
     * Show the "other" dialog, select a perspective, and run it. Pass on the selection
     * event should the meny need it.
     */
    void runOther(SelectionEvent event) {
        SelectPerspectiveDialog dlg = new SelectPerspectiveDialog(window
                .getShell(), reg);
        dlg.open();
        if (dlg.getReturnCode() == Window.CANCEL) {
			return;
		}
        IPerspectiveDescriptor desc = dlg.getSelection();
        if (desc != null) {
            run(desc, event);
        }
    }

    /**
     * Sets the showActive flag.  If <code>showActive == true</code> then the
     * active perspective is hilighted with a check mark.
     *
     * @param b the new showActive flag
     */
    protected void showActive(boolean b) {
        showActive = b;
    }
}
