/*=============================================================================#
 # Copyright (c) 2009, 2020 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.ui;

import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.core.databinding.UpdateValueStrategy;
import org.eclipse.core.databinding.observable.Realm;
import org.eclipse.core.databinding.observable.list.WritableList;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.WorkspaceModifyOperation;
import org.eclipse.ui.statushandlers.StatusManager;

import org.eclipse.statet.jcommons.collections.ImList;

import org.eclipse.statet.ecommons.databinding.jface.DataBindingSupport;
import org.eclipse.statet.ecommons.preferences.core.Preference;
import org.eclipse.statet.ecommons.preferences.ui.ConfigurationBlock;
import org.eclipse.statet.ecommons.preferences.ui.ManagedConfigurationBlock;
import org.eclipse.statet.ecommons.preferences.ui.PropertyAndPreferencePage;
import org.eclipse.statet.ecommons.resources.core.ProjectUtils;
import org.eclipse.statet.ecommons.runtime.core.StatusChangeListener;
import org.eclipse.statet.ecommons.ui.util.LayoutUtils;
import org.eclipse.statet.ecommons.ui.util.UIAccess;

import org.eclipse.statet.internal.r.ui.buildpaths.RBuildpathsUIDescription;
import org.eclipse.statet.ltk.buildpaths.core.IBuildpathElement;
import org.eclipse.statet.ltk.buildpaths.ui.SourceContainerComponent;
import org.eclipse.statet.r.core.RBuildpaths;
import org.eclipse.statet.r.core.RProject;
import org.eclipse.statet.r.core.RProjects;
import org.eclipse.statet.r.ui.RUI;


public class RProjectPropertyPage extends PropertyAndPreferencePage {
	
	
	public RProjectPropertyPage() {
	}
	
	
	@Override
	protected String getPreferencePageID() {
		return null;
	}
	
	@Override
	protected String getPropertyPageID() {
		return "org.eclipse.statet.r.propertyPages.RProject"; //$NON-NLS-1$
	}
	
	
	@Override
	protected ConfigurationBlock createConfigurationBlock() throws CoreException {
		return new RProjectConfigurationBlock(getProject(), createStatusChangedListener());
	}
	
	@Override
	protected boolean hasProjectSpecificSettings(final IProject project) {
		return true;
	}
	
}


class RProjectConfigurationBlock extends ManagedConfigurationBlock {
	
	
	private final RProject rProject;
	
	private final RBuildpathsUIDescription buildpathUIDescription;
	private final WritableList buildpathList;
	
	private final SourceContainerComponent sourceFolders;
	
	private boolean isPkg;
	private Label pkgNameLabel;
	private Text pkgNameControl;
	
	private RProjectContainerComposite projectComposite;
	
	private REnvSelectionComposite rEnvControl;
	
	private IResourceChangeListener listener;
	
	
	public RProjectConfigurationBlock(final IProject project, final StatusChangeListener statusListener) {
		super(project, statusListener);
		
		this.rProject= RProjects.getRProject(project);
		
		this.buildpathUIDescription= new RBuildpathsUIDescription();
		this.buildpathList= new WritableList<>();
		this.sourceFolders= new SourceContainerComponent(this.buildpathList,
				RBuildpaths.R_SOURCE_TYPE, null, this.buildpathUIDescription );
		
		this.listener= new IResourceChangeListener() {
			@Override
			public void resourceChanged(final IResourceChangeEvent event) {
				UIAccess.getDisplay().asyncExec(() -> {
					if (UIAccess.isOkToUse(RProjectConfigurationBlock.this.pkgNameControl)) {
						updatePkgName();
					}
				});
			}
		};
		this.rProject.getProject().getWorkspace().addResourceChangeListener(this.listener,
				IResourceChangeEvent.POST_BUILD );
	}
	
	@Override
	public void dispose() {
		if (this.listener != null) {
			this.rProject.getProject().getWorkspace().removeResourceChangeListener(this.listener);
			this.listener= null;
		}
		
		super.dispose();
	}
	
	
	@Override
	protected String getHelpContext() {
		return RUI.BUNDLE_ID + ".r_project-project_properties"; //$NON-NLS-1$
	}
	
	@Override
	protected void createBlockArea(final Composite pageComposite) {
		final Map<Preference<?>, String> prefs= new HashMap<>();
		
		prefs.put(RProject.PKG_BASE_FOLDER_PATH_PREF, null);
		prefs.put(RProject.RENV_CODE_PREF, null);
		
		setupPreferenceManager(prefs);
		
		final Composite mainComposite= new Composite(pageComposite, SWT.NONE);
		mainComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		mainComposite.setLayout(LayoutUtils.newCompositeGrid(2));
		
		final TabFolder folder = new TabFolder(mainComposite, SWT.NONE);
		folder.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
		
		{	final TabItem item = new TabItem(folder, SWT.NONE);
			item.setText("&Main");
			item.setControl(createMainTab(folder));
		}
		{	final TabItem item= new TabItem(folder, SWT.NONE);
			item.setImage(PlatformUI.getWorkbench().getSharedImages().getImage(
					ISharedImages.IMG_OBJ_FOLDER ));
			item.setText("&Source");
			item.setControl(createSourceTab(folder));
		}
		{	final TabItem item= new TabItem(folder, SWT.NONE);
			item.setImage(RUI.getImage(RUI.IMG_OBJ_R_RUNTIME_ENV));
			item.setText("R &Environment");
			item.setControl(createREnvTab(folder));
		}
		
		initBindings();
		updateControls();
	}
	
	private Control createMainTab(final Composite parent) {
		final Composite composite= new Composite(parent, SWT.NONE);
		composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		composite.setLayout(LayoutUtils.newTabGrid(2));
		
		this.projectComposite= new RProjectContainerComposite(composite, getProject());
		this.projectComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		
		final Composite buttons= new Composite(composite, SWT.NONE);
		buttons.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true));
		buttons.setLayout(LayoutUtils.newCompositeGrid(1));
		
		{	final Button button= new Button(buttons, SWT.PUSH);
			button.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
			button.setText("R &Package Root");
			button.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(final SelectionEvent e) {
					RProjectConfigurationBlock.this.projectComposite.togglePkgBaseContainer();
				}
			});
		}
		
		{	final Composite packageComposite= new Composite(composite, SWT.NONE);
			packageComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1));
			packageComposite.setLayout(LayoutUtils.newCompositeGrid(2));
			
			final Label label= new Label(packageComposite, SWT.NONE);
			label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
			label.setText("R Package &Name:");
			this.pkgNameLabel= label;
			
			this.pkgNameControl= new Text(packageComposite, SWT.READ_ONLY);
			this.pkgNameControl.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
			this.pkgNameControl.setFont(JFaceResources.getTextFont());
			this.pkgNameControl.setEditable(false);
		}
		
		return composite;
	}
	
	private Control createSourceTab(final Composite parent) {
		final Composite composite= new Composite(parent, SWT.NONE);
		composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		composite.setLayout(LayoutUtils.newTabGrid(1));
		
		{	final Control control= this.sourceFolders.create(composite);
			control.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		}
		
		return composite;
	}
	
	private Control createREnvTab(final Composite parent) {
		final Composite composite= new Composite(parent, SWT.NONE);
		composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		composite.setLayout(LayoutUtils.newTabGrid(1));
		
		{	final Label label= new Label(composite, SWT.NONE);
			label.setText("R Envir&onment:");
		}
		this.rEnvControl= new REnvSelectionComposite(composite);
		this.rEnvControl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
		
		return composite;
	}
	
	
	@Override
	protected void addBindings(final DataBindingSupport db) {
		db.getContext().bindValue(
				this.rEnvControl.createObservable(Realm.getDefault()),
				createObservable(RProject.RENV_CODE_PREF),
				new UpdateValueStrategy<String, String>()
						.setAfterGetValidator(this.rEnvControl.createValidator(db.getContext())),
				null );
		
		this.sourceFolders.bind(db);
	}
	
	private void updatePkgName() {
		final IPath pkgBasePath= this.rProject.getPkgRootPath();
		if (pkgBasePath != null) {
			String pkgName= this.rProject.getPkgName();
			if (pkgName == null) {
				pkgName= "<missing>";
			}
			this.pkgNameLabel.setEnabled(true);
			this.pkgNameControl.setText(pkgName);
		}
		else {
			this.pkgNameLabel.setEnabled(false);
			this.pkgNameControl.setText(""); //$NON-NLS-1$
		}
	}
	
	@Override
	protected void updateControls() {
		final IPath pkgBasePath= this.rProject.getPkgRootPath();
		if (pkgBasePath != null) {
			this.isPkg= true;
			this.projectComposite.setPkgBaseContainer(pkgBasePath.removeFirstSegments(1));
		}
		else {
			this.isPkg= false;
			this.projectComposite.setPkgBaseContainer(null);
		}
		
		updatePkgName();
		
		{	this.buildpathList.clear();
			this.buildpathUIDescription.toListElements(getProject(), this.rProject.getRawBuildpath(),
					this.buildpathList );
			this.sourceFolders.init(getProject());
		}
		
		super.updateControls();
	}
	
	@Override
	protected void updatePreferences() {
		final IPath pkgBasePath= this.projectComposite.getPkgBaseContainer();
		if (pkgBasePath != null) {
			this.isPkg= true;
			setPrefValue(RProject.PKG_BASE_FOLDER_PATH_PREF, pkgBasePath.toPortableString());
		}
		else {
			this.isPkg= false;
			setPrefValue(RProject.PKG_BASE_FOLDER_PATH_PREF, null);
		}
		
		super.updatePreferences();
	}
	
	@Override
	public boolean performOk(final int flags) {
		final boolean wasPkg= this.isPkg;
		
		saveProjectConfig();
		final boolean ok= super.performOk(flags);
		
		if (ok && wasPkg != this.isPkg) {
			setupRPkg(this.isPkg);
		}
		
		return ok;
	}
	
	private void saveProjectConfig() {
		final ImList<IBuildpathElement> newBuildpath= this.buildpathUIDescription.toCoreElements(this.buildpathList);
		RBuildpaths.set(getProject(), newBuildpath);
	}
	
	private void setupRPkg(final boolean pkg) {
		final WorkspaceModifyOperation op= new WorkspaceModifyOperation() {
			
			@Override
			protected void execute(final IProgressMonitor monitor) throws CoreException,
					InvocationTargetException, InterruptedException {
				final SubMonitor m= SubMonitor.convert(monitor);
				try {
					final IProject project= RProjectConfigurationBlock.this.rProject.getProject();
					if (pkg) {
						RProjects.setupRPkgProject(project, null, m);
					}
					else {
						m.beginTask(
								NLS.bind(RUIMessages.RProject_ConfigureTask_label, project.getName()),
								2 + 8 );
						
						final IProjectDescription description= project.getDescription();
						boolean changed= false;
						changed|= ProjectUtils.removeNature(description, RProjects.R_PKG_NATURE_ID);
						m.worked(2);
						
						if (changed) {
							project.setDescription(description, m.newChild(8));
						}
					}
				}
				finally {
					m.done();
				}
			}
			
		};
		try {
			UIAccess.getActiveWorkbenchWindow(true).run(true, true, op);
		}
		catch (final InvocationTargetException e) {
			StatusManager.getManager().handle(new Status(IStatus.ERROR, RUI.BUNDLE_ID,
					RUIMessages.RPkgProject_ConvertTask_error_message, e.getTargetException() ));
		}
		catch (final InterruptedException e) {
			// cancelled
		}
	}
	
	@Override
	protected String[] getFullBuildDialogStrings(final boolean workspaceSettings) {
		return new String[] {
				RUIMessages.RProject_NeedsBuild_title,
				(workspaceSettings) ?
						RUIMessages.RProject_NeedsBuild_Full_message :
						RUIMessages.RProject_NeedsBuild_Project_message
		};
	}
	
}
