/*=============================================================================#
 # Copyright (c) 2010, 2019 Stephan Wahlbrink and others.
 # 
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License 2.0 which is available at
 # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
 # which is available at https://www.apache.org/licenses/LICENSE-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 # 
 # Contributors:
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.internal.r.debug.ui.sourcelookup;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.sourcelookup.ISourceContainer;
import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector;
import org.eclipse.debug.ui.sourcelookup.AbstractSourceContainerBrowser;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.swt.widgets.Shell;

import org.eclipse.statet.internal.r.debug.ui.ProjectSelectionDialog;
import org.eclipse.statet.r.core.RProjects;
import org.eclipse.statet.r.debug.core.sourcelookup.RProjectSourceContainer;


public class RProjectSourceContainerBrowser extends AbstractSourceContainerBrowser {
	
	
	/** Created via extension point */
	public RProjectSourceContainerBrowser() {
	}
	
	
	@Override
	public ISourceContainer[] addSourceContainers(final Shell shell,
			final ISourceLookupDirector director) {
		final List<IProject> projects= getPossibleAdditions(director);
		final ProjectSelectionDialog dialog= new ProjectSelectionDialog(shell, projects);
		if (dialog.open() == Dialog.OK) {
			final Set<?> selectedProjects= dialog.getCheckedElements();
			final List<ISourceContainer> containers= new ArrayList<>();
			for (final IProject project : projects) {
				if (selectedProjects.contains(project)) {
					final RProjectSourceContainer container= new RProjectSourceContainer(project, false);
					container.init(director);
					containers.add(container);
				}
			}
			return containers.toArray(new ISourceContainer[containers.size()]);
		}
		return new ISourceContainer[0];
	}
	
	protected List<IProject> getPossibleAdditions(final ISourceLookupDirector director) {
		final List<IProject> projects= getRResourceProjects();
		final ISourceContainer[] containers= director.getSourceContainers();
		for (final ISourceContainer container : containers) {
			if (container.getType().getId().equals(RProjectSourceContainer.TYPE_ID)) {
				projects.remove(((RProjectSourceContainer) container).getProject());
			}
		}
		return projects;
	}
	
	protected List<IProject> getRResourceProjects() {
		final IProject[] projects= ResourcesPlugin.getWorkspace().getRoot().getProjects();
		final List<IProject> collected= new ArrayList<>();
		for (final IProject project : projects) {
			try {
				if (project.hasNature(RProjects.R_NATURE_ID)) {
					collected.add(project);
				}
			}
			catch (final CoreException e) {
			}
		}
		return collected;
	}
	
}
