/*******************************************************************************
 * Copyright (c) 2004 Actuate Corporation .
 * 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:
 *  Actuate Corporation  - initial API and implementation
 *******************************************************************************/

package org.eclipse.birt.report.designer.ui.internal.rcp;

import org.eclipse.birt.report.designer.ui.ReportPlugin;
import org.eclipse.birt.report.designer.ui.internal.rcp.actions.NewLibraryAction;
import org.eclipse.birt.report.designer.ui.internal.rcp.actions.NewReportAction;
import org.eclipse.birt.report.designer.ui.internal.rcp.actions.NewReportTemplateAction;
import org.eclipse.birt.report.designer.ui.internal.rcp.actions.OpenFileAction;
import org.eclipse.birt.report.designer.ui.rcp.nls.DesignerWorkbenchMessages;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.action.ActionContributionItem;
import org.eclipse.jface.action.GroupMarker;
import org.eclipse.jface.action.IContributionItem;
import org.eclipse.jface.action.ICoolBarManager;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IStatusLineManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.action.ToolBarContributionItem;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.preference.IPreferenceStore;
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.NewWizardDropDownAction;
import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction;
import org.eclipse.ui.application.ActionBarAdvisor;
import org.eclipse.ui.application.IActionBarConfigurer;

/**
 * Class for configuring the action bart of BIRT RCP designer.
 */
public class DesignerActionBarAdvisor extends ActionBarAdvisor
{

	private final IWorkbenchWindow window;

	// generic actions
	private IWorkbenchAction openFileAction;

	private IWorkbenchAction newReportAction;

	private IWorkbenchAction newLibraryAction;

	private IWorkbenchAction newReportTemplateAction;

	private IWorkbenchAction closeAction;

	private IWorkbenchAction closeAllAction;

	private IWorkbenchAction saveAction;

	private IWorkbenchAction saveAllAction;

	private IWorkbenchAction helpContentsAction;

	private IWorkbenchAction aboutAction;

	private IWorkbenchAction openPreferencesAction;

	private IWorkbenchAction saveAsAction;

	private IWorkbenchAction lockToolBarAction;

	private IWorkbenchAction backwardHistoryAction;

	private IWorkbenchAction forwardHistoryAction;

	// generic retarget actions
	private IWorkbenchAction undoAction;

	private IWorkbenchAction redoAction;

	private IWorkbenchAction cutAction;

	private IWorkbenchAction copyAction;

	private IWorkbenchAction pasteAction;

	private IWorkbenchAction deleteAction;

	private IWorkbenchAction selectAllAction;

	private IWorkbenchAction findAction;

	private IWorkbenchAction quitAction;

	// IDE-specific actions
	private IWorkbenchAction quickStartAction;

	private IWorkbenchAction tipsAndTricksAction;

	private IWorkbenchAction introAction;

	// contribution items
	private IContributionItem pinEditorContributionItem;

	/**
	 * Indicates if the action builder has been disposed
	 */
	private boolean isDisposed = false;

	/**
	 * Constructs a new action builder which contributes actions to the given
	 * window.
	 * 
	 * @param configurer
	 *            the action bar configurer for the window
	 */
	public DesignerActionBarAdvisor( IActionBarConfigurer configurer )
	{
		super( configurer );
		window = configurer.getWindowConfigurer( ).getWindow( );
	}

	/**
	 * Returns the window to which this action builder is contributing.
	 */
	private IWorkbenchWindow getWindow( )
	{
		return window;
	}

	/**
	 * Fills the coolbar with the workbench actions.
	 */
	protected void fillCoolBar( ICoolBarManager coolBar )
	{
		{
			// Set up the context Menu
			IMenuManager popUpMenu = new MenuManager( );
			popUpMenu.add( new ActionContributionItem( lockToolBarAction ) );
			coolBar.setContextMenuManager( popUpMenu );
		}
		coolBar.add( new GroupMarker( IWorkbenchActionConstants.GROUP_FILE ) );
		{
			// File Group
			IToolBarManager fileToolBar = new ToolBarManager( coolBar.getStyle( ) );
	            
			fileToolBar.add(new NewWizardDropDownAction( window));
			
//			fileToolBar.add( newReportAction );
//			fileToolBar.add( newLibraryAction );
//			fileToolBar.add( newReportTemplateAction );
			fileToolBar.add( new GroupMarker( IWorkbenchActionConstants.NEW_EXT ) );
			fileToolBar.add( new GroupMarker( IWorkbenchActionConstants.SAVE_GROUP ) );
			fileToolBar.add( saveAction );
			fileToolBar.add( new GroupMarker( IWorkbenchActionConstants.SAVE_EXT ) );

			fileToolBar.add( new Separator( IWorkbenchActionConstants.MB_ADDITIONS ) );

			// Add to the cool bar manager
			coolBar.add( new ToolBarContributionItem( fileToolBar,
					IWorkbenchActionConstants.TOOLBAR_FILE ) );
		}

		coolBar.add( new GroupMarker( IWorkbenchActionConstants.MB_ADDITIONS ) );

		// coolBar.add( new GroupMarker( IWorkbenchConstants.GROUP_NAV ) );
		{
			// Navigate group
			IToolBarManager navToolBar = new ToolBarManager( coolBar.getStyle( ) );
			navToolBar.add( new Separator( IWorkbenchActionConstants.HISTORY_GROUP ) );
			navToolBar.add( new GroupMarker( IWorkbenchActionConstants.GROUP_APP ) );
			navToolBar.add( backwardHistoryAction );
			navToolBar.add( forwardHistoryAction );
			navToolBar.add( new Separator( IWorkbenchActionConstants.PIN_GROUP ) );
			navToolBar.add( pinEditorContributionItem );

			// Add to the cool bar manager
			coolBar.add( new ToolBarContributionItem( navToolBar,
					IWorkbenchActionConstants.TOOLBAR_NAVIGATE ) );
		}

		coolBar.add( new GroupMarker( IWorkbenchActionConstants.GROUP_EDITOR ) );

		coolBar.add( new GroupMarker( IWorkbenchActionConstants.GROUP_HELP ) ); //$NON-NLS-1$

		{
			// Help group
			IToolBarManager helpToolBar = new ToolBarManager( coolBar.getStyle( ) );
			helpToolBar.add( new Separator( IWorkbenchActionConstants.GROUP_HELP ) ); //$NON-NLS-1$

			// Add the group for applications to contribute
			helpToolBar.add( new GroupMarker( IWorkbenchActionConstants.GROUP_APP ) );
			// Add to the cool bar manager
			coolBar.add( new ToolBarContributionItem( helpToolBar,
					IWorkbenchActionConstants.TOOLBAR_HELP ) ); //$NON-NLS-1$
		}

	}

	/**
	 * Fills the menu bar with the workbench actions.
	 */
	protected void fillMenuBar( IMenuManager menuBar )
	{
		menuBar.add( createFileMenu( ) );
		menuBar.add( createEditMenu( ) );
		menuBar.add( new GroupMarker( IWorkbenchActionConstants.MB_ADDITIONS ) );
		menuBar.add( createWindowMenu( ) );
		menuBar.add( createHelpMenu( ) );
	}

	/**
	 * Creates and returns the File menu.
	 */
	private MenuManager createFileMenu( )
	{
		MenuManager menu = new MenuManager( DesignerWorkbenchMessages.Workbench_file,
				IWorkbenchActionConstants.M_FILE );
		
		MenuManager newMenu = new MenuManager(DesignerWorkbenchMessages.Workbench_new, ActionFactory.NEW.getId());
		newMenu.add(newReportAction);
		newMenu.add(newLibraryAction);
		newMenu.add(newReportTemplateAction);
		menu.add(newMenu);
		
		menu.add(openFileAction);
		menu.add( new Separator( ) );

		menu.add( closeAction );
		menu.add( closeAllAction );
		menu.add( new GroupMarker( IWorkbenchActionConstants.CLOSE_EXT ) );
		menu.add( new Separator( ) );
		menu.add( saveAction );
		menu.add( saveAsAction );
		menu.add( saveAllAction );
		menu.add( new GroupMarker( IWorkbenchActionConstants.SAVE_EXT ) );

		menu.add( new Separator( IWorkbenchActionConstants.MB_ADDITIONS ) );

		menu.add( ContributionItemFactory.REOPEN_EDITORS.create( getWindow( ) ) );
		menu.add( new GroupMarker( IWorkbenchActionConstants.MRU ) );
		menu.add( new Separator( ) );
		menu.add( quitAction );
		menu.add( new GroupMarker( IWorkbenchActionConstants.FILE_END ) );
		return menu;
	}

	/**
	 * Creates and returns the Edit menu.
	 */
	private MenuManager createEditMenu( )
	{
		MenuManager menu = new MenuManager( DesignerWorkbenchMessages.Workbench_edit,
				IWorkbenchActionConstants.M_EDIT );
		menu.add( new GroupMarker( IWorkbenchActionConstants.EDIT_START ) );

		menu.add( undoAction );
		menu.add( redoAction );
		menu.add( new GroupMarker( IWorkbenchActionConstants.UNDO_EXT ) );
		menu.add( new Separator( ) );

		menu.add( cutAction );
		menu.add( copyAction );
		menu.add( pasteAction );
		menu.add( new GroupMarker( IWorkbenchActionConstants.CUT_EXT ) );
		menu.add( new Separator( ) );

		menu.add( deleteAction );
		menu.add( selectAllAction );
		menu.add( new Separator( ) );

		menu.add( findAction );
		menu.add( new GroupMarker( IWorkbenchActionConstants.FIND_EXT ) );
		menu.add( new Separator( ) );

		menu.add( new GroupMarker( IWorkbenchActionConstants.EDIT_END ) );
		menu.add( new Separator( IWorkbenchActionConstants.MB_ADDITIONS ) );
		return menu;
	}

	/**
	 * Creates and returns the Window menu.
	 */
	private MenuManager createWindowMenu( )
	{
		MenuManager menu = new MenuManager( DesignerWorkbenchMessages.Workbench_window,
				IWorkbenchActionConstants.M_WINDOW );

		addPerspectiveActions( menu );
		menu.add( new Separator( IWorkbenchActionConstants.MB_ADDITIONS ) );
		menu.add( openPreferencesAction );
		return menu;
	}

	/**
	 * Adds the perspective actions to the specified menu.
	 */
	private void addPerspectiveActions( MenuManager menu )
	{
		{
			MenuManager showViewMenuMgr = new MenuManager( DesignerWorkbenchMessages.Workbench_showView,
					"showView" ); //$NON-NLS-1$
			IContributionItem showViewMenu = ContributionItemFactory.VIEWS_SHORTLIST.create( getWindow( ) );
			showViewMenuMgr.add( showViewMenu );
			menu.add( showViewMenuMgr );
		}
	}

	/**
	 * Creates and returns the Help menu.
	 */
	private MenuManager createHelpMenu( )
	{
		MenuManager menu = new MenuManager( DesignerWorkbenchMessages.Workbench_help,
				IWorkbenchActionConstants.M_HELP );

		// See if a welcome or intro page is specified
		if ( introAction != null )
			menu.add( introAction );
		else if ( quickStartAction != null )
			menu.add( quickStartAction );
		menu.add( helpContentsAction );

		if ( tipsAndTricksAction != null )
			menu.add( tipsAndTricksAction );

		menu.add( new GroupMarker( "group.tutorials" ) ); //$NON-NLS-1$
		menu.add( new Separator( IWorkbenchActionConstants.MB_ADDITIONS ) );
		menu.add( new Separator( "group.about" ) ); //$NON-NLS-1$
		menu.add( aboutAction );
		menu.add( new GroupMarker( "group.about.ext" ) ); //$NON-NLS-1$

		return menu;
	}

	/**
	 * Disposes any resources and unhooks any listeners that are no longer
	 * needed. Called when the window is closed.
	 */
	public void dispose( )
	{
		if ( isDisposed )
			return;
		isDisposed = true;

		pinEditorContributionItem.dispose( );

		// null out actions to make leak debugging easier
		openFileAction = null;
		newReportAction = null;
		newLibraryAction = null;
		newReportTemplateAction = null;
		closeAction = null;
		closeAllAction = null;
		saveAction = null;
		saveAllAction = null;
		helpContentsAction = null;
		aboutAction = null;
		openPreferencesAction = null;
		saveAsAction = null;
		lockToolBarAction = null;
		backwardHistoryAction = null;
		forwardHistoryAction = null;
		undoAction = null;
		redoAction = null;
		cutAction = null;
		copyAction = null;
		pasteAction = null;
		deleteAction = null;
		selectAllAction = null;
		findAction = null;
		quitAction = null;
		quickStartAction = null;
		tipsAndTricksAction = null;
		pinEditorContributionItem = null;
		introAction = null;

		super.dispose( );
	}

	/**
	 * Returns true if the menu with the given ID should be considered as an OLE
	 * container menu. Container menus are preserved in OLE menu merging.
	 */
	public boolean isApplicationMenu( String menuId )
	{
		if ( menuId.equals( IWorkbenchActionConstants.M_FILE ) )
			return true;
		if ( menuId.equals( IWorkbenchActionConstants.M_WINDOW ) )
			return true;
		return false;
	}

	/**
	 * Return whether or not given id matches the id of the coolitems that the
	 * workbench creates.
	 */
	public boolean isWorkbenchCoolItemId( String id )
	{
		if ( IWorkbenchActionConstants.TOOLBAR_FILE.equalsIgnoreCase( id ) )
			return true;
		if ( IWorkbenchActionConstants.TOOLBAR_NAVIGATE.equalsIgnoreCase( id ) )
			return true;
		return false;
	}

	/**
	 * Fills the status line with the workbench contribution items.
	 */
	protected void fillStatusLine( IStatusLineManager statusLine )
	{
		// Do nothing
	}

	/**
	 * Creates actions (and contribution items) for the menu bar, toolbar and
	 * status line.
	 */
	public void makeActions( final IWorkbenchWindow window )
	{
		openFileAction = new OpenFileAction( window );
		register( openFileAction );
		
		newReportAction = new NewReportAction( window );
		register( newReportAction );

		newLibraryAction = new NewLibraryAction( window );
		register( newLibraryAction );
		
		newReportTemplateAction = new NewReportTemplateAction( window );
		register( newReportTemplateAction );

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

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

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

		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 );

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

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

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

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

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

		aboutAction = ActionFactory.ABOUT.create( window );
		aboutAction.setImageDescriptor( PlatformUI.getWorkbench( )
				.getSharedImages( )
				.getImageDescriptor( "IMG_OBJS_DEFAULT_PROD" ) ); //$NON-NLS-1$
		register( aboutAction );

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

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

		makeFeatureDependentActions( window );

		lockToolBarAction = ActionFactory.LOCK_TOOL_BAR.create( window );
		register( lockToolBarAction );

		forwardHistoryAction = ActionFactory.FORWARD_HISTORY.create( window );
		register( forwardHistoryAction );

		backwardHistoryAction = ActionFactory.BACKWARD_HISTORY.create( window );
		register( backwardHistoryAction );

		quitAction = ActionFactory.QUIT.create( window );
		register( quitAction );

		if ( window.getWorkbench( ).getIntroManager( ).hasIntro( ) )
		{
			introAction = ActionFactory.INTRO.create( window );
			register( introAction );
		}

		pinEditorContributionItem = ContributionItemFactory.PIN_EDITOR.create( window );
	}

	/**
	 * Creates the feature-dependent actions for the menu bar.
	 */
	private void makeFeatureDependentActions( IWorkbenchWindow window )
	{
		IPreferenceStore prefs = ReportPlugin.getDefault( )
				.getPreferenceStore( );

		String stateKey = "platformState"; //$NON-NLS-1$
		String prevState = prefs.getString( stateKey );
		String currentState = String.valueOf( Platform.getStateStamp( ) );
		boolean sameState = currentState.equals( prevState );
		if ( !sameState )
		{
			prefs.putValue( stateKey, currentState );
		}
	}
}
