/*******************************************************************************
 * Copyright (c) 2000, 2017 IBM Corporation and others.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 * 
 * SPDX-License-Identifier: EPL-2.0
 *
 *******************************************************************************/
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.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.dltk.core.DLTKCore;
import org.eclipse.dltk.core.IBuildpathEntry;
import org.eclipse.dltk.core.IModelElement;
import org.eclipse.dltk.core.IProjectFragment;
import org.eclipse.dltk.core.IScriptProject;
import org.eclipse.dltk.core.ModelException;
import org.eclipse.dltk.internal.corext.buildpath.BuildpathModifier;
import org.eclipse.dltk.internal.ui.actions.ActionMessages;
import org.eclipse.dltk.internal.ui.wizards.NewWizardMessages;
import org.eclipse.dltk.internal.ui.wizards.buildpath.AddSourceFolderWizard;
import org.eclipse.dltk.internal.ui.wizards.buildpath.BPListElement;
import org.eclipse.dltk.internal.ui.wizards.buildpath.EditFilterWizard;
import org.eclipse.dltk.ui.DLTKPluginImages;
import org.eclipse.dltk.ui.IContextMenuConstants;
import org.eclipse.dltk.ui.actions.AbstractOpenWizardAction;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.INewWizard;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IWorkbenchSite;
import org.eclipse.ui.IWorkingSet;
import org.eclipse.ui.actions.ActionGroup;
import org.eclipse.ui.part.Page;
import org.eclipse.ui.texteditor.IUpdate;

/**
 * Action group that adds the source and generate actions to a part's context
 * menu and installs handlers for the corresponding global menu actions.
 *
 * <p>
 * This class may be instantiated; it is not intended to be subclassed.
 * </p>
 *
 *
 */
public class GenerateBuildPathActionGroup extends ActionGroup {
	/**
	 * Pop-up menu: id of the source sub menu (value
	 * <code>org.eclipse.dltk.ui.buildpath.menu</code>).
	 *
	 *
	 */
	public static final String MENU_ID = "org.eclipse.dltk.ui.buildpath.menu"; //$NON-NLS-1$

	/**
	 * Pop-up menu: id of the build path (add /remove) group of the build path
	 * sub menu (value <code>buildpathGroup</code>).
	 *
	 *
	 */
	public static final String GROUP_BUILDPATH = "buildpathGroup"; //$NON-NLS-1$

	/**
	 * Pop-up menu: id of the filter (include / exclude) group of the build path
	 * sub menu (value <code>filterGroup</code>).
	 *
	 *
	 */
	public static final String GROUP_FILTER = "filterGroup"; //$NON-NLS-1$

	/**
	 * Pop-up menu: id of the customize (filters / output folder) group of the
	 * build path sub menu (value <code>customizeGroup</code>).
	 *
	 *
	 */
	public static final String GROUP_CUSTOMIZE = "customizeGroup"; //$NON-NLS-1$

	private static class NoActionAvailable extends Action {
		public NoActionAvailable() {
			setEnabled(false);
			setText(NewWizardMessages.GenerateBuildPathActionGroup_no_action_available);
		}
	}

	private Action fNoActionAvailable = new NoActionAvailable();

	private static abstract class OpenBuildPathWizardAction extends
			AbstractOpenWizardAction implements ISelectionChangedListener {
		@Override
		public void selectionChanged(SelectionChangedEvent event) {
			ISelection selection = event.getSelection();
			if (selection instanceof IStructuredSelection) {
				setEnabled(selectionChanged((IStructuredSelection) selection));
			} else {
				setEnabled(selectionChanged(StructuredSelection.EMPTY));
			}
		}

		// Needs to be public for the operation, will be protected later.
		public abstract boolean selectionChanged(
				IStructuredSelection selection);
	}

	private abstract static class CreateSourceFolderAction
			extends OpenBuildPathWizardAction {

		private AddSourceFolderWizard fAddSourceFolderWizard;
		private IScriptProject fSelectedProject;
		private final boolean fIsLinked;

		public CreateSourceFolderAction(boolean isLinked) {
			fIsLinked = isLinked;
		}

		@Override
		protected INewWizard createWizard() throws CoreException {
			BPListElement newEntrie = new BPListElement(fSelectedProject,
					IBuildpathEntry.BPE_SOURCE, false);
			BPListElement[] existing = BPListElement
					.createFromExisting(fSelectedProject);
			boolean isProjectSrcFolder = BPListElement
					.isProjectSourceFolder(existing, fSelectedProject);
			fAddSourceFolderWizard = new AddSourceFolderWizard(existing,
					newEntrie, fIsLinked, false, false, isProjectSrcFolder,
					isProjectSrcFolder);
			return fAddSourceFolderWizard;
		}

		@Override
		public boolean selectionChanged(IStructuredSelection selection) {
			if (selection.size() == 1) {
				final Object first = selection.getFirstElement();
				if (first instanceof IScriptProject) {
					fSelectedProject = (IScriptProject) first;
					return true;
				} else if (first instanceof IProject) {
					IScriptProject scriptProject = DLTKCore
							.create((IProject) first);
					if (scriptProject.isValid()) {
						fSelectedProject = scriptProject;
						return true;
					}
				}
			}
			return false;
		}

		public List getBPListElements() {
			return fAddSourceFolderWizard.getExistingEntries();
		}

	}

	public static class CreateLocalSourceFolderAction
			extends CreateSourceFolderAction {

		public CreateLocalSourceFolderAction() {
			super(false);
			setText(ActionMessages.OpenNewSourceFolderWizardAction_text2);
			setDescription(
					ActionMessages.OpenNewSourceFolderWizardAction_description);
			setToolTipText(
					ActionMessages.OpenNewSourceFolderWizardAction_tooltip);
			setImageDescriptor(DLTKPluginImages.DESC_TOOL_NEWPACKROOT);
			if (DLTKCore.DEBUG) {
				System.err.println("Add help support here..."); //$NON-NLS-1$
			}
			// PlatformUI.getWorkbench().getHelpSystem().setHelp(this,
			// IDLTKHelpContextIds.OPEN_SOURCEFOLDER_WIZARD_ACTION);
		}
	}

	public static class CreateLinkedSourceFolderAction
			extends CreateSourceFolderAction {

		public CreateLinkedSourceFolderAction() {
			super(true);
			setText(NewWizardMessages.NewSourceContainerWorkbookPage_ToolBar_Link_label);
			setToolTipText(
					NewWizardMessages.NewSourceContainerWorkbookPage_ToolBar_Link_tooltip);
			setImageDescriptor(
					DLTKPluginImages.DESC_ELCL_ADD_LINKED_SOURCE_TO_BUILDPATH);
			setDescription(
					NewWizardMessages.PackageExplorerActionGroup_FormText_createLinkedFolder);
		}
	}

	public static class EditFilterAction extends OpenBuildPathWizardAction {

		private IScriptProject fSelectedProject;
		private IModelElement fSelectedElement;
		private EditFilterWizard fEditFilterWizard;

		public EditFilterAction() {
			setText(NewWizardMessages.NewSourceContainerWorkbookPage_ToolBar_Edit_label);
			setDescription(
					NewWizardMessages.PackageExplorerActionGroup_FormText_Edit);
			setToolTipText(
					NewWizardMessages.NewSourceContainerWorkbookPage_ToolBar_Edit_tooltip);
			setImageDescriptor(
					DLTKPluginImages.DESC_ELCL_CONFIGURE_BUILDPATH_FILTERS);
			setDisabledImageDescriptor(
					DLTKPluginImages.DESC_DLCL_CONFIGURE_BUILDPATH_FILTERS);
		}

		@Override
		protected INewWizard createWizard() throws CoreException {
			BPListElement[] existingEntries = BPListElement
					.createFromExisting(fSelectedProject);
			BPListElement elementToEdit = findElement(fSelectedElement,
					existingEntries);
			fEditFilterWizard = new EditFilterWizard(existingEntries,
					elementToEdit);
			return fEditFilterWizard;
		}

		@Override
		public boolean selectionChanged(IStructuredSelection selection) {
			if (selection.size() != 1)
				return false;

			try {
				Object element = selection.getFirstElement();
				if (element instanceof IScriptProject) {
					IScriptProject project = (IScriptProject) element;
					if (BuildpathModifier.isSourceFolder(project)) {
						fSelectedProject = project;
						fSelectedElement = (IModelElement) element;
						return true;
					}
				} else if (element instanceof IProject) {
					IScriptProject scriptProject = DLTKCore
							.create((IProject) selection.getFirstElement());
					if (scriptProject.isValid()) {
						if (BuildpathModifier.isSourceFolder(scriptProject)) {
							fSelectedProject = scriptProject;
							fSelectedElement = scriptProject;
							return true;
						}
					}
				} else if (element instanceof IProjectFragment) {
					IProjectFragment ProjectFragment = ((IProjectFragment) element);
					IScriptProject project = ProjectFragment.getScriptProject();
					if (ProjectFragment.getKind() == IProjectFragment.K_SOURCE
							&& project != null
							&& findElement((IModelElement) element,
									BPListElement.createFromExisting(
											project)) != null) {
						fSelectedProject = project;
						fSelectedElement = (IModelElement) element;
						return true;
					}
				}
			} catch (ModelException e) {
				return false;
			}
			return false;
		}

		private static BPListElement findElement(IModelElement element,
				BPListElement[] elements) {
			IPath path = element.getPath();
			for (int i = 0; i < elements.length; i++) {
				BPListElement cur = elements[i];
				if (cur.getEntryKind() == IBuildpathEntry.BPE_SOURCE
						&& cur.getPath().equals(path)) {
					return cur;
				}
			}
			return null;
		}

		public List getBPListElements() {
			return fEditFilterWizard.getExistingEntries();
		}
	}

	private IWorkbenchSite fSite;
	private List<Action> fActions;

	private String fGroupName = IContextMenuConstants.GROUP_REORGANIZE;

	/**
	 * Creates a new <code>GenerateActionGroup</code>. The group requires that
	 * the selection provided by the page's selection provider is of type
	 * <code>org.eclipse.jface.viewers.IStructuredSelection</code>.
	 *
	 * @param page
	 *            the page that owns this action group
	 */
	public GenerateBuildPathActionGroup(Page page) {
		this(page.getSite());
	}

	/**
	 * Creates a new <code>GenerateActionGroup</code>. The group requires that
	 * the selection provided by the part's selection provider is of type
	 * <code>org.eclipse.jface.viewers.IStructuredSelection</code>.
	 *
	 * @param part
	 *            the view part that owns this action group
	 */
	public GenerateBuildPathActionGroup(IViewPart part) {
		this(part.getSite());
	}

	private GenerateBuildPathActionGroup(IWorkbenchSite site) {
		fSite = site;
		fActions = new ArrayList<>();

		final CreateLinkedSourceFolderAction addLinkedSourceFolderAction = new CreateLinkedSourceFolderAction();
		fActions.add(addLinkedSourceFolderAction);

		final CreateLocalSourceFolderAction addSourceFolderAction = new CreateLocalSourceFolderAction();
		fActions.add(addSourceFolderAction);

		final AddFolderToBuildpathAction addFolder = new AddFolderToBuildpathAction(
				site);
		fActions.add(addFolder);

		final AddSelectedLibraryToBuildpathAction addSelectedLibrary = new AddSelectedLibraryToBuildpathAction(
				site);
		fActions.add(addSelectedLibrary);

		final RemoveFromBuildpathAction remove = new RemoveFromBuildpathAction(
				site);
		fActions.add(remove);

		final AddArchiveToBuildpathAction addArchive = new AddArchiveToBuildpathAction(
				site);
		fActions.add(addArchive);

		final AddLibraryToBuildpathAction addLibrary = new AddLibraryToBuildpathAction(
				site);
		fActions.add(addLibrary);

		if (DLTKCore.DEBUG) {
			System.err.println("Add Update Zip Action here..."); //$NON-NLS-1$
		}

		final ExcludeFromBuildpathAction exclude = new ExcludeFromBuildpathAction(
				site);
		fActions.add(exclude);

		final IncludeToBuildpathAction include = new IncludeToBuildpathAction(
				site);
		fActions.add(include);

		final EditFilterAction editFilterAction = new EditFilterAction();
		fActions.add(editFilterAction);

		final ConfigureBuildPathAction configure = new ConfigureBuildPathAction(
				site);
		fActions.add(configure);

		final ISelectionProvider provider = fSite.getSelectionProvider();
		for (Iterator iter = fActions.iterator(); iter.hasNext();) {
			Action action = (Action) iter.next();
			if (action instanceof ISelectionChangedListener) {
				provider.addSelectionChangedListener(
						(ISelectionChangedListener) action);
			}
		}

	}

	@Override
	public void fillActionBars(IActionBars actionBar) {
		super.fillActionBars(actionBar);
		setGlobalActionHandlers(actionBar);
	}

	@Override
	public void fillContextMenu(IMenuManager menu) {
		super.fillContextMenu(menu);
		if (!canOperateOnSelection())
			return;
		String menuText = ActionMessages.BuildPath_label;
		IMenuManager subMenu = new MenuManager(menuText, MENU_ID);
		subMenu.addMenuListener(manager -> fillViewSubMenu(manager));
		subMenu.setRemoveAllWhenShown(true);
		subMenu.add(new ConfigureBuildPathAction(fSite));
		menu.appendToGroup(fGroupName, subMenu);
	}

	private void fillViewSubMenu(IMenuManager source) {
		int added = 0;
		int i = 0;
		for (Iterator<Action> iter = fActions.iterator(); iter.hasNext();) {
			Action action = iter.next();
			if (action instanceof IUpdate)
				((IUpdate) action).update();

			if (i == 2)
				source.add(new Separator(GROUP_BUILDPATH));
			else if (i == 8)
				source.add(new Separator(GROUP_FILTER));
			else if (i == 10)
				source.add(new Separator(GROUP_CUSTOMIZE));
			added += addAction(source, action);
			i++;
		}

		if (added == 0) {
			source.add(fNoActionAvailable);
		}
	}

	private void setGlobalActionHandlers(IActionBars actionBar) {
		// TODO implement
	}

	private int addAction(IMenuManager menu, IAction action) {
		if (action != null && action.isEnabled()) {
			menu.add(action);
			return 1;
		}
		return 0;
	}

	private boolean canOperateOnSelection() {
		ISelection sel = fSite.getSelectionProvider().getSelection();
		if (!(sel instanceof IStructuredSelection))
			return false;
		IStructuredSelection selection = (IStructuredSelection) sel;

		if (selection == null || selection.isEmpty()) {
			return false;
		}

		if (selection.isEmpty()) {
			return false;
		}

		for (Iterator iter = selection.iterator(); iter.hasNext();) {
			Object element = iter.next();

			if (element instanceof IProject) {
				IProject project = (IProject) element;
				if (!project.isAccessible()) {
					return false;
				}
			}

			if (element instanceof IWorkingSet)
				return false;
		}
		return true;
	}

	@Override
	public void dispose() {
		if (fActions != null) {
			final ISelectionProvider provider = fSite.getSelectionProvider();
			for (Iterator<Action> iter = fActions.iterator(); iter.hasNext();) {
				Action action = iter.next();
				if (action instanceof ISelectionChangedListener)
					provider.removeSelectionChangedListener(
							(ISelectionChangedListener) action);
			}
		}
		fActions = null;
		super.dispose();
	}
}
