/**
 *                                                                            
 *  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.util.Base64;
import java.util.Locale;

import org.eclipse.core.databinding.Binding;
import org.eclipse.core.databinding.UpdateValueStrategy;
import org.eclipse.core.databinding.conversion.Converter;
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.extension.editparts.IRichTextAreaEditpart;
import org.eclipse.osbp.ecview.extension.model.YECviewPackage;
import org.eclipse.osbp.ecview.extension.model.YRichTextArea;
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.databinding.VaadinObservables;

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;
import com.vaadin.ui.RichTextArea;

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

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

	/** The text. */
	private CustomRichTextArea text;

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

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

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

			text = new CustomRichTextArea();
			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<String>(null, String.class);
			text.setPropertyDataSource(property);

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

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

			applyCaptions();

			initializeField(text);
		}
		return text;
	}

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

	/**
	 * 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.YRICH_TEXT_AREA__VALUE);
	}

	/**
	 * Creates the bindings for the given values.
	 *
	 * @param yField
	 *            the y field
	 * @param field
	 *            the field
	 */
	protected void createBindings(YRichTextArea yField, RichTextArea field) {
		// create the model binding from ridget to ECView-model
		if (yField.isUseBlob()) {
			registerBinding(createBindings_BlobValue(castEObject(getModel()),
					YECviewPackage.Literals.YRICH_TEXT_AREA__BLOB_VALUE, text));
		} else {
			registerBinding(createBindings_Value(castEObject(getModel()),
					YECviewPackage.Literals.YRICH_TEXT_AREA__VALUE, text));
		}

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

	/**
	 * Binds the value attribute from the ecview model to the ui element.
	 *
	 * @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 Binding - the created binding
	 */
	protected Binding createBindings_BlobValue(EObject model,
			EStructuralFeature modelFeature, Field<?> field) {
		IBindingManager bindingManager = getViewContext()
				.getService(
						org.eclipse.osbp.ecview.core.common.binding.IECViewBindingManager.class
								.getName());
		if (bindingManager != null) {

			UpdateValueStrategy targetToModel = new UpdateValueStrategy(
					UpdateValueStrategy.POLICY_UPDATE);
			targetToModel.setConverter(new TextToBlobConverter());
			UpdateValueStrategy modelToTarget = new UpdateValueStrategy(
					UpdateValueStrategy.POLICY_UPDATE);
			modelToTarget.setConverter(new BlobToTextConverter());

			// bind the value of yText to textRidget
			IObservableValue modelObservable = EMFObservables.observeValue(
					model, modelFeature);
			IObservableValue uiObservable = VaadinObservables
					.observeValue(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 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 YRichTextArea yField;

		/**
		 * Instantiates a new model access.
		 *
		 * @param yField
		 *            the y field
		 */
		public ModelAccess(YRichTextArea 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 CustomRichTextArea.
	 */
	@SuppressWarnings("serial")
	private class CustomRichTextArea extends RichTextArea {

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

	private static class TextToBlobConverter extends Converter {

		public TextToBlobConverter() {
			super(String.class, byte[].class);
		}

		@Override
		public Object convert(Object fromObject) {
			if (fromObject == null) {
				return null;
			}
			return Base64.getEncoder().encode(((String) fromObject).getBytes());
		}
	}

	private static class BlobToTextConverter extends Converter {

		public BlobToTextConverter() {
			super(byte[].class, String.class);
		}

		@Override
		public Object convert(Object fromObject) {
			if (fromObject == null) {
				return "";
			}
			return new String(Base64.getDecoder().decode((byte[]) fromObject));
		}
	}
}
