/*=============================================================================#
 # Copyright (c) 2017, 2021 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.ecommons.ui.workbench.workspace;

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

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.dialogs.SelectionStatusDialog;

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


public abstract class AbstractResourceSelectionDialog<TResource extends IResource> extends SelectionStatusDialog {
	
	
	public static IResource findExistingResource(final IPath path, final IContainer base) {
		IResource initialElement= null;
		if (path != null) {
			IContainer container= base;
			final int nSegments= path.segmentCount();
			for (int i= 0; i < nSegments; i++) {
				final IResource elem= container.findMember(path.segment(i));
				if (elem != null) {
					initialElement= elem;
				}
				if (elem instanceof IContainer) {
					container= (IContainer) elem;
				}
				else {
					break;
				}
			}
		}
		return initialElement;
	}
	
	
	/* the root element to populate the viewer with */
	private IContainer rootContainer;
	
	private boolean allowNew;
	
	private TResource selectedResource;
	
	private Text textField;
	private boolean ignoreTextFieldModifications= false;
	
	
	public AbstractResourceSelectionDialog(final Shell parent) {
		super(parent);
		
		setHelpAvailable(false);
		setShellStyle(getShellStyle() | SWT.RESIZE);
	}
	
	
	protected abstract String getDefaultMessage();
	
	protected abstract int getResourceTypes();
	
	
	public void setRootElement(final IContainer container) {
		this.rootContainer= container;
	}
	
	protected IContainer getRootElement() {
		return this.rootContainer;
	}
	
	public void setAllowNewResources(final boolean allowNew) {
		this.allowNew= allowNew;
	}
	
	protected boolean isAllowNewResources() {
		return this.allowNew;
	}
	
	public void setInitialElementSelection(final IResource resource) {
		setInitialElementSelections((resource != null) ? ImCollections.newList(resource) : null);
	}
	
	protected TResource getSelectedResource() {
		return this.selectedResource;
	}
	
	
	@Override
	public void create() {
		// check settings
		if (this.rootContainer == null) {
			setRootElement(ResourcesPlugin.getWorkspace().getRoot());
		}
		if (getMessage() == null) {
			setMessage(getDefaultMessage());
		}
		
		super.create();
		
		initDialog();
	}
	
	protected ISelectionChangedListener createSelectionChangeListener() {
		return new ISelectionChangedListener() {
			@Override
			public void selectionChanged(final SelectionChangedEvent event) {
				final IResource selection= (IResource)
						((IStructuredSelection) event.getSelection()).getFirstElement();
				if (selection != null) {
					onResourceSelected(selection);
					validate();
				}
			}
		};
	}
	
	protected IDoubleClickListener createSelectionDoubleClickListener() {
		return new IDoubleClickListener() {
			@Override
			public void doubleClick(final DoubleClickEvent event) {
				if (getOkButton().isEnabled()) {
					okPressed();
				}
			}
		};
	}
	
	protected void createTextField(final Composite composite) {
		this.textField= new Text(composite, SWT.BORDER | SWT.SINGLE);
		this.textField.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
		
		this.textField.addModifyListener((final ModifyEvent e) -> {
					if (!AbstractResourceSelectionDialog.this.ignoreTextFieldModifications) {
						onTextChanged(AbstractResourceSelectionDialog.this.textField.getText());
						validate();
					}
				});
	}
	
	protected void initSelection(final List<IResource> checkedResources) {
	}
	
	
	protected IResource checkSelectionElement(final Object o) {
		if (o instanceof IResource) {
			final IResource resource= (IResource) o;
			final IPath fullPath= resource.getFullPath();
			final IPath rootPath= this.rootContainer.getFullPath();
			if (rootPath.isPrefixOf(fullPath)) {
				return findExistingResource(fullPath.makeRelativeTo(rootPath), this.rootContainer);
			}
		}
		return null;
	}
	
	protected void initDialog() {
		{	// init selection
			final List elements= getInitialElementSelections();
			if (!elements.isEmpty()) {
				final List<IResource> checkedResources= new ArrayList<>();
				for (final Object o : elements) {
					final IResource resource= checkSelectionElement(o);
					if (resource != null) {
						checkedResources.add(resource);
					}
				}
				if (!checkedResources.isEmpty()) {
					initSelection(checkedResources);
				}
			}
		}
		
		validate();
	}
	
	
	private void setSelectedResource0(final IResource resource) {
		this.selectedResource= ((resource.getType() & getResourceTypes()) != 0) ?
				(TResource) resource : null;
	}
	
	protected void onTextChanged(String pathText) {
		pathText= pathText.trim();
		
		IResource resource= null;
		try {
			final IPath path= new Path(pathText).makeRelative();
			resource= this.rootContainer.findMember(path);
			if (resource == null) {
				resource= (path.hasTrailingSeparator()
								|| ((getResourceTypes() & IResource.FILE) == 0)) ?
						this.rootContainer.getFolder(path) :
						this.rootContainer.getFile(path);
			}
		}
		catch (final IllegalArgumentException e) {}
		
		setSelectedResource0(resource);
	}
	
	protected void onResourceSelected(final IResource resource) {
		setSelectedResource0(resource);
		
		this.ignoreTextFieldModifications= true;
		try {
			final String pathText= (resource != null) ?
					resource.getFullPath().makeRelativeTo(
							this.rootContainer.getFullPath()).toString() :
					""; //$NON-NLS-1$
			this.textField.setText(pathText);
		}
		finally {
			this.ignoreTextFieldModifications= false;
		}
	}
	
	protected void validate() {
		boolean isValid= false;
		final IResource selectedResource= getSelectedResource();
		if (selectedResource != null) {
			final IPath path= selectedResource.getFullPath();
			final IStatus test= ResourcesPlugin.getWorkspace().validatePath(path.toString(), IResource.FILE);
			isValid= (test.getCode() == IStatus.OK && this.rootContainer.getFullPath().isPrefixOf(path)
						&& (isAllowNewResources() || selectedResource.exists()) );
		}
		getOkButton().setEnabled(isValid);
	}
	
	
	@Override
	protected void computeResult() {
		setSelectionResult(new IResource[] { getSelectedResource() });
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public TResource getFirstResult() {
		return (TResource) super.getFirstResult();
	}
	
}
