/*******************************************************************************
 * Copyright (c) 2000, 2017 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
 *
 *******************************************************************************/
package org.eclipse.dltk.internal.ui.wizards.buildpath.newsourcepage;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.dltk.core.DLTKCore;
import org.eclipse.dltk.core.IModelElement;
import org.eclipse.dltk.core.IProjectFragment;
import org.eclipse.dltk.core.IScriptFolder;
import org.eclipse.dltk.core.IScriptProject;
import org.eclipse.dltk.core.ISourceModule;
import org.eclipse.dltk.core.ModelException;
import org.eclipse.dltk.internal.corext.buildpath.AddSelectedSourceFolderOperation;
import org.eclipse.dltk.internal.corext.buildpath.BuildpathModifier;
import org.eclipse.dltk.internal.corext.buildpath.BuildpathModifier.IBuildpathModifierListener;
import org.eclipse.dltk.internal.corext.buildpath.BuildpathModifierOperation;
import org.eclipse.dltk.internal.corext.buildpath.CreateFolderOperation;
import org.eclipse.dltk.internal.corext.buildpath.EditFiltersOperation;
import org.eclipse.dltk.internal.corext.buildpath.ExcludeOperation;
import org.eclipse.dltk.internal.corext.buildpath.IBuildpathInformationProvider;
import org.eclipse.dltk.internal.corext.buildpath.IPackageExplorerActionListener;
import org.eclipse.dltk.internal.corext.buildpath.LinkedSourceFolderOperation;
import org.eclipse.dltk.internal.corext.buildpath.PackageExplorerActionEvent;
import org.eclipse.dltk.internal.corext.buildpath.RemoveFromBuildpathOperation;
import org.eclipse.dltk.internal.corext.buildpath.ResetAllOperation;
import org.eclipse.dltk.internal.corext.buildpath.UnexcludeOperation;
import org.eclipse.dltk.internal.ui.actions.CompositeActionGroup;
import org.eclipse.dltk.internal.ui.scriptview.BuildPathContainer;
import org.eclipse.dltk.internal.ui.util.ViewerPane;
import org.eclipse.dltk.internal.ui.wizards.NewWizardMessages;
import org.eclipse.dltk.ui.DLTKPluginImages;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.ui.actions.ActionContext;

/**
 * Action group for the package explorer. Creates and manages a set of
 * <code>BuildpathModifierOperation</code>s and creates a
 * <code>ToolBarManager</code> on request. Based on this operations,
 * <code>BuildpathModifierAction</code>s are generated. The available operations
 * are:
 *
 * @see org.eclipse.dltk.internal.corext.buildpath.AddSelectedSourceFolderOperation
 * @see org.eclipse.dltk.internal.corext.buildpath.RemoveFromBuildpathOperation
 * @see org.eclipse.dltk.internal.corext.buildpath.IncludeOperation
 * @see org.eclipse.dltk.internal.corext.buildpath.UnincludeOperation
 * @see org.eclipse.dltk.internal.corext.buildpath.ExcludeOperation
 * @see org.eclipse.dltk.internal.corext.buildpath.UnexcludeOperation
 * @see org.eclipse.dltk.internal.corext.buildpath.EditFiltersOperation
 * @see org.eclipse.dltk.internal.corext.buildpath.ResetOperation
 */
public class DialogPackageExplorerActionGroup extends CompositeActionGroup {

	public static class DialogExplorerActionContext extends ActionContext {
		private IScriptProject fScriptProject;
		private List fSelectedElements;

		/**
		 * Constructor to create an action context for the dialog package
		 * explorer.
		 *
		 * For reasons of completeness, the selection of the super class
		 * <code>ActionContext</code> is also set, but is not intendet to be
		 * used.
		 *
		 * @param selection
		 *            the current selection
		 * @param jProject
		 *            the element's script project
		 */
		public DialogExplorerActionContext(ISelection selection,
				IScriptProject jProject) {
			super(null);
			fScriptProject = jProject;
			fSelectedElements = ((IStructuredSelection) selection).toList();
			IStructuredSelection structuredSelection = new StructuredSelection(
					new Object[] { fSelectedElements, jProject });
			super.setSelection(structuredSelection);
		}

		/**
		 * Constructor to create an action context for the dialog package
		 * explorer.
		 *
		 * For reasons of completeness, the selection of the super class
		 * <code>ActionContext</code> is also set, but is not intendet to be
		 * used.
		 *
		 * @param selectedElements
		 *            a list of currently selected elements
		 * @param jProject
		 *            the element's script project
		 */
		public DialogExplorerActionContext(List selectedElements,
				IScriptProject jProject) {
			super(null);
			fScriptProject = jProject;
			fSelectedElements = selectedElements;
			IStructuredSelection structuredSelection = new StructuredSelection(
					new Object[] { fSelectedElements, jProject });
			super.setSelection(structuredSelection);
		}

		public IScriptProject getScriptProject() {
			return fScriptProject;
		}

		public List getSelectedElements() {
			return fSelectedElements;
		}
	}

	/** script project */
	public static final int SCRIPT_PROJECT = 0x01;
	/** Package fragment root */
	public static final int PACKAGE_FRAGMENT_ROOT = 0x02;
	/** Package fragment */
	public static final int PACKAGE_FRAGMENT = 0x03;
	/** Compilation unit */
	public static final int SOURCE_MODULE = 0x04;
	/** File */
	public static final int FILE = 0x05;
	/** Normal folder */
	public static final int FOLDER = 0x06;
	/** Excluded folder */
	public static final int EXCLUDED_FOLDER = 0x07;
	/** Excluded file */
	public static final int EXCLUDED_FILE = 0x08;
	/** Included file */
	public static final int INCLUDED_FILE = 0xA;
	/** Included folder */
	public static final int INCLUDED_FOLDER = 0xB;
	/** An archive element */
	public static final int ARCHIVE = 0xD;
	/** A IProjectFragment with include/exclude filters set */
	public static final int MODIFIED_FRAGMENT_ROOT = 0xE;
	/** Default package fragment */
	public static final int DEFAULT_FRAGMENT = 0xF;
	/** Undefined type */
	public static final int UNDEFINED = 0x10;
	/** Multi selection */
	public static final int MULTI = 0x11;
	/** No elements selected */
	public static final int NULL_SELECTION = 0x12;
	/** Elements that are contained in an archive */
	public static final int ARCHIVE_RESOURCE = 0x13;

	public static final int EXTERNAL_RESOURCE = 0x15;
	/** Elements that represent Buildpath container (= libraries) */
	public static final int CONTAINER = 0x14;

	private BuildpathModifierAction[] fActions;
	private int fLastType;
	private List fListeners;
	private static final int fContextSensitiveActions = 5;

	/**
	 * Constructor which creates the operations and based on this operations the
	 * actions.
	 *
	 * @param provider
	 *            a information provider to pass necessary information to the
	 *            operations
	 * @param listener
	 *            a listener for the changes on Buildpath entries, that is the
	 *            listener will be notified whenever a Buildpath entry changed.
	 * @see IBuildpathModifierListener
	 */
	public DialogPackageExplorerActionGroup(
			IBuildpathInformationProvider provider,
			IBuildpathModifierListener listener) {
		super();
		fLastType = UNDEFINED;
		fListeners = new ArrayList();
		fActions = new BuildpathModifierAction[8];
		BuildpathModifierOperation op;
		op = new AddSelectedSourceFolderOperation(listener, provider);
		// TODO User disabled image when available
		addAction(new BuildpathModifierAction(op,
				DLTKPluginImages.DESC_ELCL_ADD_AS_SOURCE_FOLDER, null,
				NewWizardMessages.NewSourceContainerWorkbookPage_ToolBar_AddSelSFToCP_label,
				NewWizardMessages.NewSourceContainerWorkbookPage_ToolBar_AddSelSFToCP_tooltip,
				IAction.AS_PUSH_BUTTON), 0);
		op = new RemoveFromBuildpathOperation(listener, provider);
		addAction(new BuildpathModifierAction(op,
				DLTKPluginImages.DESC_ELCL_REMOVE_AS_SOURCE_FOLDER,
				DLTKPluginImages.DESC_DLCL_REMOVE_AS_SOURCE_FOLDER,
				NewWizardMessages.NewSourceContainerWorkbookPage_ToolBar_RemoveFromCP_label,
				NewWizardMessages.NewSourceContainerWorkbookPage_ToolBar_RemoveFromCP_tooltip,
				IAction.AS_PUSH_BUTTON), 1);
		op = new ExcludeOperation(listener, provider);
		addAction(new BuildpathModifierAction(op,
				DLTKPluginImages.DESC_ELCL_EXCLUDE_FROM_BUILDPATH,
				DLTKPluginImages.DESC_DLCL_EXCLUDE_FROM_BUILDPATH,
				NewWizardMessages.NewSourceContainerWorkbookPage_ToolBar_Exclude_label,
				NewWizardMessages.NewSourceContainerWorkbookPage_ToolBar_Exclude_tooltip,
				IAction.AS_PUSH_BUTTON), 2);
		op = new UnexcludeOperation(listener, provider);
		addAction(new BuildpathModifierAction(op,
				DLTKPluginImages.DESC_ELCL_INCLUDE_ON_BUILDPATH,
				DLTKPluginImages.DESC_DLCL_INCLUDE_ON_BUILDPATH,
				NewWizardMessages.NewSourceContainerWorkbookPage_ToolBar_Unexclude_label,
				NewWizardMessages.NewSourceContainerWorkbookPage_ToolBar_Unexclude_tooltip,
				IAction.AS_PUSH_BUTTON), 3);
		op = new EditFiltersOperation(listener, provider);
		BuildpathModifierAction action = new BuildpathModifierAction(op,
				DLTKPluginImages.DESC_ELCL_CONFIGURE_BUILDPATH_FILTERS,
				DLTKPluginImages.DESC_DLCL_CONFIGURE_BUILDPATH_FILTERS,
				NewWizardMessages.NewSourceContainerWorkbookPage_ToolBar_Edit_label,
				NewWizardMessages.NewSourceContainerWorkbookPage_ToolBar_Edit_tooltip,
				IAction.AS_PUSH_BUTTON);
		BuildpathModifierDropDownAction dropDown = new BuildpathModifierDropDownAction(
				action,
				NewWizardMessages.NewSourceContainerWorkbookPage_ToolBar_Configure_label,
				NewWizardMessages.NewSourceContainerWorkbookPage_ToolBar_Configure_tooltip);
		addAction(dropDown, 4);

		/*
		 * addAction(new BuildpathModifierAction(op,
		 * DLTKPluginImages.DESC_OBJS_TEXT_EDIT,
		 * DLTKPluginImages.DESC_DLCL_TEXT_EDIT, NewWizardMessages.getString(
		 * "NewSourceContainerWorkbookPage.ToolBar.Edit.label"), //$NON-NLS-1$
		 * NewWizardMessages.getString(
		 * "NewSourceContainerWorkbookPage.ToolBar.Edit.tooltip"),
		 * IAction.AS_PUSH_BUTTON), //$NON-NLS-1$
		 * IBuildpathInformationProvider.EDIT);
		 */
		op = new LinkedSourceFolderOperation(listener, provider);
		addAction(new BuildpathModifierAction(op,
				DLTKPluginImages.DESC_ELCL_ADD_LINKED_SOURCE_TO_BUILDPATH,
				DLTKPluginImages.DESC_DLCL_ADD_LINKED_SOURCE_TO_BUILDPATH,
				NewWizardMessages.NewSourceContainerWorkbookPage_ToolBar_Link_label,
				NewWizardMessages.NewSourceContainerWorkbookPage_ToolBar_Link_tooltip,
				IAction.AS_PUSH_BUTTON), 5);
		op = new CreateFolderOperation(listener, provider);
		addAction(new BuildpathModifierAction(op,
				DLTKPluginImages.DESC_OBJS_PACKFRAG_ROOT, null,
				NewWizardMessages.NewSourceContainerWorkbookPage_ToolBar_CreateSrcFolder_label,
				NewWizardMessages.NewSourceContainerWorkbookPage_ToolBar_CreateSrcFolder_tooltip,
				IAction.AS_PUSH_BUTTON), 6);
		op = new ResetAllOperation(listener, provider);
		addAction(new BuildpathModifierAction(op,
				DLTKPluginImages.DESC_ELCL_CLEAR,
				DLTKPluginImages.DESC_DLCL_CLEAR,
				NewWizardMessages.NewSourceContainerWorkbookPage_ToolBar_ClearAll_label,
				NewWizardMessages.NewSourceContainerWorkbookPage_ToolBar_ClearAll_tooltip,
				IAction.AS_PUSH_BUTTON), 7);
	}

	private void addAction(BuildpathModifierAction action, int index) {
		fActions[index] = action;
	}

	/**
	 * Get an action of the specified type
	 *
	 * @param type
	 *            the type of the desired action, must be a constante of
	 *            <code>IBuildpathInformationProvider</code>
	 * @return the requested action
	 *
	 * @see IBuildpathInformationProvider
	 */
	public BuildpathModifierAction getAction(int type) {
		for (int i = 0; i < fActions.length; i++) {
			if (fActions[i].getOperation().getTypeId() == type)
				return fActions[i];
		}
		throw new ArrayIndexOutOfBoundsException();
	}

	public BuildpathModifierAction[] getActions() {
		List<BuildpathModifierAction> result = new ArrayList<BuildpathModifierAction>();
		for (int i = 0; i < fActions.length; i++) {
			BuildpathModifierAction action = fActions[i];
			if (action instanceof BuildpathModifierDropDownAction) {
				BuildpathModifierDropDownAction dropDownAction = (BuildpathModifierDropDownAction) action;
				BuildpathModifierAction[] actions = dropDownAction.getActions();
				for (int j = 0; j < actions.length; j++) {
					result.add(actions[j]);
				}
			} else {
				result.add(action);
			}
		}
		return result.toArray(new BuildpathModifierAction[result.size()]);
	}

	/**
	 * Create a toolbar manager for a given <code>ViewerPane</code>
	 *
	 * @param pane
	 *            the pane to create the <code>
	 * ToolBarManager</code> for.
	 * @return the created <code>ToolBarManager</code>
	 */
	public ToolBarManager createLeftToolBarManager(ViewerPane pane) {
		ToolBarManager tbm = pane.getToolBarManager();
		for (int i = 0; i < fContextSensitiveActions; i++) {
			tbm.add(fActions[i]);
			if (i == 1 || i == 3)
				tbm.add(new Separator());
		}
		tbm.update(true);
		return tbm;
	}

	/**
	 * Create a toolbar manager for a given <code>ViewerPane</code>
	 *
	 * @param pane
	 *            the pane to create the help toolbar for
	 * @return the created <code>ToolBarManager</code>
	 */
	public ToolBarManager createLeftToolBar(ViewerPane pane) {
		ToolBar tb = new ToolBar(pane, SWT.FLAT);
		pane.setTopRight(tb);
		ToolBarManager tbm = new ToolBarManager(tb);
		for (int i = fContextSensitiveActions; i < fActions.length; i++) {
			tbm.add(fActions[i]);
		}
		if (DLTKCore.DEBUG) {
			System.err.println("Add help support here..."); //$NON-NLS-1$
		}
		// tbm.add(new HelpAction());
		tbm.update(true);
		return tbm;
	}

	/**
	 * Forces the action group to recompute the available actions and fire an
	 * event to all listeners
	 * 
	 * @throws ModelException
	 *
	 * @see #setContext(DialogExplorerActionContext)
	 * @see #informListeners(String[], BuildpathModifierAction[])
	 */
	public void refresh(DialogExplorerActionContext context)
			throws ModelException {
		super.setContext(context);
		if (context == null) // can happen when disposing
			return;
		List selectedElements = context.getSelectedElements();
		IScriptProject project = context.getScriptProject();

		int type = MULTI;
		if (selectedElements.size() == 0) {
			type = NULL_SELECTION;

			if (type == fLastType)
				return;
		} else if (selectedElements.size() == 1
				|| identicalTypes(selectedElements, project)) {
			type = getType(selectedElements.get(0), project);
		}

		internalSetContext(selectedElements, project, type);
	}

	/**
	 * Set the context for the action group. This also includes updating the
	 * actions (that is, enable or disable them). The decision which actions
	 * should be enabled or disabled is based on the content of the
	 * <code>DialogExplorerActionContext</code>
	 *
	 * If the type of the selection changes, then listeners will be notified
	 * about the new set of available actions.
	 *
	 * Note: notification is only done if the TYPE changes (not the selected
	 * object as such). This means that if elements of the same type are
	 * selected (for example two times a folder), NO notification will take
	 * place. There might be situations where the type of two objects is the
	 * same but the set of available actions is not. However, if clients decide
	 * that upon some action a recomputation of the available actions has to be
	 * forced, then
	 * <code>PackageExplorerActionGroup.refresh(DialogExplorerActionContext)</code>
	 * can be called.
	 *
	 * @param context
	 *            the action context
	 *
	 * @see IPackageExplorerActionListener
	 * @see PackageExplorerActionEvent
	 * @see DialogExplorerActionContext
	 * @see #addListener(IPackageExplorerActionListener)
	 * @see #refresh(DialogExplorerActionContext)
	 *
	 * @throws ModelException
	 *             if there is a failure while computing the available actions.
	 */
	public void setContext(DialogExplorerActionContext context)
			throws ModelException {
		super.setContext(context);
		if (context == null) // can happen when disposing
			return;
		List selectedElements = context.getSelectedElements();
		IScriptProject project = context.getScriptProject();

		int type = MULTI;
		if (selectedElements.size() == 0) {
			type = NULL_SELECTION;

			if (type == fLastType)
				return;
		} else if (selectedElements.size() == 1
				|| identicalTypes(selectedElements, project)) {
			type = getType(selectedElements.get(0), project);

			if (selectedElements.size() > 1)
				type = type | MULTI;

			if (type == fLastType)
				return;
		}

		internalSetContext(selectedElements, project, type);
	}

	/**
	 * Get a description for the last selection explaining why no operation is
	 * possible.
	 * <p>
	 * This can be usefull if a context sensitive widget does not want to
	 * display all operations although some of them are valid.
	 *
	 * @return a description for the last selection that explains why no
	 *         operation is available.
	 */
	public String getNoActionDescription() {
		String[] description = noAction(fLastType);
		return description[0];
	}

	/**
	 * Internal method to set the context of the action group.
	 *
	 * @param selectedElements
	 *            a list of selected elements, can be empty
	 * @param project
	 *            the script project
	 * @param type
	 *            the type of the selected element(s)
	 * @throws ModelException
	 */
	private void internalSetContext(List selectedElements,
			IScriptProject project, int type) throws ModelException {
		fLastType = type;
		List availableActions = getAvailableActions(selectedElements, project);
		BuildpathModifierAction[] actions = new BuildpathModifierAction[availableActions
				.size()];
		String[] descriptions = new String[availableActions.size()];
		if (availableActions.size() > 0) {
			for (int i = 0; i < availableActions.size(); i++) {
				BuildpathModifierAction action = (BuildpathModifierAction) availableActions
						.get(i);
				actions[i] = action;
				descriptions[i] = action.getDescription(type);
			}
		} else
			descriptions = noAction(type);

		informListeners(descriptions, actions);
	}

	/**
	 * Finds out wheter the list of elements consists only of elements having
	 * the same type (for example all are of type
	 * DialogPackageExplorerActionGroup.COMPILATION_UNIT). This allows to use a
	 * description for the available actions which is more specific and
	 * therefore provides more information.
	 *
	 * @param elements
	 *            a list of elements to be compared to each other
	 * @param project
	 *            the script project
	 * @return <code>true</code> if all elements are of the same type,
	 *         <code>false</code> otherwise.
	 * @throws ModelException
	 */
	private boolean identicalTypes(List elements, IScriptProject project)
			throws ModelException {
		if (elements.size() == 0) {
			return false;
		}

		Object firstElement = elements.get(0);
		int firstType = getType(firstElement, project);
		for (int i = 1; i < elements.size(); i++) {
			if (firstType != getType(elements.get(i), project))
				return false;
		}
		return true;
	}

	/**
	 * Inform all listeners about new actions.
	 *
	 * @param descriptions
	 *            an array of descriptions for each actions, where the
	 *            description at position 'i' belongs to the action at position
	 *            'i'
	 * @param actions
	 *            an array of available actions
	 */
	private void informListeners(String[] descriptions,
			BuildpathModifierAction[] actions) {
		Iterator iterator = fListeners.iterator();
		PackageExplorerActionEvent event = new PackageExplorerActionEvent(
				descriptions, actions);
		while (iterator.hasNext()) {
			IPackageExplorerActionListener listener = (IPackageExplorerActionListener) iterator
					.next();
			listener.handlePackageExplorerActionEvent(event);
		}
	}

	/**
	 * Returns string array with only one element which contains a short reason
	 * to indicate why there are no actions available.
	 *
	 * @return a description to explain why there are no actions available
	 */
	private String[] noAction(int type) {
		String reason;
		switch (type) {
		case FILE:
			reason = NewWizardMessages.PackageExplorerActionGroup_NoAction_File;
			break;
		case FILE | MULTI:
			reason = NewWizardMessages.PackageExplorerActionGroup_NoAction_File;
			break;
		case DEFAULT_FRAGMENT:
			reason = NewWizardMessages.PackageExplorerActionGroup_NoAction_DefaultPackage;
			break;
		case DEFAULT_FRAGMENT | MULTI:
			reason = NewWizardMessages.PackageExplorerActionGroup_NoAction_DefaultPackage;
			break;
		case NULL_SELECTION:
			reason = NewWizardMessages.PackageExplorerActionGroup_NoAction_NullSelection;
			break;
		case MULTI:
			reason = NewWizardMessages.PackageExplorerActionGroup_NoAction_MultiSelection;
			break;
		case ARCHIVE_RESOURCE:
			reason = NewWizardMessages.PackageExplorerActionGroup_NoAction_ArchiveResource;
			break;
		default:
			reason = NewWizardMessages.PackageExplorerActionGroup_NoAction_NoReason;
		}
		return new String[] { reason };
	}

	/**
	 * Computes the type based on the current selection. The type can be usefull
	 * to set the content of the hint text group properly.
	 *
	 * @param obj
	 *            the object to get the type from
	 * @return the type of the current selection or UNDEFINED if no appropriate
	 *         type could be found. Possible types are:<br>
	 *         PackageExplorerActionGroup.FOLDER<br>
	 *         PackageExplorerActionGroup.EXCLUDED_FOLDER;<br>
	 *         PackageExplorerActionGroup.EXCLUDED_FILE<br>
	 *         PackageExplorerActionGroup.DEFAULT_OUTPUT<br>
	 *         PackageExplorerActionGroup.INCLUDED_FILE<br>
	 *         PackageExplorerActionGroup.INCLUDED_FOLDER<br>
	 *         PackageExplorerActionGroup.OUTPUT<br>
	 *         PackageExplorerActionGroup.MODIFIED_FRAGMENT_ROOT<br>
	 *         PackageExplorerActionGroup.DEFAULT_FRAGMENT<br>
	 *         PackageExplorerActionGroup.JAVA_PROJECT<br>
	 *         PackageExplorerActionGroup.PACKAGE_FRAGMENT_ROOT<br>
	 *         PackageExplorerActionGroup.PACKAGE_FRAGMENT<br>
	 *         PackageExplorerActionGroup.COMPILATION_UNIT<br>
	 *         PackageExplorerActionGroup.FILE<br>
	 * @throws ModelException
	 */
	public static int getType(Object obj, IScriptProject project)
			throws ModelException {
		if (obj instanceof IScriptProject)
			return SCRIPT_PROJECT;
		if (obj instanceof BuildPathContainer)
			return CONTAINER;
		if (obj instanceof IProjectFragment)
			return BuildpathModifier.filtersSet((IProjectFragment) obj)
					? MODIFIED_FRAGMENT_ROOT
					: PACKAGE_FRAGMENT_ROOT;
		if (obj instanceof IScriptFolder) {
			if (BuildpathModifier.isDefaultFragment((IScriptFolder) obj)) {
				if (((IProjectFragment) ((IModelElement) obj)
						.getAncestor(IModelElement.PROJECT_FRAGMENT))
								.isArchive())
					return ARCHIVE_RESOURCE;
				return DEFAULT_FRAGMENT;
			}
			if (BuildpathModifier.isIncluded((IModelElement) obj, project,
					null))
				return INCLUDED_FOLDER;
			if (((IProjectFragment) ((IModelElement) obj)
					.getAncestor(IModelElement.PROJECT_FRAGMENT)).isArchive())
				return ARCHIVE_RESOURCE;
			if (((IProjectFragment) ((IModelElement) obj)
					.getAncestor(IModelElement.PROJECT_FRAGMENT)).isExternal())
				return EXTERNAL_RESOURCE;
			return PACKAGE_FRAGMENT;
		}
		if (obj instanceof ISourceModule) {
			if (((IProjectFragment) ((IModelElement) obj)
					.getAncestor(IModelElement.PROJECT_FRAGMENT)).isArchive()) {
				return ARCHIVE_RESOURCE;
			}
			if (((IProjectFragment) ((IModelElement) obj)
					.getAncestor(IModelElement.PROJECT_FRAGMENT))
							.isExternal()) {
				return EXTERNAL_RESOURCE;
			}
			return BuildpathModifier.isIncluded((IModelElement) obj, project,
					null) ? INCLUDED_FILE : SOURCE_MODULE;
		}
		if (obj instanceof IFolder) {
			return getFolderType((IFolder) obj, project);
		}
		if (obj instanceof IFile)
			return getFileType((IFile) obj, project);
		return UNDEFINED;
	}

	/**
	 * Get the type of the folder
	 *
	 * @param folder
	 *            folder to get the type from
	 * @return the type code for the folder. Possible types are:<br>
	 *         PackageExplorerActionGroup.FOLDER<br>
	 *         PackageExplorerActionGroup.EXCLUDED_FOLDER;<br>
	 * @throws ModelException
	 */
	private static int getFolderType(IFolder folder, IScriptProject project)
			throws ModelException {
		IContainer folderParent = folder.getParent();
		if (folderParent.getFullPath().equals(project.getPath()))
			return FOLDER;
		if (BuildpathModifier.getFragment(folderParent) != null)
			return EXCLUDED_FOLDER;
		IProjectFragment fragmentRoot = BuildpathModifier
				.getFragmentRoot(folder, project, null);
		if (fragmentRoot == null)
			return FOLDER;
		if (fragmentRoot.equals(DLTKCore.create(folderParent)))
			return EXCLUDED_FOLDER;
		return FOLDER;
	}

	/**
	 * Get the type of the file
	 *
	 * @param file
	 *            file to get the type from
	 * @return the type code for the file. Possible types are:<br>
	 *         PackageExplorerActionGroup.EXCLUDED_FILE<br>
	 *         PackageExplorerActionGroup.FILE
	 * @throws ModelException
	 */
	private static int getFileType(IFile file, IScriptProject project)
			throws ModelException {
		if (BuildpathModifier.isArchive(file, project))
			return ARCHIVE;
		if (DLTKCore.DEBUG) {
			System.err.println(
					"DialogPackageExplorerActionGroup:: Add some filters here"); //$NON-NLS-1$
		}
		// if (!DLTKCore.isScriptLikeFileName(file.getName()))
		// return FILE;
		IContainer fileParent = file.getParent();
		if (fileParent.getFullPath().equals(project.getPath())) {
			if (project.isOnBuildpath(project))
				return EXCLUDED_FILE;
			return FILE;
		}
		IProjectFragment fragmentRoot = BuildpathModifier.getFragmentRoot(file,
				project, null);
		if (fragmentRoot == null)
			return FILE;
		if (fragmentRoot.isArchive())
			return ARCHIVE_RESOURCE;
		if (fragmentRoot.equals(DLTKCore.create(fileParent)))
			return EXCLUDED_FILE;
		if (BuildpathModifier.getFragment(fileParent) == null) {
			if (BuildpathModifier.parentExcluded(fileParent, project))
				return FILE;
			return EXCLUDED_FILE;
		}
		return EXCLUDED_FILE;
	}

	/**
	 * Based on the given list of elements, get the list of available actions
	 * that can be applied on this elements
	 *
	 * @param selectedElements
	 *            the list of elements to get the actions for
	 * @param project
	 *            the script project
	 * @return a list of <code>BuildpathModifierAction</code>s
	 * @throws ModelException
	 */
	private List getAvailableActions(List selectedElements,
			IScriptProject project) throws ModelException {
		if (project == null || !project.exists()) {
			return new ArrayList();
		}

		List actions = new ArrayList();
		int[] types = new int[selectedElements.size()];
		for (int i = 0; i < types.length; i++) {
			types[i] = getType(selectedElements.get(i), project);
		}
		for (int i = 0; i < fActions.length; i++) {
			if (fActions[i] instanceof BuildpathModifierDropDownAction) {
				if (changeEnableState(fActions[i], selectedElements, types)) {
					BuildpathModifierAction[] dropDownActions = ((BuildpathModifierDropDownAction) fActions[i])
							.getActions();
					for (int j = 0; j < dropDownActions.length; j++) {
						if (changeEnableState(dropDownActions[j],
								selectedElements, types))
							actions.add(dropDownActions[j]);
					}
				}
			} else if (changeEnableState(fActions[i], selectedElements,
					types)) {
				actions.add(fActions[i]);
			}
		}
		return actions;
	}

	/**
	 * Changes the enabled state of an action if necessary.
	 *
	 * @param action
	 *            the action to change it's state for
	 * @param selectedElements
	 *            a list of selected elements
	 * @param types
	 *            an array of types corresponding to the types of the selected
	 *            elements
	 * @return <code>true</code> if the action is valid (= enabled),
	 *         <code>false</code> otherwise
	 * @throws ModelException
	 */
	private boolean changeEnableState(BuildpathModifierAction action,
			List selectedElements, int[] types) throws ModelException {
		if (action.isValid(selectedElements, types)) {
			if (!action.isEnabled())
				action.setEnabled(true);
			return true;
		} else {
			if (action.isEnabled())
				action.setEnabled(false);
			return false;
		}
	}

	/**
	 * Fill the context menu with the available actions
	 *
	 * @param menu
	 *            the menu to be filled up with actions
	 */
	@Override
	public void fillContextMenu(IMenuManager menu) {
		for (int i = 0; i < fContextSensitiveActions; i++) {
			IAction action = getAction(i);
			if (action instanceof BuildpathModifierDropDownAction) {
				if (action.isEnabled()) {
					IAction[] actions = ((BuildpathModifierDropDownAction) action)
							.getActions();
					for (int j = 0; j < actions.length; j++) {
						if (actions[j].isEnabled())
							menu.add(actions[j]);
					}
				}
			} else if (action.isEnabled())
				menu.add(action);
		}
		super.fillContextMenu(menu);
	}

	/**
	 * Add listeners for the <code>PackageExplorerActionEvent</code>.
	 *
	 * @param listener
	 *            the listener to be added
	 *
	 * @see PackageExplorerActionEvent
	 * @see IPackageExplorerActionListener
	 */
	public void addListener(IPackageExplorerActionListener listener) {
		fListeners.add(listener);
	}

	/**
	 * Remove the listener from the list of registered listeners.
	 *
	 * @param listener
	 *            the listener to be removed
	 */
	public void removeListener(IPackageExplorerActionListener listener) {
		fListeners.remove(listener);
	}

	@Override
	public void dispose() {
		fListeners.clear();
		super.dispose();
	}
}
