/**
 *                                                                            
 *  Copyright (c) 2011, 2016 - 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 v1.0       
 *  which accompanies this distribution, and is available at                  
 *  http://www.eclipse.org/legal/epl-v10.html                                 
 *                                                                            
 *  Contributors:                                                      
 * 	   Florian Pirchner - Initial implementation
 * 
 */
package org.eclipse.osbp.ecview.extension.presentation.vaadin.components;

import java.text.DecimalFormatSymbols;
import java.util.Locale;

import org.eclipse.core.databinding.observable.IObservable;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.emf.databinding.EMFObservables;
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.extension.editparts.IMaskedDecimalFieldEditpart;
import org.eclipse.osbp.ecview.extension.model.YECviewPackage;
import org.eclipse.osbp.ecview.extension.model.YMaskedDecimalField;
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.vaadin.addons.maskedtextfield.DecimalField;

import com.vaadin.data.util.ObjectProperty;
import com.vaadin.server.ErrorMessage;
import com.vaadin.ui.Component;
import com.vaadin.ui.ComponentContainer;
import com.vaadin.ui.Field;

/**
 * This presenter is responsible to render a text field for quantities.
 */
public class MaskedDecimalFieldPresentation extends
		AbstractFieldWidgetPresenter<Component> {

	/** The model access. */
	private final ModelAccess modelAccess;

	/** The text. */
	private CustomMaskedDecimalField text;

	/** The property. */
	private ObjectProperty<Number> property;

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

	/**
	 * {@inheritDoc}
	 */
	@Override
	public Component doCreateWidget(Object parent) {
		if (text == null) {

			text = new CustomMaskedDecimalField();
			text.addStyleName(CSS_CLASS_CONTROL);
			text.setNullRepresentation("");
			text.setImmediate(true);
			setupComponent(text, getCastedModel());

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

			property = new ObjectProperty<Number>(null, Number.class);
			text.setPropertyDataSource(property);

			if(modelAccess.yField.getMask() != null && !modelAccess.yField.getMask().isEmpty()) {
				text.setMask(modelAccess.yField.getMask());
			} else {
				text.setMask("#,##0.00");
			}

			applyDecimals();

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

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

			applyCaptions();

			initializeField(text);
		}
		return text;
	}

	protected void applyDecimals() {
		DecimalFormatSymbols symbols = DecimalFormatSymbols
				.getInstance(getLocale());
		text.setGroupingSeparator(symbols.getGroupingSeparator());
		text.setDecimalSeparator(symbols.getDecimalSeparator());
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.
	 * AbstractVaadinWidgetPresenter#doUpdateLocale(java.util.Locale)
	 */
	@Override
	protected void doUpdateLocale(Locale locale) {
		// no need to set the locale to the ui elements. Is handled by vaadin
		// internally.

		// update the captions
		applyCaptions();
		
		applyDecimals();
	}

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

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

	/*
	 * (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()),
				YECviewPackage.Literals.YMASKED_DECIMAL_FIELD__VALUE);
	}

	/**
	 * Creates the bindings for the given values.
	 *
	 * @param yField
	 *            the y field
	 * @param field
	 *            the field
	 */
	protected void createBindings(YMaskedDecimalField yField, DecimalField field) {
		registerBinding(createBindings_Value(castEObject(getModel()),
				YECviewPackage.Literals.YMASKED_DECIMAL_FIELD__VALUE, text));

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

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

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

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

			// unbind all active bindings
			unbind();

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

			// remove assocations
			unassociateWidget(text);

			text = null;
		}
	}

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

	/**
	 * A helper class.
	 */
	private static class ModelAccess {

		/** The y field. */
		private final YMaskedDecimalField yField;

		/**
		 * Instantiates a new model access.
		 *
		 * @param yField
		 *            the y field
		 */
		public ModelAccess(YMaskedDecimalField 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;
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.
	 * AbstractFieldWidgetPresenter#setConverter(java.lang.Object)
	 */
	@Override
	public void setConverter(Object object) {
		if (object == null) {

		}
		super.setConverter(object);
	}

	/**
	 * The Class CustomMaskedDecimalField.
	 */
	@SuppressWarnings("serial")
	private class CustomMaskedDecimalField extends DecimalField {

		/*
		 * (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;
		}
	}
}
