/*******************************************************************************
 * Copyright (c) 2000, 2018 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<>();
		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;
		}
		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();
	}
}
