/*******************************************************************************
 * Copyright (c) 2010, 2017 BestSolution.at 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
 *
 * Contributors:
 * Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
 * Sopot Cela <sopotcela@gmail.com>
 * Patrik Suzzi <psuzzi@gmail.com> - Bug 421066, 466491
 ******************************************************************************/
package org.eclipse.e4.internal.tools.wizards.classes;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;

import org.eclipse.core.databinding.Binding;
import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.UpdateValueStrategy;
import org.eclipse.core.databinding.beans.BeanProperties;
import org.eclipse.core.databinding.conversion.Converter;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.databinding.validation.IValidator;
import org.eclipse.core.databinding.validation.MultiValidator;
import org.eclipse.core.databinding.validation.ValidationStatus;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.e4.internal.tools.Messages;
import org.eclipse.e4.internal.tools.ToolsPlugin;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaModel;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaConventions;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.wizards.NewWizardMessages;
import org.eclipse.jdt.internal.ui.wizards.TypedElementSelectionValidator;
import org.eclipse.jdt.internal.ui.wizards.TypedViewerFilter;
import org.eclipse.jdt.ui.JavaElementComparator;
import org.eclipse.jdt.ui.JavaElementLabelProvider;
import org.eclipse.jdt.ui.StandardJavaElementContentProvider;
import org.eclipse.jface.databinding.swt.ISWTObservableValue;
import org.eclipse.jface.databinding.swt.IWidgetValueProperty;
import org.eclipse.jface.databinding.swt.WidgetProperties;
import org.eclipse.jface.databinding.wizard.WizardPageSupport;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.window.Window;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.dialogs.ElementListSelectionDialog;
import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;

@SuppressWarnings("restriction")
public abstract class AbstractNewClassPage extends WizardPage {
	private static final String BUNDLECLASS = "bundleclass://"; //$NON-NLS-1$
	private static final String FRAGMENT_ROOT = "fragmentRoot"; //$NON-NLS-1$
	public static final String PACKAGE_FRAGMENT = "packageFragment"; //$NON-NLS-1$
	public static final String PROPERTY_NAME = "name"; //$NON-NLS-1$

	public static class JavaClass {

		protected PropertyChangeSupport support = new PropertyChangeSupport(this);

		private IPackageFragmentRoot fragmentRoot;
		private IPackageFragment packageFragment;
		private String name;

		public JavaClass(IPackageFragmentRoot fragmentRoot) {
			this.fragmentRoot = fragmentRoot;
		}

		public IPackageFragmentRoot getFragmentRoot() {
			return fragmentRoot;
		}

		public void setFragmentRoot(IPackageFragmentRoot fragmentRoot) {
			support.firePropertyChange(FRAGMENT_ROOT, this.fragmentRoot, this.fragmentRoot = fragmentRoot);
		}

		public IPackageFragment getPackageFragment() {
			return packageFragment;
		}

		public void setPackageFragment(IPackageFragment packageFragment) {
			support.firePropertyChange(PACKAGE_FRAGMENT, this.packageFragment, this.packageFragment = packageFragment);
		}

		public String getName() {
			return name;
		}

		public void setName(String name) {
			support.firePropertyChange(PROPERTY_NAME, this.name, this.name = name);
		}

		public void addPropertyChangeListener(PropertyChangeListener listener) {
			support.addPropertyChangeListener(listener);
		}

		public void removePropertyChangeListener(PropertyChangeListener listener) {
			support.removePropertyChangeListener(listener);
		}

		public static boolean exists(IPackageFragmentRoot pFragmentRoot, IPackageFragment pPackageFragment, String pName) {

			if (pFragmentRoot == null) {
				return false;
			}

			final String cuName = pName + ".java"; //$NON-NLS-1$
			IFile file;

			if (pPackageFragment != null) {
				final ICompilationUnit unit = pPackageFragment.getCompilationUnit(cuName);
				final IResource resource = unit.getResource();
				file = (IFile) resource;
			} else {
				final IFolder p = (IFolder) pFragmentRoot.getResource();
				file = p.getFile(cuName);
			}
			return file.exists();
		}
	}

	private JavaClass clazz;
	private IPackageFragmentRoot froot;
	private final IWorkspaceRoot fWorkspaceRoot;
	private String initialString;
	private String initialPackage;

	protected AbstractNewClassPage(String pageName, String title, String description, IPackageFragmentRoot froot,
			IWorkspaceRoot fWorkspaceRoot) {
		super(pageName);
		this.froot = froot;
		this.fWorkspaceRoot = fWorkspaceRoot;

		setTitle(title);
		setDescription(description);
	}

	protected AbstractNewClassPage(String pageName, String title, String description, IPackageFragmentRoot froot,
			IWorkspaceRoot fWorkspaceRoot, String initialString) {
		this(pageName, title, description, froot, fWorkspaceRoot);
		this.initialString = initialString;
	}

	/**
	 * The wizard owning this page is responsible for calling this method with
	 * the current selection. The selection is used to initialize the fields of
	 * the wizard page.
	 *
	 * @param selection
	 *            used to initialize the fields
	 */
	public void init(IStructuredSelection selection) {
		if (selection == null || selection.isEmpty() || selection.getFirstElement() == null) {
			return;
		}
		if (selection.getFirstElement() instanceof IPackageFragment) {
			final IPackageFragment pkg = (IPackageFragment) selection.getFirstElement();
			initialPackage = pkg.getElementName();
		}
	}

	@Override
	public void createControl(Composite parent) {
		final Image img = new Image(parent.getDisplay(), getClass().getClassLoader().getResourceAsStream(
				"/icons/full/wizban/newclass_wiz.png")); //$NON-NLS-1$
		setImageDescriptor(ImageDescriptor.createFromImage(img));

		parent.addDisposeListener(e -> {
			img.dispose();
			setImageDescriptor(null);
		});

		parent = new Composite(parent, SWT.NULL);
		parent.setLayoutData(new GridData(GridData.FILL_BOTH));
		parent.setLayout(new GridLayout(3, false));

		clazz = createInstance();
		if (froot != null && initialString != null) {
			clazz.setPackageFragment(froot.getPackageFragment(parseInitialStringForPackage(initialString) == null ? "" //$NON-NLS-1$
					: parseInitialStringForPackage(initialString)));
			clazz.setName(parseInitialStringForClassName(initialString));
		} else if (froot != null && initialPackage != null) {
			clazz.setPackageFragment(froot.getPackageFragment(initialPackage));
		}
		final DataBindingContext dbc = new DataBindingContext();
		WizardPageSupport.create(this, dbc);

		{
			final Label l = new Label(parent, SWT.NONE);
			l.setText(Messages.AbstractNewClassPage_SourceFolder);

			final Text t = new Text(parent, SWT.BORDER);
			t.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
			t.setEditable(false);

			final Binding bd = dbc.bindValue(
					WidgetProperties.text().observe(t),
					BeanProperties.value(FRAGMENT_ROOT).observe(clazz),
					new UpdateValueStrategy().setBeforeSetValidator(new PFRootValidator()),
					new UpdateValueStrategy().setConverter(new PackageFragmentRootToStringConverter())
					);

			final Button b = new Button(parent, SWT.PUSH);
			b.setText(Messages.AbstractNewClassPage_Browse);
			b.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					final IPackageFragmentRoot root = choosePackageRoot();
					if (root != null) {
						froot = root;
						clazz.setFragmentRoot(root);
					}
					bd.updateModelToTarget();
				}
			});
		}

		final Text tClassPackage;
		{
			final Label l = new Label(parent, SWT.NONE);
			l.setText(Messages.AbstractNewClassPage_Package);
			tClassPackage = new Text(parent, SWT.BORDER);
			tClassPackage.setEditable(true);
			tClassPackage.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
			final Binding bd = dbc.bindValue(
					WidgetProperties.text(SWT.Modify).observe(tClassPackage),
					BeanProperties.value(PACKAGE_FRAGMENT).observe(clazz),
					new UpdateValueStrategy().setConverter(new StringToPackageFragmentConverter(clazz)),
					new UpdateValueStrategy().setConverter(new PackageFragmentToStringConverter())
					);

			final Button b = new Button(parent, SWT.PUSH);
			b.setText(Messages.AbstractNewClassPage_Browse);
			b.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					final IPackageFragment fragment = choosePackage();
					if (fragment != null) {
						clazz.setPackageFragment(fragment);
					}
					bd.updateModelToTarget(); // TODO Find out why this is needed
				}
			});
		}

		final Text tClassName;
		{
			final IWidgetValueProperty textProp = WidgetProperties.text(SWT.Modify);

			final Label l = new Label(parent, SWT.NONE);
			l.setText(Messages.AbstractNewClassPage_Name);

			tClassName = new Text(parent, SWT.BORDER);
			tClassName.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
			dbc.bindValue(textProp.observe(tClassName),
					BeanProperties.value(PROPERTY_NAME, String.class).observe(clazz),
					new UpdateValueStrategy().setBeforeSetValidator(new ClassnameValidator()), null);

			new Label(parent, SWT.NONE);
		}

		{
			final Label l = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL);
			l.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, false, false, 3, 1));
		}

		final ISWTObservableValue obsPackage = WidgetProperties.text(SWT.Modify).observe(tClassPackage);
		final ISWTObservableValue obsClass = WidgetProperties.text(SWT.Modify).observe(tClassName);
		@SuppressWarnings("unchecked")
		final ClassMultiValidator multiValidator = new ClassMultiValidator(clazz, obsPackage, obsClass);
		dbc.addValidationStatusProvider(multiValidator);

		createFields(parent, dbc);
		setControl(parent);
	}

	private String parseInitialStringForPackage(String initialString2) {
		if (initialString2 == null) {
			return null;
		}
		final int ioBC = initialString2.indexOf(BUNDLECLASS);
		final int iSecondSlash = initialString2.lastIndexOf('/');
		if (

				initialString2.length() == 0 || // empty
				ioBC == -1 || // no bundle class
				iSecondSlash == -1 || // no package &| class name
				initialString2.indexOf('.') == -1// no package
				) {
			return null;
		}

		final int lastDot = initialString2.lastIndexOf('.');
		final String packageString = initialString2.substring(iSecondSlash + 1, lastDot);
		return packageString;
	}

	private String parseInitialStringForClassName(String initialString) {
		if (initialString == null) {
			return null;
		}
		final int ioBC = initialString.indexOf(BUNDLECLASS);
		final int iSecondSlash = initialString.lastIndexOf('/');
		if (

				initialString.length() == 0 || // empty
				ioBC == -1 || // no bundle class
				iSecondSlash == -1 || // no package &| class name
				initialString.indexOf('.') == -1// no package
				) {
			return null;
		}
		final int lastDot = initialString.lastIndexOf('.');
		if (lastDot != -1) {
			return initialString.substring(lastDot + 1);
		}
		return null;
	}

	private IPackageFragmentRoot choosePackageRoot() {
		final IJavaElement initElement = clazz.getFragmentRoot();
		Class<?>[] acceptedClasses = new Class[] { IPackageFragmentRoot.class, IJavaProject.class };
		final TypedElementSelectionValidator validator = new TypedElementSelectionValidator(acceptedClasses, false) {
			@Override
			public boolean isSelectedValid(Object element) {
				try {
					if (element instanceof IJavaProject) {
						final IJavaProject jproject = (IJavaProject) element;
						final IPath path = jproject.getProject().getFullPath();
						return jproject.findPackageFragmentRoot(path) != null;
					} else if (element instanceof IPackageFragmentRoot) {
						return ((IPackageFragmentRoot) element).getKind() == IPackageFragmentRoot.K_SOURCE;
					}
					return true;
				} catch (final JavaModelException e) {
					JavaPlugin.log(e.getStatus()); // just log, no UI in validation
				}
				return false;
			}
		};

		acceptedClasses = new Class[] { IJavaModel.class, IPackageFragmentRoot.class, IJavaProject.class };
		final ViewerFilter filter = new TypedViewerFilter(acceptedClasses) {
			@Override
			public boolean select(Viewer viewer, Object parent, Object element) {
				if (element instanceof IPackageFragmentRoot) {
					try {
						return ((IPackageFragmentRoot) element).getKind() == IPackageFragmentRoot.K_SOURCE;
					} catch (final JavaModelException e) {
						JavaPlugin.log(e.getStatus()); // just log, no UI in validation
						return false;
					}
				}
				return super.select(viewer, parent, element);
			}
		};

		final StandardJavaElementContentProvider provider = new StandardJavaElementContentProvider();
		final ILabelProvider labelProvider = new JavaElementLabelProvider(JavaElementLabelProvider.SHOW_DEFAULT);
		final ElementTreeSelectionDialog dialog = new ElementTreeSelectionDialog(getShell(), labelProvider, provider);
		dialog.setValidator(validator);
		dialog.setComparator(new JavaElementComparator());
		dialog.setTitle(NewWizardMessages.NewContainerWizardPage_ChooseSourceContainerDialog_title);
		dialog.setMessage(NewWizardMessages.NewContainerWizardPage_ChooseSourceContainerDialog_description);
		dialog.addFilter(filter);
		dialog.setInput(JavaCore.create(fWorkspaceRoot));
		dialog.setInitialSelection(initElement);
		dialog.setHelpAvailable(false);

		if (dialog.open() == Window.OK) {
			final Object element = dialog.getFirstResult();
			if (element instanceof IJavaProject) {
				final IJavaProject jproject = (IJavaProject) element;
				return jproject.getPackageFragmentRoot(jproject.getProject());
			} else if (element instanceof IPackageFragmentRoot) {
				return (IPackageFragmentRoot) element;
			}
			return null;
		}
		return null;
	}

	private IPackageFragment choosePackage() {
		IJavaElement[] packages = null;
		try {
			if (froot != null && froot.exists()) {
				packages = froot.getChildren();
			}
		} catch (final JavaModelException e) {
			e.printStackTrace();
		}
		if (packages == null) {
			packages = new IJavaElement[0];
		}

		final ElementListSelectionDialog dialog = new ElementListSelectionDialog(getShell(),
				new JavaElementLabelProvider(JavaElementLabelProvider.SHOW_DEFAULT));
		dialog.setIgnoreCase(false);
		dialog.setTitle(Messages.AbstractNewClassPage_ChoosePackage);
		dialog.setMessage(Messages.AbstractNewClassPage_ChooseAPackage);
		dialog.setEmptyListMessage(Messages.AbstractNewClassPage_NeedToSelectAPackage);
		dialog.setElements(packages);
		dialog.setHelpAvailable(false);
		final IPackageFragment pack = clazz.getPackageFragment();
		if (pack != null) {
			dialog.setInitialSelections(new Object[] { pack });
		}

		if (dialog.open() == Window.OK) {
			return (IPackageFragment) dialog.getFirstResult();
		}
		return null;
	}

	protected abstract void createFields(Composite parent, DataBindingContext dbc);

	protected abstract JavaClass createInstance();

	public JavaClass getClazz() {
		return clazz;
	}

	/**
	 * Validate the specified class does not already exists
	 */
	static class ClassMultiValidator extends MultiValidator {

		private final JavaClass javaClass;
		private final IObservableValue<String> observedPackage;
		private final IObservableValue<String> observedClass;

		public ClassMultiValidator(JavaClass javaClass, final IObservableValue<String> observedPackage,
				final IObservableValue<String> observedClass) {
			this.javaClass = javaClass;
			this.observedPackage = observedPackage;
			this.observedClass = observedClass;
		}

		/**
		 * {@inheritDoc}
		 *
		 * @see org.eclipse.core.databinding.validation.MultiValidator#validate()
		 */
		@Override
		protected IStatus validate() {
			final String classPackage = observedPackage.getValue();
			final String className = observedClass.getValue();

			final IPackageFragment packageFragment = javaClass.getFragmentRoot().getPackageFragment(classPackage);

			if (JavaClass.exists(javaClass.getFragmentRoot(), packageFragment, className)) {
				return new Status(IStatus.ERROR, ToolsPlugin.PLUGIN_ID, Messages.AbstractNewClassPage_ClassExists);
			}

			return ValidationStatus.ok();
		}

	}

	static class ClassnameValidator implements IValidator {

		@Override
		public IStatus validate(Object value) {
			final String name = value.toString();
			if (name.length() == 0) {
				return new Status(IStatus.ERROR, ToolsPlugin.PLUGIN_ID, Messages.AbstractNewClassPage_NameNotEmpty);
			}
			if (name.indexOf('.') != -1 || name.trim().indexOf(' ') != -1) {
				return new Status(IStatus.ERROR, ToolsPlugin.PLUGIN_ID,
						Messages.AbstractNewClassPage_NameMustBeQualified);
			}

			return JavaConventions.validateJavaTypeName(name, JavaCore.VERSION_1_3, JavaCore.VERSION_1_3);
		}
	}

	static class PFRootValidator implements IValidator {

		@Override
		public IStatus validate(Object value) {
			final String name = value.toString();
			if (name.length() == 0) {
				return new Status(IStatus.ERROR, ToolsPlugin.PLUGIN_ID,
						Messages.AbstractNewClassPage_SourceFolderNotEmpty);
			}

			return new Status(IStatus.OK, ToolsPlugin.PLUGIN_ID, ""); //$NON-NLS-1$
		}
	}

	static class PackageFragmentRootToStringConverter extends Converter {

		public PackageFragmentRootToStringConverter() {
			super(IPackageFragmentRoot.class, String.class);
		}

		@Override
		public Object convert(Object fromObject) {
			final IPackageFragmentRoot f = (IPackageFragmentRoot) fromObject;
			if (f == null) {
				return ""; //$NON-NLS-1$
			}
			return f.getPath().makeRelative().toString();
		}
	}

	static class PackageFragmentToStringConverter extends Converter {

		public PackageFragmentToStringConverter() {
			super(IPackageFragment.class, String.class);
		}

		@Override
		public Object convert(Object fromObject) {
			if (fromObject == null) {
				return ""; //$NON-NLS-1$
			}
			final IPackageFragment f = (IPackageFragment) fromObject;
			return f.getElementName();
		}
	}

	static class StringToPackageFragmentConverter extends Converter {

		private final JavaClass clazz;

		public StringToPackageFragmentConverter(JavaClass clazz) {
			super(String.class, IPackageFragment.class);
			this.clazz = clazz;
		}

		@Override
		public Object convert(Object fromObject) {
			if (clazz.getFragmentRoot() == null) {
				return null;
			}
			if (fromObject == null) {
				return clazz.getFragmentRoot().getPackageFragment(""); //$NON-NLS-1$
			}

			return clazz.getFragmentRoot().getPackageFragment((String) fromObject);

		}
	}
}
