/**
 * Copyright (c) 2011, 2015 - Lunifera GmbH (Gross Enzersdorf, Austria), Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
 * 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:
 *         Florian Pirchner - Initial implementation
 */
package org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.internal;

import java.util.Locale;

import org.eclipse.core.databinding.Binding;
import org.eclipse.core.databinding.UpdateValueStrategy;
import org.eclipse.core.databinding.observable.IObservable;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.emf.databinding.EMFObservables;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.osbp.ecview.core.common.editpart.IElementEditpart;
import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddableBindingEndpoint;
import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddableValueEndpoint;
import org.eclipse.osbp.ecview.core.common.model.core.YValueBindable;
import org.eclipse.osbp.ecview.core.common.model.datatypes.YDatatype;
import org.eclipse.osbp.ecview.core.extension.model.datatypes.YNumericDatatype;
import org.eclipse.osbp.ecview.core.extension.model.extension.ExtensionModelPackage;
import org.eclipse.osbp.ecview.core.extension.model.extension.YNumericField;
import org.eclipse.osbp.ecview.core.ui.core.editparts.extension.INumericFieldEditpart;
import org.eclipse.osbp.ecview.core.util.emf.ModelUtil;
import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.IBindingManager;
import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.AbstractFieldWidgetPresenter;
import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.internal.util.Util;
import org.eclipse.osbp.runtime.web.vaadin.components.converter.NumberConverter;
import org.eclipse.osbp.runtime.web.vaadin.components.fields.NumericField;
import org.eclipse.osbp.runtime.web.vaadin.databinding.VaadinObservables;

import com.vaadin.data.Property;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.util.ObjectProperty;
import com.vaadin.data.util.converter.Converter;
import com.vaadin.server.ErrorMessage;
import com.vaadin.ui.AbstractField;
import com.vaadin.ui.Component;
import com.vaadin.ui.ComponentContainer;
import com.vaadin.ui.Field;

// TODO: Auto-generated Javadoc
/**
 * This presenter is responsible to render a text area on the given layout.
 */
public class NumericFieldPresentation extends
		AbstractFieldWidgetPresenter<Component> {

	/** The model access. */
	private final ModelAccess modelAccess;
	
	/** The number field. */
	private CustomField numberField;
	
	/** The binding_value to ui. */
	private Binding binding_valueToUI;
	
	/** The property. */
	private ObjectProperty<Double> property;

	/**
	 * Constructor.
	 * 
	 * @param editpart
	 *            The editpart of that presenter
	 */
	public NumericFieldPresentation(IElementEditpart editpart) {
		super((INumericFieldEditpart) editpart);
		this.modelAccess = new ModelAccess((YNumericField) editpart.getModel());
	}

	/**
	 * {@inheritDoc}
	 */
	@SuppressWarnings("serial")
	@Override
	public Component doCreateWidget(Object parent) {
		if (numberField == null) {

			numberField = new CustomField((NumberConverter) getConverter());
			numberField.addStyleName(CSS_CLASS_CONTROL);
			numberField.setImmediate(true);
			setupComponent(numberField, getCastedModel());

			associateWidget(numberField, modelAccess.yField);
			if (modelAccess.isCssIdValid()) {
				numberField.setId(modelAccess.getCssID());
			} else {
				numberField.setId(getEditpart().getId());
			}

			property = new ObjectProperty<Double>(0d, Double.class);
			numberField.setPropertyDataSource(property);

			numberField
					.addValueChangeListener(new Property.ValueChangeListener() {
						@Override
						public void valueChange(ValueChangeEvent event) {
							if (binding_valueToUI != null) {
								binding_valueToUI.updateTargetToModel();

								Binding domainToEObjectBinding = ModelUtil
										.getValueBinding((YValueBindable) getModel());
								if (domainToEObjectBinding != null) {
									domainToEObjectBinding
											.updateTargetToModel();
								}
							}
						}
					});

			if (modelAccess.isCssClassValid()) {
				numberField.addStyleName(modelAccess.getCssClass());
			}

			applyCaptions();
			doApplyDatatype(modelAccess.yField.getDatatype());

			initializeField(numberField);

			// creates the binding for the field
			createBindings(modelAccess.yField, numberField);

			// send an event, that the content was rendered again
			sendRenderedLifecycleEvent();

		}
		return numberField;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.AbstractFieldWidgetPresenter#getDefaultConverter()
	 */
	@Override
	protected Converter<?, ?> getDefaultConverter() {
		return new NumberConverter();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.AbstractFieldWidgetPresenter#doUpdateConverter(com.vaadin.data.util.converter.Converter)
	 */
	@SuppressWarnings("rawtypes")
	protected void doUpdateConverter(Converter converter) {
		super.doUpdateConverter(converter);

		// if converter changes, then apply the settings from datatype to it
		doApplyDatatype(modelAccess.yField.getDatatype());
	}

	/**
	 * Applies the datatype options to the field.
	 *
	 * @param yDt
	 *            the y dt
	 */
	protected void doApplyDatatype(YDatatype yDt) {
		if (numberField == null) {
			return;
		}
		if (yDt == null) {
			numberField.setUseGrouping(true);
			numberField.setMarkNegative(true);
		} else {
			YNumericDatatype yCasted = (YNumericDatatype) yDt;
			numberField.setUseGrouping(yCasted.isGrouping());
			numberField.setMarkNegative(yCasted.isMarkNegative());
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.AbstractVaadinWidgetPresenter#doUpdateLocale(java.util.Locale)
	 */
	@Override
	protected void doUpdateLocale(Locale locale) {
		// update the captions
		applyCaptions();

		// tell the number field about the locale change
		if(numberField != null) {
			numberField.setLocale(locale);
		}
	}

	/**
	 * Applies the labels to the widgets.
	 */
	protected void applyCaptions() {
		Util.applyCaptions(getI18nService(), modelAccess.getLabel(),
				modelAccess.getLabelI18nKey(), getLocale(), numberField);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.AbstractFieldWidgetPresenter#doGetField()
	 */
	@Override
	protected Field<?> doGetField() {
		return numberField;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.AbstractVaadinWidgetPresenter#internalGetObservableEndpoint(org.eclipse.osbp.ecview.core.common.model.core.YEmbeddableBindingEndpoint)
	 */
	@Override
	protected IObservable internalGetObservableEndpoint(
			YEmbeddableBindingEndpoint bindableValue) {
		if (bindableValue == null) {
			throw new IllegalArgumentException(
					"BindableValue must not be null!");
		}

		if (bindableValue instanceof YEmbeddableValueEndpoint) {
			return internalGetValueEndpoint();
		}
		throw new IllegalArgumentException("Not a valid input: "
				+ bindableValue);
	}

	/**
	 * Returns the observable to observe value.
	 *
	 * @return the i observable value
	 */
	protected IObservableValue internalGetValueEndpoint() {
		// return the observable value for text
		return EMFObservables.observeValue(castEObject(getModel()),
				ExtensionModelPackage.Literals.YNUMERIC_FIELD__VALUE);
	}

	/**
	 * Creates the bindings for the given values.
	 *
	 * @param yField
	 *            the y field
	 * @param field
	 *            the field
	 */
	protected void createBindings(YNumericField yField, NumericField field) {
		// create the model binding from ridget to ECView-model

		binding_valueToUI = createModelBinding(castEObject(getModel()),
				ExtensionModelPackage.Literals.YNUMERIC_FIELD__VALUE, field,
				null, null);

		registerBinding(binding_valueToUI);

		super.createBindings(yField, field, null);
	}

	/**
	 * Creates the model binding.
	 *
	 * @param model
	 *            the model
	 * @param modelFeature
	 *            the model feature
	 * @param field
	 *            the field
	 * @param targetToModel
	 *            the target to model
	 * @param modelToTarget
	 *            the model to target
	 * @return the binding
	 */
	protected Binding createModelBinding(EObject model,
			EStructuralFeature modelFeature, AbstractField<?> field,
			UpdateValueStrategy targetToModel, UpdateValueStrategy modelToTarget) {
		IBindingManager bindingManager = getViewContext()
				.getService(
						org.eclipse.osbp.ecview.core.common.binding.IECViewBindingManager.class
								.getName());
		if (bindingManager != null) {
			// bind the value of yText to textRidget
			IObservableValue modelObservable = EMFObservables.observeValue(
					model, modelFeature);
			IObservableValue uiObservable = VaadinObservables
					.observeConvertedValue(field);
			return bindingManager.bindValue(uiObservable, modelObservable,
					targetToModel, modelToTarget);
		}
		return null;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ecview.core.common.presentation.IWidgetPresentation#getWidget()
	 */
	@Override
	public Component getWidget() {
		return numberField;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ecview.core.common.presentation.IWidgetPresentation#isRendered()
	 */
	@Override
	public boolean isRendered() {
		return numberField != null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void doUnrender() {
		if (numberField != null) {

			// unbind all active bindings
			unbind();

			Component parent = ((Component) numberField.getParent());
			if (parent != null && parent instanceof ComponentContainer) {
				((ComponentContainer) parent).removeComponent(numberField);
			}

			// remove assocations
			unassociateWidget(numberField);

			numberField = null;
		}
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected void internalDispose() {
		try {
			unrender();
		} finally {
			super.internalDispose();
		}
	}

	/**
	 * A helper class.
	 */
	private static class ModelAccess {
		
		/** The y field. */
		private final YNumericField yField;

		/**
		 * Instantiates a new model access.
		 *
		 * @param yField
		 *            the y field
		 */
		public ModelAccess(YNumericField yField) {
			super();
			this.yField = yField;
		}

		/**
		 * Gets the css class.
		 *
		 * @return the css class
		 * @see org.eclipse.osbp.ecview.core.ui.core.model.core.YCssAble#getCssClass()
		 */
		public String getCssClass() {
			return yField.getCssClass();
		}

		/**
		 * Returns true, if the css class is not null and not empty.
		 *
		 * @return true, if is css class valid
		 */
		public boolean isCssClassValid() {
			return getCssClass() != null && !getCssClass().equals("");
		}

		/**
		 * Gets the css id.
		 *
		 * @return the css id
		 * @see org.eclipse.osbp.ecview.core.ui.core.model.core.YCssAble#getCssID()
		 */
		public String getCssID() {
			return yField.getCssID();
		}

		/**
		 * Returns true, if the css id is not null and not empty.
		 *
		 * @return true, if is css id valid
		 */
		public boolean isCssIdValid() {
			return getCssID() != null && !getCssID().equals("");
		}

		/**
		 * Returns the label.
		 *
		 * @return the label
		 */
		public String getLabel() {
			return yField.getDatadescription() != null ? yField
					.getDatadescription().getLabel() : null;
		}

		/**
		 * Returns the label.
		 *
		 * @return the label i18n key
		 */
		public String getLabelI18nKey() {
			return yField.getDatadescription() != null ? yField
					.getDatadescription().getLabelI18nKey() : null;
		}
	}

	/**
	 * The Class CustomField.
	 */
	@SuppressWarnings("serial")
	private class CustomField extends NumericField {

		/**
		 * Instantiates a new custom field.
		 *
		 * @param converter
		 *            the converter
		 */
		public CustomField(NumberConverter converter) {
			super("", converter);
		}

		/* (non-Javadoc)
		 * @see com.vaadin.ui.AbstractField#getErrorMessage()
		 */
		@Override
		public ErrorMessage getErrorMessage() {
			if(isDisposed()) {
				// after disposal, Vaadin will call this method once.
				return null;
			}

			ErrorMessage message = super.getErrorMessage();
			reportValidationError(message);
			return message;
		}
		
		public void clear() {
			setValue("0");
		}
	}
}
