//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 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 implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.rcp;

import org.eclipse.epf.authoring.ui.AuthoringUIHelpContexts;
import org.eclipse.epf.authoring.ui.UIActionDispatcher;
import org.eclipse.epf.authoring.ui.preferences.ApplicationPreferenceConstants;
import org.eclipse.epf.authoring.ui.views.ViewHelper;
import org.eclipse.epf.library.LibraryPlugin;
import org.eclipse.epf.publishing.ui.PublisherFactory;
import org.eclipse.epf.rcp.actions.NewButtonAction;
import org.eclipse.epf.rcp.actions.UIActionFactory;
import org.eclipse.epf.rcp.actions.UIOpenPerspectiveDialogAction;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.GroupMarker;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IContributionItem;
import org.eclipse.jface.action.ICoolBarManager;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.SWT;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.actions.ContributionItemFactory;
import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction;
import org.eclipse.ui.application.ActionBarAdvisor;
import org.eclipse.ui.application.IActionBarConfigurer;

/**
 * Creates, adds and disposes the actions added to a workbench window.
 * 
 * @author Bingxue Xu
 * @author Kelvin Low
 * @author Phong Nguyen Le
 * @author Jinhua Xi
 * @since 1.0
 */
public class MainActionBarAdvisor extends ActionBarAdvisor {

	// All actions should be created in makeActions and referenced in the
	// fill methods. This ensures that the actions aren't recreated
	// when fillActionBars is called with FILL_PROXY.

	// File actions. 
	private IWorkbenchAction newAction;

	private IWorkbenchAction closeAction;

	private IWorkbenchAction closeAllAction;

	private IWorkbenchAction saveAction;

	private IWorkbenchAction saveAsAction;

	private IWorkbenchAction saveAllAction;

	private IWorkbenchAction revertAction;

	private IWorkbenchAction moveAction;

	private IWorkbenchAction renameAction;

	private IWorkbenchAction refreshAction;

	// private IWorkbenchAction printAction;
	private IWorkbenchAction importAction;

	private IWorkbenchAction exportAction;

	private IWorkbenchAction propertiesAction;

	private IWorkbenchAction exitAction;

	// Edit actions.
	private IWorkbenchAction openElementAction;

	private IWorkbenchAction undoAction;

	private IWorkbenchAction redoAction;

	private IWorkbenchAction cutAction;

	private IWorkbenchAction copyAction;

	private IWorkbenchAction pasteAction;

	private IWorkbenchAction deleteAction;

	private IWorkbenchAction selectAllAction;

	private IWorkbenchAction findAction;

	// Navigate actions.
	private IWorkbenchAction goIntoAction;

	private IWorkbenchAction nextAction;

	private IWorkbenchAction previousAction;

	private IWorkbenchAction backAction;

	private IWorkbenchAction forwardAction;

	// Window actions.
	private IWorkbenchAction openNewWindowAction;
	
	private IWorkbenchAction openPerspectiveDialogAction;
	
	private IContributionItem showViewShortList;
	
	private IWorkbenchAction customizePerspectiveAction;

	private IWorkbenchAction savePerspectiveAction;

	private IWorkbenchAction resetPerspectiveAction;

	private IWorkbenchAction closePerspectiveAction;

	private IWorkbenchAction closeAllPerspectiveAction;

	private IWorkbenchAction preferencesAction;

	// Window navigation actions.
	private IWorkbenchAction nextEditorAction;

	private IWorkbenchAction previousEditorAction;

	private IWorkbenchAction nextPartAction;

	private IWorkbenchAction previousPartAction;

	private IWorkbenchAction nextPerspectiveAction;

	private IWorkbenchAction previousPerspectiveAction;

	// Help actions.
	private IWorkbenchAction welcomeAction;

	private IWorkbenchAction helpContentsAction;

	private IWorkbenchAction aboutAction;
	
	// Upgrade Library action.	
	//private IAction upgradeI1LibraryAction;
	
	private IAction openAuthoringPerspectiveAction;
	private IAction openBrowsingPerspectiveAction;
	
	// New action invoked via the New button on the system toolbar.
	private NewButtonAction fileNewAction;

	private MenuManager mainHelpMenu;

	private MenuManager mainFileMenu;

	private MenuManager internalMenu;

	private IWorkbenchWindow window;

	/**
	 * Creates a new instance.
	 * 
	 * @param configurer
	 *            the action bar configurer
	 */
	public MainActionBarAdvisor(IActionBarConfigurer configurer) {
		super(configurer);
		window = configurer.getWindowConfigurer().getWindow();
	}

	public IWorkbenchWindow getWindow() {
		return window;
	}

	/**
	 * @see org.eclipse.ui.application.ActionBarAdvisor#makeActions(final
	 *      IWorkbenchWindow window)
	 */
	protected void makeActions(final IWorkbenchWindow window) {
		// Creates the actions and registers them. Registering is needed to
		// ensure that
		// key bindings work. The corresponding commands key bindings are
		// defined in the
		// plugin.xml file. Registering also provides automatic disposal of the
		// actions
		// when the window is closed.
		newAction = ActionFactory.NEW.create(window);
		register(newAction);

		closeAction = ActionFactory.CLOSE.create(window);
		register(closeAction);

		closeAllAction = ActionFactory.CLOSE_ALL.create(window);
		register(closeAllAction);

		saveAction = ActionFactory.SAVE.create(window);
		register(saveAction);

		saveAsAction = ActionFactory.SAVE_AS.create(window);
		register(saveAsAction);

		saveAllAction = ActionFactory.SAVE_ALL.create(window);
		register(saveAllAction);

		revertAction = ActionFactory.REVERT.create(window);
		register(revertAction);

		moveAction = ActionFactory.MOVE.create(window);
		register(moveAction);

		renameAction = ActionFactory.RENAME.create(window);
		register(renameAction);

		refreshAction = ActionFactory.REFRESH.create(window);
		register(refreshAction);

		// printAction = ActionFactory.PRINT.create(window);
		// register(printAction);

		importAction = UIActionFactory.UI_IMPORT.create(window);
		PlatformUI.getWorkbench().getHelpSystem().setHelp(importAction, AuthoringUIHelpContexts.FILE_IMPORT_CONTEXT);
		register(importAction);
		
		exportAction = UIActionFactory.UI_EXPORT.create(window);
		PlatformUI.getWorkbench().getHelpSystem().setHelp(exportAction, AuthoringUIHelpContexts.FILE_EXPORT_CONTEXT);
		register(exportAction);

		propertiesAction = ActionFactory.PROPERTIES.create(window);
		register(propertiesAction);

		exitAction = ActionFactory.QUIT.create(window);
		register(exitAction);		
		
		openElementAction = UIActionFactory.OPEN_ELEMENT.create(window);
		register(openElementAction);

		undoAction = ActionFactory.UNDO.create(window);
		register(undoAction);

		redoAction = ActionFactory.REDO.create(window);
		register(redoAction);

		cutAction = ActionFactory.CUT.create(window);
		register(cutAction);

		copyAction = ActionFactory.COPY.create(window);
		register(copyAction);

		pasteAction = ActionFactory.PASTE.create(window);
		register(pasteAction);

		deleteAction = ActionFactory.DELETE.create(window);
		register(deleteAction);

		selectAllAction = ActionFactory.SELECT_ALL.create(window);
		register(selectAllAction);

		findAction = ActionFactory.FIND.create(window);
		register(findAction);

		goIntoAction = ActionFactory.GO_INTO.create(window);
		register(goIntoAction);

		nextAction = ActionFactory.NEXT.create(window);
		register(nextAction);

		previousAction = ActionFactory.PREVIOUS.create(window);
		register(previousAction);

		backAction = ActionFactory.BACK.create(window);
		register(backAction);

		forwardAction = ActionFactory.FORWARD.create(window);
		register(forwardAction);

		openNewWindowAction = ActionFactory.OPEN_NEW_WINDOW.create(window);
		register(openNewWindowAction);

		nextEditorAction = ActionFactory.NEXT_EDITOR.create(window);
		register(nextEditorAction);

		previousEditorAction = ActionFactory.PREVIOUS_EDITOR.create(window);
		register(previousEditorAction);

		nextPartAction = ActionFactory.NEXT_PART.create(window);
		register(nextPartAction);

		previousPartAction = ActionFactory.PREVIOUS_PART.create(window);
		register(previousPartAction);

		nextPerspectiveAction = ActionFactory.NEXT_PERSPECTIVE.create(window);
		register(nextPerspectiveAction);

		previousPerspectiveAction = ActionFactory.PREVIOUS_PERSPECTIVE
				.create(window);
		register(previousPerspectiveAction);
		
		openPerspectiveDialogAction = createTNGOpenPerspectiveDialogAction(window);
		openPerspectiveDialogAction.setText(RCPResources.otherMenuItem_text); 
		register(openPerspectiveDialogAction);

		showViewShortList = ContributionItemFactory.VIEWS_SHORTLIST.create(window);

		customizePerspectiveAction = ActionFactory.EDIT_ACTION_SETS.create(window);
		register(customizePerspectiveAction);

		savePerspectiveAction = ActionFactory.SAVE_PERSPECTIVE.create(window);
		register(savePerspectiveAction);

		resetPerspectiveAction = ActionFactory.RESET_PERSPECTIVE.create(window);
		register(resetPerspectiveAction);

		closePerspectiveAction = ActionFactory.CLOSE_PERSPECTIVE.create(window);
		register(closePerspectiveAction);

		closeAllPerspectiveAction = ActionFactory.CLOSE_ALL_PERSPECTIVES
				.create(window);
		register(closeAllPerspectiveAction);

		preferencesAction = ActionFactory.PREFERENCES.create(window);
		register(preferencesAction);

		welcomeAction = UIActionFactory.SHOW_INTRO.create(window);
		register(welcomeAction);
		ImageDescriptor imgDes = MainPlugin.getDefault().getImageDescriptor(
				"full/obj16/product.gif"); //$NON-NLS-1$
		welcomeAction.setImageDescriptor(imgDes);

		helpContentsAction = ActionFactory.HELP_CONTENTS.create(window);
		register(helpContentsAction);

		// helpSearchItem = ContributionItemFactory.HELP_SEARCH.create(window);
		aboutAction = ActionFactory.ABOUT.create(window);
		register(aboutAction);
		
		/* TODO: Is this still needed?
		upgradeI1LibraryAction = new Action(RCPResources.getString("RCP.upgradeLibraryAction.text")) { //$NON-NLS-1$
			public void run() {
				ViewHelper.loadAllAndSaveAll();
			}
		};
		upgradeI1LibraryAction.setId("com.ibm.rmc.rcp.actions.upgradeI1LibraryAction"); //$NON-NLS-1$
		*/
		
		openAuthoringPerspectiveAction = new Action(RCPResources.openAuthoringPerspectiveAction_text) { 
			public void run() {
				UIActionDispatcher.openAuthoringPerspective();
			}
		};
		
		openBrowsingPerspectiveAction = new Action(RCPResources.openBrowsingPerspectiveAction_text) { 
			public void run() {
				UIActionDispatcher.openLibraryPerspective();
			}
		};		
   }
    
	/**
	 * @see org.eclipse.ui.application.ActionBarAdvisor#fillMenuBar(IMenuManager
	 *      menuBar)
	 */
	protected void fillMenuBar(IMenuManager menuBar) {
		mainFileMenu = createFileMenu(menuBar);
		menuBar.add(mainFileMenu);
		menuBar.add(createEditMenu(menuBar));

		IMenuManager navManager = createNavigateMenu(menuBar);
		menuBar.add(navManager);
		navManager.setVisible(false);

		// add the configuration menu
		menuBar.add(createConfigurationMenu(menuBar));

		menuBar.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
		menuBar.add(createWindowMenu(menuBar));

		mainHelpMenu = createHelpMenu(menuBar);
		menuBar.add(mainHelpMenu);
	}

	/**
	 * Gets the File menu manager.
	 */
	public MenuManager getFileMenuManager() {
		return mainFileMenu;
	}

	/**
	 * Gets the Help menu manager.
	 */
	public MenuManager getHelpMenuManager() {
		return mainHelpMenu;
	}

	/**
	 * @see org.eclipse.ui.application.ActionBarAdvisor#fillCoolBar(ICoolBarManager
	 *      coolBar)
	 */
	protected void fillCoolBar(ICoolBarManager coolBar) {
		coolBar.add(createFileToolbar());
	}

	/**
	 * Creates the File menu.
	 */
	private MenuManager createFileMenu(IMenuManager menuBar) {
		MenuManager fileMenu = new MenuManager(RCPResources.fileMenuItem_text,
				IWorkbenchActionConstants.M_FILE);
		fileMenu.add(new GroupMarker(IWorkbenchActionConstants.FILE_START));

		MenuManager newSubMenu = new MenuManager(
				RCPResources.fileNewMenuItem_text,
				IWorkbenchActionConstants.NEW_EXT);
		newSubMenu.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
		newSubMenu.add(new Separator());
		fileMenu.add(newSubMenu);

		fileMenu.add(new Separator());
		MenuManager openSubMenu = new MenuManager(
				RCPResources.fileOpenMenuItem_text,
				IWorkbenchActionConstants.OPEN_EXT);
		openSubMenu
				.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
		openSubMenu.add(new Separator());
		fileMenu.add(openSubMenu);

		fileMenu.add(closeAction);
		fileMenu.add(closeAllAction);
		fileMenu.add(new Separator());
		fileMenu.add(saveAction);
		fileMenu.add(saveAsAction);
		fileMenu.add(saveAllAction);
		fileMenu.add(revertAction);
		fileMenu.add(new Separator());
		fileMenu.add(moveAction);
		fileMenu.add(renameAction);
		fileMenu.add(refreshAction);
		fileMenu.add(new Separator());
		// fileMenu.add(printAction);
		// fileMenu.add(new Separator());
		fileMenu.add(importAction);
		fileMenu.add(exportAction);
		fileMenu.add(new Separator());
		fileMenu.add(propertiesAction);
		fileMenu.add(new Separator());
		fileMenu.add(exitAction);
		fileMenu.add(new GroupMarker(IWorkbenchActionConstants.FILE_END));

		return fileMenu;
	}

	/**
	 * Creates the Edit menu.
	 */
	private MenuManager createEditMenu(IMenuManager menuBar) {
		MenuManager editMenu = new MenuManager(RCPResources.editMenuItem_text,
				IWorkbenchActionConstants.M_EDIT);
		editMenu.add(new GroupMarker(IWorkbenchActionConstants.EDIT_START));
		editMenu.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
		editMenu.add(new Separator());
		editMenu.add(new GroupMarker("opengroup")); //$NON-NLS-1$
		editMenu.add(openElementAction);
		editMenu.add(cutAction);
		editMenu.add(copyAction);
		editMenu.add(pasteAction);
		editMenu.add(new Separator());
		editMenu.add(deleteAction);
		editMenu.add(selectAllAction);
		editMenu.add(new Separator());
		editMenu.add(findAction);
		editMenu.add(new GroupMarker(IWorkbenchActionConstants.EDIT_END));
		return editMenu;
	}

	/**
	 * Creates the Navigate menu.
	 */
	private MenuManager createNavigateMenu(IMenuManager menuBar) {
		MenuManager navMenu = new MenuManager(
				RCPResources.navigateMenuItem_text,
				IWorkbenchActionConstants.M_NAVIGATE);
		navMenu.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
		navMenu.add(goIntoAction);
		navMenu.add(new Separator());
		navMenu.add(nextAction);
		navMenu.add(previousAction);
		navMenu.add(new Separator());
		navMenu.add(backAction);
		navMenu.add(forwardAction);
		navMenu.add(new GroupMarker(IWorkbenchActionConstants.WB_END));
		return navMenu;
	}

	private MenuManager createConfigurationMenu(IMenuManager menuBar) {
		String id = "org.eclipse.epf.library.menu.configuration"; //$NON-NLS-1$
		String name = RCPResources.configurationMenuItem_text;
		MenuManager configMenu = new MenuManager(name, id);
		configMenu.add(new GroupMarker(IWorkbenchActionConstants.WB_START));
		configMenu.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));

		// create publish actions
		Action[] actions = PublisherFactory.getInstance()
				.createPublishActions();
		if (actions != null && actions.length > 0) {
			for (int i = 0; i < actions.length; i++) {
				configMenu.add(actions[i]);
			}
		}

		return configMenu;
	}

	/**
	 * Creates the Window menu.
	 */
	private MenuManager createWindowMenu(IMenuManager menuBar) {
		MenuManager windowMenu = new MenuManager(
				RCPResources.windowMenuItem_text,
				IWorkbenchActionConstants.M_WINDOW);
		windowMenu.add(new GroupMarker(IWorkbenchActionConstants.WB_START));
		windowMenu.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));

		MenuManager changePerspMenuMgr = new MenuManager(
				RCPResources.windowOpenPerspectiveMenuItem_text,
				"openPerspective"); //$NON-NLS-1$
		IContributionItem changePerspMenuItem = ContributionItemFactory.PERSPECTIVES_SHORTLIST
				.create(getWindow());
		changePerspMenuMgr.add(changePerspMenuItem);
		windowMenu.add(changePerspMenuMgr);
		MenuManager showViewMenuMgr = new MenuManager(
				RCPResources.windowShowViewMenuItem_text, "showView"); //$NON-NLS-1$
		IContributionItem showViewMenu = ContributionItemFactory.VIEWS_SHORTLIST
				.create(getWindow());
		showViewMenuMgr.add(showViewMenu);
		windowMenu.add(showViewMenuMgr);

		windowMenu.add(new Separator());
		windowMenu.add(customizePerspectiveAction);
		windowMenu.add(savePerspectiveAction);
		windowMenu.add(resetPerspectiveAction);
		windowMenu.add(closePerspectiveAction);
		windowMenu.add(closeAllPerspectiveAction);
		windowMenu.add(new Separator());
		windowMenu.add(preferencesAction);
		windowMenu.add(new GroupMarker(IWorkbenchActionConstants.WB_END));
		return windowMenu;
	}

	private void createInternalMenu(final IMenuManager helpMmenu) {
		internalMenu = new MenuManager(
				RCPResources.mainActionBarAdvisor_Diagnosis, ""); //$NON-NLS-1$

		internalMenu.add(new Action(
				RCPResources.mainActionBarAdvisor_HealthCheck) {
			public void run() {
				ViewHelper.checkLibraryHealth();
			}
		});
		internalMenu.add(new Action(
				RCPResources.mainActionBarAdvisor_RemoveReference) {
			public void run() {
				ViewHelper.removeInvalidReferences();
			}
		});

		if (LibraryPlugin.getDefault().getPreferenceStore().getBoolean(
				ApplicationPreferenceConstants.PREF_ENABLE_HEALTH_CHECK)) {
			helpMmenu.appendToGroup("group.internal", internalMenu); //$NON-NLS-1$
		}

		LibraryPlugin.getDefault().getPreferenceStore()
				.addPropertyChangeListener(new IPropertyChangeListener() {

					public void propertyChange(PropertyChangeEvent event) {
						if (event
								.getProperty()
								.equals(
										ApplicationPreferenceConstants.PREF_ENABLE_HEALTH_CHECK)) {
							Boolean healthCheckEnabled = (Boolean) event
									.getNewValue();
							if (healthCheckEnabled != null
									&& healthCheckEnabled.booleanValue()) {
								helpMmenu.insertAfter(
										"group.internal", internalMenu); //$NON-NLS-1$
							} else {
								helpMmenu.remove(internalMenu);
							}
						}
					}

				});
	}

	/**
	 * Creates the Help menu.
	 */
	private MenuManager createHelpMenu(IMenuManager menuBar) {
		MenuManager helpMmenu = new MenuManager(RCPResources.helpMenuItem_text,
				IWorkbenchActionConstants.M_HELP);
		helpMmenu.add(new GroupMarker(IWorkbenchActionConstants.HELP_START));
		helpMmenu.add(welcomeAction);

		helpMmenu.add(new Separator());
		helpMmenu.add(helpContentsAction);
		helpMmenu.add(new GroupMarker("group.help")); //$NON-NLS-1$

		helpMmenu.add(new Separator());
		helpMmenu.add(new GroupMarker("group.assist")); //$NON-NLS-1$

		helpMmenu.add(new Separator());
		helpMmenu.add(new GroupMarker("group.tools")); //$NON-NLS-1$
		
		helpMmenu.add(new Separator());
		helpMmenu.add(new GroupMarker("group.updates")); //$NON-NLS-1$

		// Menu items for internal tool
		helpMmenu.add(new Separator());
		helpMmenu.add(new GroupMarker("group.internal")); //$NON-NLS-1$
		createInternalMenu(helpMmenu);

		helpMmenu.add(new Separator());
		helpMmenu.add(aboutAction);
		helpMmenu.add(new GroupMarker(IWorkbenchActionConstants.HELP_END));
		return helpMmenu;
	}

	/**
	 * Creates the File toolbar.
	 */
	private IToolBarManager createFileToolbar() {
		IToolBarManager toolbar = new ToolBarManager(SWT.FLAT | SWT.LEFT);
		toolbar.add(new GroupMarker(IWorkbenchActionConstants.FILE_START));
		fileNewAction = new NewButtonAction();
		toolbar.add(fileNewAction);
		toolbar.add(saveAction);
		toolbar.add(saveAllAction);
		// toolbar.add(printAction);
		toolbar.add(new GroupMarker(IWorkbenchActionConstants.FILE_END));
		return toolbar;
    }
	
    private IWorkbenchAction createTNGOpenPerspectiveDialogAction(IWorkbenchWindow window) {
        if (window == null) {
            throw new IllegalArgumentException();
        }
        IWorkbenchAction action = new UIOpenPerspectiveDialogAction(window);
        action.setId("openPerspectiveDialog"); //$NON-NLS-1$
        return action;
    }
    
}
