/*******************************************************************************
 * Copyright (c) 2010, 2019 BestSolution.at and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 * Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
 * Steven Spungin <steve@spungin.tv> - Ongoing Maintenance, Bug 439532, Bug 443945
 * Patrik Suzzi <psuzzi@gmail.com> - Bug 467262
 * Olivier Prouvost <olivier.prouvost@opcoach.com> - Bug 509488, 525986
 * Patrik Suzzi <psuzzi@gmail.com> - Bug 509606
 ******************************************************************************/
package org.eclipse.e4.tools.emf.ui.internal.common.component;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.inject.Inject;

import org.eclipse.core.databinding.observable.list.IObservableList;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.emf.xpath.EcoreXPathContextFactory;
import org.eclipse.e4.emf.xpath.XPathContext;
import org.eclipse.e4.emf.xpath.XPathContextFactory;
import org.eclipse.e4.tools.emf.ui.common.IEditorFeature.FeatureClass;
import org.eclipse.e4.tools.emf.ui.common.Util;
import org.eclipse.e4.tools.emf.ui.common.Util.InternalPackage;
import org.eclipse.e4.tools.emf.ui.common.component.AbstractComponentEditor;
import org.eclipse.e4.tools.emf.ui.internal.E4Properties;
import org.eclipse.e4.tools.emf.ui.internal.ResourceProvider;
import org.eclipse.e4.tools.emf.ui.internal.common.AbstractPickList.PickListFeatures;
import org.eclipse.e4.tools.emf.ui.internal.common.E4PickList;
import org.eclipse.e4.tools.emf.ui.internal.common.component.ControlFactory.TextPasteHandler;
import org.eclipse.e4.tools.emf.ui.internal.common.component.dialogs.FeatureSelectionDialog;
import org.eclipse.e4.tools.emf.ui.internal.common.component.dialogs.FindParentReferenceElementDialog;
import org.eclipse.e4.tools.emf.ui.internal.common.component.tabs.empty.E;
import org.eclipse.e4.tools.emf.ui.internal.common.component.virtual.VSnippetsEditor;
import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.e4.ui.model.application.MApplicationElement;
import org.eclipse.e4.ui.model.application.impl.ApplicationElementImpl;
import org.eclipse.e4.ui.model.application.impl.ApplicationPackageImpl;
import org.eclipse.e4.ui.model.fragment.MModelFragment;
import org.eclipse.e4.ui.model.fragment.MStringModelFragment;
import org.eclipse.e4.ui.model.fragment.impl.FragmentPackageImpl;
import org.eclipse.e4.ui.model.fragment.impl.StringModelFragmentImpl;
import org.eclipse.e4.ui.model.internal.ModelUtils;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.databinding.EMFDataBindingContext;
import org.eclipse.emf.databinding.FeaturePath;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.edit.command.AddCommand;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.bindings.keys.KeyStroke;
import org.eclipse.jface.bindings.keys.ParseException;
import org.eclipse.jface.databinding.swt.IWidgetValueProperty;
import org.eclipse.jface.databinding.swt.typed.WidgetProperties;
import org.eclipse.jface.fieldassist.ContentProposal;
import org.eclipse.jface.fieldassist.ContentProposalAdapter;
import org.eclipse.jface.fieldassist.ControlDecoration;
import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
import org.eclipse.jface.fieldassist.IContentProposal;
import org.eclipse.jface.fieldassist.IContentProposalProvider;
import org.eclipse.jface.fieldassist.TextContentAdapter;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabItem;
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;

public class StringModelFragment extends AbstractComponentEditor<MStringModelFragment> {
	private Composite composite;
	private EMFDataBindingContext context;

	// The selected Container is the class that match the ID.
	// It can be get from the FindParentReferenceDialog or computed from the ID.
	private EClass selectedContainer;

	// This is the list of available 'add child' actions depending on selected
	// values
	private final List<Action> actions = new ArrayList<>();

	@Inject
	IEclipseContext eclipseContext;

	// The pickList to select the kind of children to add (must be refreshed)
	private E4PickList pickList;
	private Text featureText;

	@Inject
	public StringModelFragment() {
		super();
	}

	@PostConstruct
	public void init() {
	}

	@Override
	public Image getImage(Object element) {
		return getImage(element, ResourceProvider.IMG_StringModelFragment);
	}

	@Override
	public String getLabel(Object element) {

		MStringModelFragment modelFragment;
		if (element instanceof MStringModelFragment) {
			modelFragment = (MStringModelFragment) element;
		} else {
			modelFragment = getStringModelFragment();
		}

		EClass container = findContainerType(modelFragment);
		String result;
		if (container == null) {
			result = Messages.StringModelFragment_Label;
		} else {
			result = Messages.StringModelFragment_LabelFor + container.getName();
		}

		return result;
	}

	@Override
	public FeaturePath[] getLabelProperties() {
		return new FeaturePath[] {
				FeaturePath.fromList(FragmentPackageImpl.Literals.STRING_MODEL_FRAGMENT__FEATURENAME),
				FeaturePath.fromList(FragmentPackageImpl.Literals.STRING_MODEL_FRAGMENT__PARENT_ELEMENT_ID) };
	}

	@Override
	public String getDetailLabel(Object element) {
		if (element instanceof StringModelFragmentImpl) {
			final StringModelFragmentImpl fragment = (StringModelFragmentImpl) element;
			String ret = ""; //$NON-NLS-1$
			if (E.notEmpty(fragment.getFeaturename())) {
				ret += fragment.getFeaturename();
			}
			if (E.notEmpty(fragment.getParentElementId())) {
				ret += " (" + fragment.getParentElementId() + ")"; //$NON-NLS-1$ //$NON-NLS-2$
			}
			return ret;
		}
		return null;
	}

	@Override
	public String getDescription(Object element) {
		return Messages.StringModelFragment_Description;
	}

	@Override
	public Composite doGetEditor(Composite parent, Object object) {
		if (composite == null) {
			context = new EMFDataBindingContext();
			composite = createForm(parent);
		}
		selectedContainer = null;
		getMaster().setValue((MStringModelFragment) object);
		updateChildrenChoice();
		getEditor().setHeaderTitle(getLabel(null));
		return composite;
	}

	/**
	 * Returns the selectedContainer, which is the EClass behind the Extended
	 * Element ID. It can be known thanks to the dialog or must be computed from
	 * the ID value
	 *
	 * @return
	 */
	private EClass getSelectedContainer() {
		if (selectedContainer != null) {
			return selectedContainer;
		}

		// we get the StringModelFragment. If not initialized, no search...
		StringModelFragmentImpl modelFragment = getStringModelFragment();
		selectedContainer = findContainerType(modelFragment);

		updateTitle();

		return selectedContainer;
	}

	/**
	 * Returns the selectedContainer, which is the EClass behind the Extended
	 * Element ID. It can be known thanks to the dialog or must be computed from the
	 * ID value
	 *
	 */
	public static EClass findContainerType(MStringModelFragment modelFragment) {
		// we get the StringModelFragment. If not initialized, no search...
		if (modelFragment == null) {
			return null;
		}

		// If no element ID, no search...
		String parentElementId = modelFragment.getParentElementId();
		if ((parentElementId == null) || (parentElementId.isEmpty())) {
			return null;
		}

		// known ID for application are directly filtered.
		if ("xpath:/".equals(parentElementId) || "org.eclipse.e4.legacy.ide.application".equals(parentElementId)) {
			return ApplicationPackageImpl.eINSTANCE.getApplication();
		}

		// We have to proceed to a simple search on all elements in all resource
		// set... this resource set is cached by Util...
		ResourceSet resourceSet = Util.getModelElementResources();

		String xpath = parentElementId.startsWith("xpath:") ? parentElementId.substring(6) : null;

		for (final Resource res : resourceSet.getResources()) {
			final TreeIterator<EObject> it = EcoreUtil.getAllContents(res, true);
			while (it.hasNext()) {
				final EObject o = it.next();
				// We found this element, if this is an application element not
				// contained in model fragment imports
				// and having the same ID. We return the first found.

				// Deal with non default MApplication IDs.
				if (xpath != null) {
					if (o instanceof MApplication) {
						EClass found = getTargetClassFromXPath((MApplication) o, xpath);
						if (found != null) {
							return found;
						}
					}
				} else {
					// This is a standard search with ID.
					if ((o instanceof MApplicationElement)
							&& (o.eContainingFeature() != FragmentPackageImpl.Literals.MODEL_FRAGMENTS__IMPORTS)
							&& parentElementId.equals(((MApplicationElement) o).getElementId())) {
						return o.eClass();
					}
				}
			}
		}

		return null;
	}

	private void updateTitle() {
		getEditor().setHeaderTitle(getLabel(null));
	}

	private StringModelFragmentImpl getStringModelFragment() {
		return ((StringModelFragmentImpl) getMaster().getValue());
	}

	private Composite createForm(Composite parent) {
		final CTabFolder folder = new CTabFolder(parent, SWT.BOTTOM);

		final CTabItem item = new CTabItem(folder, SWT.NONE);
		item.setText(Messages.ModelTooling_Common_TabDefault);

		parent = createScrollableContainer(folder);
		item.setControl(parent.getParent());

		if (getEditor().isShowXMIId() || getEditor().isLiveModel()) {
			ControlFactory.createXMIId(parent, this);
		}

		final IWidgetValueProperty<Text, String> textProp = WidgetProperties.text(SWT.Modify);
		{
			final Label l = new Label(parent, SWT.NONE);
			l.setText(Messages.StringModelFragment_ParentId);
			l.setToolTipText(Messages.StringModelFragment_ParentIdTooltip);
			l.setLayoutData(new GridData());

			final Composite comp = new Composite(parent, SWT.NONE);
			GridData gd = new GridData(GridData.FILL_HORIZONTAL);
			gd.horizontalSpan = 2;
			comp.setLayoutData(gd);
			final GridLayout gl = new GridLayout(2, false);
			gl.marginWidth = gl.marginHeight = 0;
			gl.verticalSpacing = 0;
			gl.marginLeft = gl.marginBottom = gl.marginRight = gl.marginTop = 0;
			comp.setLayout(gl);

			final Text t = new Text(comp, SWT.BORDER);
			TextPasteHandler.createFor(t);
			// t.setEditable(false);
			gd = new GridData(GridData.FILL_HORIZONTAL);
			t.setLayoutData(gd);
			context.bindValue(textProp.observeDelayed(200, t),
					E4Properties.parentElementId(getEditingDomain()).observeDetail(getMaster()));

			// Add a modify listener to control the change of the ID -> Must
			// force the computation of selectedContainer.
			t.addModifyListener(e -> selectedContainer = null);

			Button b = ControlFactory.createFindButton(comp, resourcePool);
			b.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					final FindParentReferenceElementDialog dialog = new FindParentReferenceElementDialog(b.getShell(),
							StringModelFragment.this, getMaster().getValue(), Messages,
							getSelectedContainer());
					dialog.open();
					selectedContainer = dialog.getSelectedContainer();
					updateTitle();
				}
			});
		}

		{
			final Label l = new Label(parent, SWT.NONE);
			l.setText(Messages.StringModelFragment_Featurename);
			l.setToolTipText(Messages.StringModelFragment_FeaturenameTooltip);
			l.setLayoutData(new GridData());

			final Composite comp = new Composite(parent, SWT.NONE);
			GridData gd = new GridData(GridData.FILL_HORIZONTAL);
			gd.horizontalSpan = 2;
			comp.setLayoutData(gd);
			final GridLayout gl = new GridLayout(2, false);
			gl.marginWidth = gl.marginHeight = 0;
			gl.verticalSpacing = 0;
			gl.marginLeft = gl.marginBottom = gl.marginRight = gl.marginTop = 0;
			comp.setLayout(gl);

			featureText = new Text(comp, SWT.BORDER);
			TextPasteHandler.createFor(featureText);
			gd = new GridData(GridData.FILL_HORIZONTAL);
			featureText.setLayoutData(gd);
			context.bindValue(textProp.observeDelayed(200, featureText),
					E4Properties.featureName(getEditingDomain()).observeDetail(getMaster()));

			// create the decoration for the text component
			final ControlDecoration deco = new ControlDecoration(featureText, SWT.TOP | SWT.LEFT);

			// use an existing image
			Image image = FieldDecorationRegistry.getDefault()
					.getFieldDecoration(FieldDecorationRegistry.DEC_INFORMATION).getImage();

			// set description and image
			deco.setDescriptionText(Messages.StringModelFragment_Ctrl_Space);
			deco.setImage(image);

			// always show decoration
			deco.setShowOnlyOnFocus(false);

			// hide the decoration if the text component has content
			featureText.addModifyListener(e -> {
				Text text = (Text) e.getSource();
				if (!text.getText().isEmpty()) {
					deco.hide();
				} else {
					deco.show();
				}
			});

			KeyStroke keyStroke;
			try {
				char[] autoactivationChar = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.".toCharArray();
				keyStroke = KeyStroke.getInstance("Ctrl+Space");
				ContentProposalAdapter adapter = new ContentProposalAdapter(featureText, new TextContentAdapter(),
						new StringModelFragmentProposalProvider(this, featureText), keyStroke, autoactivationChar);
				adapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE);
			} catch (ParseException e) {
				e.printStackTrace();
			}
			featureText.addModifyListener(e -> updateChildrenChoice());

			Button b = ControlFactory.createFindButton(comp, resourcePool);
			b.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					final FeatureSelectionDialog dialog = new FeatureSelectionDialog(b.getShell(),
							getEditingDomain(), getMaster().getValue(), Messages,
							getSelectedContainer());
					dialog.open();
				}
			});

		}

		ControlFactory.createTextField(parent, Messages.StringModelFragment_PositionInList, getMaster(), context,
				textProp, E4Properties.positionInList(getEditingDomain()));

		// ------------------------------------------------------------
		{

			pickList = new E4PickList(parent, SWT.NONE, Arrays.asList(PickListFeatures.NO_GROUP), this,
					FragmentPackageImpl.Literals.MODEL_FRAGMENT__ELEMENTS) {
				@Override
				protected void addPressed() {
					if(!getSelection().isEmpty()) {
						final EClass eClass = ((FeatureClass) getSelection().getFirstElement()).eClass;
						handleAdd(eClass, false);
					}
				}

				@Override
				protected List<?> getContainerChildren(Object master) {
					return ((StringModelFragmentImpl) master).getElements();
				}
			};

			pickList.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1));

			pickList.setLabelProvider(new LabelProvider() {
				@Override
				public String getText(Object element) {
					final FeatureClass eclass = (FeatureClass) element;
					return eclass.label;
				}
			});

			pickList.setComparator(new ViewerComparator() {
				@Override
				public int compare(Viewer viewer, Object e1, Object e2) {
					final FeatureClass eClass1 = (FeatureClass) e1;
					final FeatureClass eClass2 = (FeatureClass) e2;
					return eClass1.label.compareTo(eClass2.label);
				}
			});

		}

		createContributedEditorTabs(folder, context, getMaster(), MStringModelFragment.class);

		folder.setSelection(0);

		updateChildrenChoice();

		return folder;
	}

	static class StringModelFragmentProposalProvider implements IContentProposalProvider {

		private StringModelFragment fragment;
		private Text text;

		/**
		 * Initialize the class passing the current instance.
		 */
		public StringModelFragmentProposalProvider(StringModelFragment fragment, Text t) {
			this.fragment = fragment;
			this.text = t;
		}

		@Override
		public IContentProposal[] getProposals(String cont, int position) {
			List<String[]> contents = new ArrayList<>();
			StringBuilder sb = new StringBuilder(256);
			if (fragment.getSelectedContainer() != null) {
				for (EReference r : fragment.getSelectedContainer().getEAllReferences()) {
					if (Util.referenceIsModelFragmentCompliant(r) && r.getName().startsWith(text.getText())) {
						String content = r.getName();
						sb.setLength(0);
						sb.append(content).append(": ");
						final EClassifier type = ModelUtils.getTypeArgument(this.fragment.getSelectedContainer(),
								r.getEGenericType());
						if (r.isMany()) {
							// List<Container>
							sb.append("List<").append(type.getName()).append(">");
						} else {
							// TypeOfTheClass
							sb.append(type.getName());
						}
						contents.add(new String[] { content, sb.toString() });
					}
				}
			}

			Collections.sort(contents, (o1, o2) -> o1[0].compareTo(o2[0]));

			IContentProposal[] contentProposals = new IContentProposal[contents.size()];
			for (int i = 0; i < contents.size(); i++) {
				contentProposals[i] = new ContentProposal(contents.get(i)[0], contents.get(i)[1], null);
			}
			return contentProposals;
		}

	}

	public void dispose() {
		if (composite != null) {
			composite.dispose();
			composite = null;
		}

		if (context != null) {
			context.dispose();
			context = null;
		}
	}

	/**
	 * This method will update the picklist containing the list of possible
	 * children classes
	 *
	 */
	private void updateChildrenChoice() {
		selectedContainer = getSelectedContainer();

		final List<FeatureClass> list = getTargetChildrenClasses();

		pickList.setInput(list);
		if (list.size() > 0) {
			pickList.setSelection(new StructuredSelection(list.get(0)));
		}

		// pickList.getList().refresh();

		pickList.getList().setInput(E4Properties.elements().observeDetail(getMaster()));

		// Update the possible actions
		actions.clear();
		for (final FeatureClass featureClass : list) {
			actions.add(new Action(featureClass.label) {
				@Override
				public void run() {
					handleAdd(featureClass.eClass, false);
				}
			});
		}
	}

	@Override
	public IObservableList<?> getChildList(Object element) {
		return E4Properties.elements().observe((MModelFragment) element);
	}

	protected void handleAdd(EClass eClass, boolean separator) {
		final EObject eObject = EcoreUtil.create(eClass);
		setElementId(eObject);
		final Command cmd = AddCommand.create(getEditingDomain(), getMaster().getValue(),
				FragmentPackageImpl.Literals.MODEL_FRAGMENT__ELEMENTS, eObject);

		if (cmd.canExecute()) {
			getEditingDomain().getCommandStack().execute(cmd);
			getEditor().setSelection(eObject);
		}
	}

	@Override
	public List<Action> getActions(Object element) {
		final ArrayList<Action> l = new ArrayList<>(super.getActions(element));
		l.addAll(actions);
		Collections.sort(l, (o1, o2) -> o1.getText().compareTo(o2.getText()));
		return l;
	}

	/**
	 * Returns the EClass of the Application element(s) referenced by the xpath
	 * value (without prefix)
	 *
	 * @param application
	 *            : the application to be parsed
	 * @param xpath
	 *            : the xpath value without the 'xpath:' prefix
	 * @return the list of EClass(es) matching this xpath
	 */
	private static EClass getTargetClassFromXPath(MApplication application, String xpath) {

		XPathContextFactory<EObject> f = EcoreXPathContextFactory.newInstance();
		XPathContext xpathContext = f.newContext((EObject) application);
		Iterator<Object> i = xpathContext.iterate(xpath);

		try {
			while (i.hasNext()) {
				Object obj = i.next();
				if (obj instanceof MApplicationElement) {
					ApplicationElementImpl ae = (ApplicationElementImpl) obj;
					return ae.eClass();
				}
			}
		} catch (Exception ex) {
			// custom xpath functions will throw exceptions
			ex.printStackTrace();
		}

		return null;
	}

	/**
	 * This method computes the available classes that can be selected as child
	 * for the current selected element. The result is cached in a map as the
	 * meta model will not change !
	 *
	 * @return an empty list or the list for possible children
	 */

	public List<FeatureClass> getTargetChildrenClasses() {
		List<FeatureClass> targetChildrenClasses = new ArrayList<>();
		if (selectedContainer != null) {
			List<FeatureClass> childTypes = getTargetChildrenClasses(selectedContainer,
					featureText.getText());
			targetChildrenClasses.addAll(childTypes);
		}
		return targetChildrenClasses;
	}

	/**
	 * This method computes the available classes that can be selected as child for
	 * the current selected element. The result is cached in a map as the meta model
	 * will not change !
	 *
	 * @param targetClass
	 *            the target class to check against
	 *
	 * @return an empty list or the list for possible children
	 */

	public static List<FeatureClass> getTargetChildrenClasses(EClass targetClass, String featurename) {
		List<FeatureClass> result = Collections.emptyList();

		if (targetClass != null) {
			// The top level class for children, is the class of the EReference
			// bound to feature name

			// We must manage especially snippets (see bug 531219) No other solution ...
			if ("snippets".equals(featurename)) {
				result = new ArrayList<>();
				for (EClass c : VSnippetsEditor.SNIPPET_CHILDREN) {
					result.add(new FeatureClass(c.getName(), c));
				}
			} else {
				EReference childRef = null;

				for (EReference ref : targetClass.getEAllReferences()) {
					if (ref.getName().equals(featurename)) {
						childRef = ref;
						break;
					}
				}

				if (childRef == null) {
					return result;
				}

				// Get the parent EClass where this childRef is defined...
				// For instance : for the 'children' reference it will be in
				// UIElementContainer<T extends UIElement>
				// We must check if the selectedContainer extends
				// UIElementContainer<XXX> and in this case childRef is XXX
				final EClass childClass = (EClass) ModelUtils.getTypeArgument(targetClass,
						childRef.getEGenericType());

				// Search for descendant of ChildClass -> This result could be
				// cached for all StringModelFragment editors instances and computed
				// once...
				result = new ArrayList<>();
				for (final InternalPackage p : Util.loadPackages()) {
					for (EClass c : p.getAllClasses()) {
						if (childClass.isSuperTypeOf(c) && isRelevant(c.getName())) {
							result.add(new FeatureClass(c.getName(), c));
						}
					}

				}
			}
		}
		return result;
	}

	// Fix bug 531054 -> This code could be removed when Dialog and WizardDialog
	// will disappear from model !
	static private final List<String> excludeNames = Arrays.asList("Dialog", "WizardDialog");

	// Fix bug 531054 -> This code could be removed when DIalog and WizardDialog
	// will be definitively removed from code (after 2020).
	private static boolean isRelevant(String className)
	{
		// System.out.println("Checking if " + className + " should be kept : " +
		// !excludeNames.contains(className));
		return !excludeNames.contains(className);
	}

}
