/*******************************************************************************
 * Copyright (c) 2011-2019 EclipseSource Muenchen GmbH and others.
 *
 * All rights reserved. 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:
 * Alexandra Buzila - initial API and implementation
 * Lucas Koehler - Also support DMR segments (Bug 542669)
 * Christian W. Damus - bugs 527686, 548592
 ******************************************************************************/
package org.eclipse.emf.ecp.view.internal.editor.controls;

import java.text.MessageFormat;
import java.util.Collection;
import java.util.HashSet;

import javax.inject.Inject;

import org.eclipse.core.databinding.Binding;
import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.UpdateValueStrategy;
import org.eclipse.core.databinding.observable.IObserving;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.databinding.IEMFValueProperty;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecp.common.spi.EMFUtils;
import org.eclipse.emf.ecp.edit.internal.swt.SWTImageHelper;
import org.eclipse.emf.ecp.edit.spi.ReferenceService;
import org.eclipse.emf.ecp.edit.spi.swt.reference.DeleteReferenceAction;
import org.eclipse.emf.ecp.edit.spi.swt.reference.NewReferenceAction;
import org.eclipse.emf.ecp.edit.spi.util.ECPModelElementChangeListener;
import org.eclipse.emf.ecp.spi.common.ui.CompositeFactory;
import org.eclipse.emf.ecp.spi.common.ui.composites.SelectionComposite;
import org.eclipse.emf.ecp.view.internal.editor.handler.CreateDomainModelReferenceWizard;
import org.eclipse.emf.ecp.view.spi.context.ViewModelContext;
import org.eclipse.emf.ecp.view.spi.core.swt.SimpleControlSWTControlSWTRenderer;
import org.eclipse.emf.ecp.view.spi.editor.controls.Helper;
import org.eclipse.emf.ecp.view.spi.label.model.VLabel;
import org.eclipse.emf.ecp.view.spi.model.VControl;
import org.eclipse.emf.ecp.view.spi.model.VDomainModelReference;
import org.eclipse.emf.ecp.view.spi.model.VDomainModelReferenceSegment;
import org.eclipse.emf.ecp.view.spi.model.VFeaturePathDomainModelReference;
import org.eclipse.emf.ecp.view.spi.model.VViewPackage;
import org.eclipse.emf.ecp.view.spi.model.util.VViewResourceImpl;
import org.eclipse.emf.ecp.view.spi.rule.model.LeafCondition;
import org.eclipse.emf.ecp.view.spi.table.model.VTableDomainModelReference;
import org.eclipse.emf.ecp.view.template.model.VTViewTemplateProvider;
import org.eclipse.emf.edit.command.SetCommand;
import org.eclipse.emf.edit.provider.AdapterFactoryItemDelegator;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.emf.edit.provider.ReflectiveItemProviderAdapterFactory;
import org.eclipse.emfforms.spi.common.report.ReportService;
import org.eclipse.emfforms.spi.core.services.databinding.DatabindingFailedException;
import org.eclipse.emfforms.spi.core.services.databinding.DatabindingFailedReport;
import org.eclipse.emfforms.spi.core.services.databinding.EMFFormsDatabinding;
import org.eclipse.emfforms.spi.core.services.databinding.emf.EMFFormsDatabindingEMF;
import org.eclipse.emfforms.spi.core.services.editsupport.EMFFormsEditSupport;
import org.eclipse.emfforms.spi.core.services.label.EMFFormsLabelProvider;
import org.eclipse.emfforms.spi.ide.view.segments.ToolingModeUtil;
import org.eclipse.emfforms.spi.localization.LocalizationServiceHelper;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.databinding.swt.ISWTObservableValue;
import org.eclipse.jface.databinding.swt.typed.WidgetProperties;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StackLayout;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;

/**
 * Renderer for DomainModelReferences.
 *
 * @author Alexandra Buzila
 *
 */
public class DomainModelReferenceControlSWTRenderer extends SimpleControlSWTControlSWTRenderer {

	private final EMFFormsEditSupport emfFormsEditSupport;
	private final EMFFormsDatabindingEMF emfFormsDatabindingEMF;

	/**
	 * Default constructor.
	 *
	 * @param vElement the view model element to be rendered
	 * @param viewContext the view context
	 * @param reportService The {@link ReportService}
	 * @param emfFormsDatabindingEMF The {@link EMFFormsDatabinding}
	 * @param emfFormsLabelProvider The {@link EMFFormsLabelProvider}
	 * @param vtViewTemplateProvider The {@link VTViewTemplateProvider}
	 * @param emfFormsEditSupport The {@link EMFFormsEditSupport}
	 */
	@Inject
	public DomainModelReferenceControlSWTRenderer(VControl vElement, ViewModelContext viewContext,
		ReportService reportService, EMFFormsDatabindingEMF emfFormsDatabindingEMF,
		EMFFormsLabelProvider emfFormsLabelProvider, VTViewTemplateProvider vtViewTemplateProvider,
		EMFFormsEditSupport emfFormsEditSupport) {
		super(vElement, viewContext, reportService, emfFormsDatabindingEMF, emfFormsLabelProvider,
			vtViewTemplateProvider);
		this.emfFormsDatabindingEMF = emfFormsDatabindingEMF;
		this.emfFormsEditSupport = emfFormsEditSupport;
	}

	private Composite mainComposite;
	private StackLayout stackLayout;
	private Label unsetLabel;
	private EObject eObject;
	private EStructuralFeature structuralFeature;
	// private Setting setting;
	private ECPModelElementChangeListener modelElementChangeListener;
	private ComposedAdapterFactory composedAdapterFactory;
	private AdapterFactoryItemDelegator adapterFactoryItemDelegator;
	private Composite parentComposite;
	private Label setLabel;
	private Label imageLabel;
	private Composite contentSetComposite;
	private Button setBtn;

	@Override
	protected Binding[] createBindings(Control control) throws DatabindingFailedException {

		final Binding[] bindings = new Binding[3];
		final IObservableValue value = WidgetProperties.text().observe(setLabel);

		bindings[0] = getDataBindingContext().bindValue(value, getModelValue(),
			withPreSetValidation(new UpdateValueStrategy() {

				@Override
				public Object convert(Object value) { // target to model
					try {
						return getModelValue().getValue();
					} catch (final DatabindingFailedException ex) {
						getReportService().report(new DatabindingFailedReport(ex));
						return null;
					}
				}
			}), new UpdateValueStrategy() {// model to target
				@Override
				public Object convert(Object value) {
					updateChangeListener((EObject) value);
					return getText(value);
				}
			});

		final IObservableValue imageValue = WidgetProperties.image().observe(imageLabel);
		bindings[1] = getDataBindingContext().bindValue(imageValue, getModelValue(),
			withPreSetValidation(new UpdateValueStrategy(UpdateValueStrategy.POLICY_NEVER)),
			new UpdateValueStrategy() {
				@Override
				public Object convert(Object value) {
					return getImage(value);
				}
			});

		final ISWTObservableValue setLabelTooltip = WidgetProperties.tooltipText().observe(setLabel);
		bindings[2] = getDataBindingContext().bindValue(
			setLabelTooltip,
			getModelValue(),
			withPreSetValidation(new UpdateValueStrategy(UpdateValueStrategy.POLICY_NEVER)),
			new UpdateValueStrategy() {
				@Override
				public Object convert(Object value) {
					if (!EObject.class.isInstance(value)) {
						return ""; //$NON-NLS-1$
					}
					final EObject eObject = EObject.class.cast(value);
					final Resource resource = eObject.eResource();
					if (!VViewResourceImpl.class.isInstance(resource)) {
						return ""; //$NON-NLS-1$
					}
					final String id = VViewResourceImpl.class.cast(resource).getID(eObject);
					return MessageFormat.format("UUID: {0}", id); //$NON-NLS-1$
				}
			});
		return bindings;
	}

	private Object getImage(Object value) {
		final Object image = adapterFactoryItemDelegator.getImage(value);
		return SWTImageHelper.getImage(image);
	}

	// TODO this whole method is ugly as it has to many dependencies, the generating of the text should be delegated to
	// some service
	// BEGIN COMPLEX CODE
	private Object getText(Object object) {
		if (ToolingModeUtil.isSegmentToolingEnabled()) {
			return getTextForSegments((VDomainModelReference) object);
		}

		VFeaturePathDomainModelReference modelReference = (VFeaturePathDomainModelReference) object;
		if (VTableDomainModelReference.class.isInstance(modelReference)) {
			VTableDomainModelReference tableRef = VTableDomainModelReference.class.cast(modelReference);
			while (tableRef.getDomainModelReference() != null
				&& VTableDomainModelReference.class.isInstance(tableRef.getDomainModelReference())) {
				tableRef = VTableDomainModelReference.class.cast(tableRef.getDomainModelReference());
			}
			modelReference = (VFeaturePathDomainModelReference) tableRef.getDomainModelReference();
		}
		if (modelReference == null) {
			return null;
		}
		final EStructuralFeature value = modelReference.getDomainModelEFeature();

		String className = ""; //$NON-NLS-1$
		final String attributeName = " -> " + adapterFactoryItemDelegator.getText(value); //$NON-NLS-1$
		String referencePath = ""; //$NON-NLS-1$

		for (final EReference ref : modelReference.getDomainModelEReferencePath()) {
			if (className.isEmpty()) {
				className = ref.getEContainingClass().getName();
			}
			referencePath = referencePath + " -> " + adapterFactoryItemDelegator.getText(ref); //$NON-NLS-1$
		}
		if (className.isEmpty() && modelReference.getDomainModelEFeature() != null
			&& modelReference.getDomainModelEFeature().getEContainingClass() != null) {
			className = modelReference.getDomainModelEFeature().getEContainingClass().getName();
		}

		final String linkText = className + referencePath + attributeName;
		if (linkText.equals(" -> ")) { //$NON-NLS-1$
			return null;
		}
		return linkText;
	}
	// END COMPLEX CODE

	/**
	 * Provides a label text for a segment based DMR.
	 */
	private String getTextForSegments(VDomainModelReference dmr) {
		final EList<VDomainModelReferenceSegment> segments = dmr.getSegments();
		if (segments.isEmpty()) {
			return adapterFactoryItemDelegator.getText(dmr);
		}

		String attributeType = null;
		final EClass rootEClass = getDmrRootEClass();
		try {
			final IEMFValueProperty valueProperty = emfFormsDatabindingEMF.getValueProperty(
				dmr, rootEClass);
			attributeType = valueProperty.getStructuralFeature().getEType().getName();
		} catch (final DatabindingFailedException ex) {
			// TODO handle?
		}

		final String className = rootEClass.getName();
		String attributeName = " -> " + adapterFactoryItemDelegator.getText(segments.get(segments.size() - 1)); //$NON-NLS-1$
		if (attributeType != null && !attributeType.isEmpty()) {
			attributeName += " : " + attributeType; //$NON-NLS-1$
		}
		String referencePath = ""; //$NON-NLS-1$

		for (int i = 0; i < segments.size() - 1; i++) {
			referencePath = referencePath + " -> " //$NON-NLS-1$
				+ adapterFactoryItemDelegator.getText(segments.get(i));
		}

		final String linkText = className + referencePath + attributeName;
		if (linkText.equals(" -> ")) { //$NON-NLS-1$
			return null;
		}
		return linkText;
	}

	private void updateChangeListener(final EObject value) {
		if (modelElementChangeListener != null) {
			if (modelElementChangeListener.getTarget().equals(value)) {
				return;
			}
			modelElementChangeListener.remove();
			modelElementChangeListener = null;
		}

		if (value == null) {
			if (stackLayout.topControl != unsetLabel) {
				stackLayout.topControl = unsetLabel;
				mainComposite.layout();
			}

		} else {
			if (stackLayout.topControl != contentSetComposite) {
				stackLayout.topControl = contentSetComposite;
				mainComposite.layout();
			}

			modelElementChangeListener = new ECPModelElementChangeListener(value) {

				@Override
				public void onChange(Notification notification) {
					Display.getDefault().syncExec(() -> getDataBindingContext().updateTargets());
				}
			};
		}
	}

	@Override
	protected Control createSWTControl(Composite parent) throws DatabindingFailedException {
		final IObservableValue<?> observableValue = getEMFFormsDatabinding()
			.getObservableValue(getVElement().getDomainModelReference(), getViewModelContext().getDomainModel());
		eObject = (EObject) ((IObserving) observableValue).getObserved();
		structuralFeature = (EStructuralFeature) observableValue.getValueType();
		observableValue.dispose();

		final Composite containerComposite = new Composite(parent, SWT.NONE);
		containerComposite.setBackground(parent.getBackground());
		GridLayoutFactory.fillDefaults().applyTo(containerComposite);
		GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.BEGINNING).applyTo(containerComposite);

		parentComposite = new Composite(containerComposite, SWT.NONE);
		parentComposite.setBackground(parent.getBackground());
		GridLayoutFactory.fillDefaults().numColumns(4).spacing(0, 0).equalWidth(false)
			.applyTo(parentComposite);
		GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.BEGINNING).applyTo(parentComposite);

		stackLayout = new StackLayout();

		mainComposite = new Composite(parentComposite, SWT.NONE);
		mainComposite.setBackground(parentComposite.getBackground());
		GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.CENTER).applyTo(mainComposite);
		mainComposite.setLayout(stackLayout);

		unsetLabel = new Label(mainComposite, SWT.NONE);
		GridDataFactory.fillDefaults().grab(true, true).align(SWT.FILL, SWT.FILL).applyTo(unsetLabel);
		unsetLabel.setText(
			LocalizationServiceHelper.getString(DomainModelReferenceControlSWTRenderer.class, "LinkControl_NotSet")); //$NON-NLS-1$
		unsetLabel.setBackground(mainComposite.getBackground());
		unsetLabel.setForeground(parentComposite.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY));
		unsetLabel.setAlignment(SWT.CENTER);

		contentSetComposite = new Composite(mainComposite, SWT.NONE);
		GridLayoutFactory.fillDefaults().numColumns(2).equalWidth(false).applyTo(contentSetComposite);
		contentSetComposite.setBackground(mainComposite.getBackground());
		imageLabel = new Label(contentSetComposite, SWT.NONE);
		imageLabel.setBackground(contentSetComposite.getBackground());
		GridDataFactory.fillDefaults().grab(false, false).align(SWT.FILL, SWT.FILL).hint(17, SWT.DEFAULT)
			.applyTo(imageLabel);
		setLabel = new Label(contentSetComposite, SWT.NONE);
		setLabel.setBackground(contentSetComposite.getBackground());
		GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.FILL).applyTo(setLabel);

		if (eObject.eIsSet(structuralFeature)) {
			stackLayout.topControl = contentSetComposite;
		} else {
			stackLayout.topControl = unsetLabel;
		}

		createButtons(parentComposite);

		composedAdapterFactory = new ComposedAdapterFactory(new AdapterFactory[] {
			new ReflectiveItemProviderAdapterFactory(),
			new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE) });
		adapterFactoryItemDelegator = new AdapterFactoryItemDelegator(composedAdapterFactory);

		return containerComposite;
	}

	/**
	 * @param parentComposite
	 * @throws DatabindingFailedException
	 */
	private void createButtons(Composite composite) throws DatabindingFailedException {
		final Button unsetBtn = createButtonForAction(new DeleteReferenceAction(getEditingDomain(eObject), eObject,
			structuralFeature, null), composite);
		unsetBtn.addSelectionListener(new SelectionListener() {

			@Override
			public void widgetSelected(SelectionEvent e) {
				final Command setCommand = SetCommand.create(getEditingDomain(eObject), eObject, structuralFeature,
					SetCommand.UNSET_VALUE);
				getEditingDomain(eObject).getCommandStack().execute(setCommand);
			}

			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
				// TODO Auto-generated method stub
			}
		});

		setBtn = createButtonForAction(new NewReferenceAction(getEditingDomain(eObject), eObject,
			structuralFeature, emfFormsEditSupport, getEMFFormsLabelProvider(), null, getReportService(), getVElement()
				.getDomainModelReference(),
			getViewModelContext().getDomainModel()), composite); // getViewModelContext().getService(ReferenceService.class)
		setBtn.addSelectionListener(new SelectionAdapterExtension(setLabel, getModelValue(), getViewModelContext(),
			getDataBindingContext(), (EReference) structuralFeature));

	}

	/**
	 * A helper method which creates a button for an action on a composite.
	 *
	 * @param action the action to create a button for
	 * @param composite the composite to create the button onto
	 * @return the created button
	 */
	protected Button createButtonForAction(final Action action, final Composite composite) {
		final Button selectButton = new Button(composite, SWT.PUSH);
		selectButton.setImage(Activator.getImage(action));
		selectButton.setEnabled(true);
		selectButton.setToolTipText(action.getToolTipText());
		return selectButton;
	}

	@Override
	protected String getUnsetText() {
		return LocalizationServiceHelper.getString(getClass(), "LinkControl_NoLinkSetClickToSetLink"); //$NON-NLS-1$
	}

	/**
	 * Create a new segment based domain model reference and set it in the <code>reference</code> of the given
	 * <code>container</code> object.
	 *
	 * @param container The EObject which will contain the new domain model reference
	 * @param reference The EReference which the new domain model reference will be set in
	 */
	protected void addNewSegmentDmr(EObject container, EReference reference) {
		final ReferenceService referenceService = getViewModelContext().getService(ReferenceService.class);
		referenceService.addNewModelElements(eObject, (EReference) structuralFeature, false);
	}

	/**
	 * Edits the existing DMR set in the <code>reference</code> of the given
	 * <code>container</code> object.
	 *
	 * @param container The EObject which will contain the new domain model reference
	 * @param reference The EReference which contains the current new domain model reference
	 * @param dmr The domain model reference to edit
	 */
	protected void editSegmentDmr(EObject container, EReference reference, VDomainModelReference dmr) {
		final ReferenceService referenceService = getViewModelContext().getService(ReferenceService.class);
		referenceService.openInNewContext(dmr);
	}

	/**
	 * Returns the root EClass of the domain model reference.
	 *
	 * @return the DMR's root EClass.
	 */
	protected EClass getDmrRootEClass() {
		return Helper.getRootEClass(getViewModelContext().getDomainModel());
	}

	@Override
	protected void rootDomainModelChanged() throws DatabindingFailedException {
		final IObservableValue<?> observableValue = getEMFFormsDatabinding()
			.getObservableValue(getVElement().getDomainModelReference(), getViewModelContext().getDomainModel());
		try {
			eObject = (EObject) ((IObserving) observableValue).getObserved();
		} finally {
			observableValue.dispose();
		}

		super.rootDomainModelChanged();
	}

	@Override
	public void scrollToReveal() {
		if (canReveal(setBtn) && setBtn.isEnabled()) {
			scrollToReveal(setBtn);
		} else {
			super.scrollToReveal();
		}
	}

	/** SelectionAdapter for the set button. */
	private class SelectionAdapterExtension extends SelectionAdapter {

		private final EReference eReference;

		SelectionAdapterExtension(Label label, IObservableValue<?> modelValue, ViewModelContext viewModelContext,
			DataBindingContext dataBindingContext, EReference eReference) {
			this.eReference = eReference;
		}

		@Override
		public void widgetSelected(SelectionEvent e) {
			final EClass eclass = getDmrRootEClass();

			VDomainModelReference reference = null;
			if (VControl.class.isInstance(eObject)) {
				reference = VControl.class.cast(eObject).getDomainModelReference();
			} else if (VLabel.class.isInstance(eObject)) {
				reference = VLabel.class.cast(eObject).getDomainModelReference();
			} else if (eObject instanceof LeafCondition) {
				reference = LeafCondition.class.cast(eObject).getDomainModelReference();
			}

			if (ToolingModeUtil.isSegmentToolingEnabled()) {
				if (reference == null) {
					addNewSegmentDmr(eObject, eReference);
				} else {
					editSegmentDmr(eObject, eReference, reference);
				}
			} else {
				final Collection<EClass> classes = EMFUtils.getSubClasses(eReference.getEReferenceType());
				// Don't allow to create a plain DMR legacy mode
				classes.remove(VViewPackage.Literals.DOMAIN_MODEL_REFERENCE);

				final CreateDomainModelReferenceWizard wizard = new CreateDomainModelReferenceWizard(
					eObject, structuralFeature, getEditingDomain(eObject), eclass,
					reference == null ? "New Reference Element" : "Configure " + reference.eClass().getName(), //$NON-NLS-1$ //$NON-NLS-2$
					LocalizationServiceHelper.getString(DomainModelReferenceControlSWTRenderer.class,
						"NewModelElementWizard_WizardTitle_AddModelElement"), //$NON-NLS-1$
					LocalizationServiceHelper.getString(DomainModelReferenceControlSWTRenderer.class,
						"NewModelElementWizard_PageTitle_AddModelElement"), //$NON-NLS-1$
					LocalizationServiceHelper.getString(DomainModelReferenceControlSWTRenderer.class,
						"NewModelElementWizard_PageDescription_AddModelElement"), //$NON-NLS-1$
					reference);

				final SelectionComposite<TreeViewer> helper = CompositeFactory.getSelectModelClassComposite(
					new HashSet<EPackage>(),
					new HashSet<EPackage>(), classes);
				wizard.setCompositeProvider(helper);
				new WizardDialog(Display.getDefault().getActiveShell(), wizard).open();
			}

		}
	}
}
