/**
 *                                                                            
 *  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 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.ecview.extension.presentation.vaadin.components;

import java.util.Locale;

import org.eclipse.core.databinding.Binding;
import org.eclipse.core.databinding.observable.IObservable;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.emf.databinding.EMFObservables;
import org.eclipse.osbp.blob.component.BlobUploadComponent;
import org.eclipse.osbp.ecview.core.common.context.IViewContext;
import org.eclipse.osbp.ecview.core.common.editpart.IElementEditpart;
import org.eclipse.osbp.ecview.core.common.editpart.IEmbeddableEditpart;
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.components.IBlobUploadComponentEditpart;
import org.eclipse.osbp.ecview.extension.model.YBlobUploadComponent;
import org.eclipse.osbp.ecview.extension.model.YECviewPackage;
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.VaadinProperties;
import org.eclipse.osbp.runtime.web.vaadin.databinding.values.IVaadinObservableValue;
import org.eclipse.osbp.ui.api.customfields.IBlobService;
import org.eclipse.osbp.ui.api.metadata.IDSLMetadataService;
import org.eclipse.osbp.ui.api.themes.IThemeResourceService;
import org.eclipse.osbp.ui.api.themes.IThemeResourceService.ThemeResourceType;
import org.eclipse.osbp.ui.api.user.IUser;

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

/**
 * This presenter is responsible to render a text field on the given layout.
 */
public class BlobUploadComponentPresentation extends AbstractFieldWidgetPresenter<Component> {

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

	/** The blob upload comp. */
	private BlobUploadComponent blobUploadComp;

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

	/**
	 * {@inheritDoc}
	 */
	@Override
	public Component doCreateWidget(Object parent) {
		if (blobUploadComp == null) {
			IDSLMetadataService dslMetadataService = getViewContext().getService(IDSLMetadataService.class.getName());
			IBlobService blobService = getViewContext().getService(IBlobService.class.getName());
			IUser user = getViewContext().getService(IUser.class.getName());
			blobUploadComp = new BlobUploadComponent(blobService, dslMetadataService, user);
			blobUploadComp.setDisplayResolutionId(modelAccess.yblobUploadComp.getDisplayResolutionId());
			blobUploadComp.addStyleName(CSS_CLASS_CONTROL);
			blobUploadComp.setImmediate(true);
			setupComponent(blobUploadComp, getCastedModel());

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

			ObjectProperty<String> property = new ObjectProperty<>("", String.class);
			blobUploadComp.setPropertyDataSource(property);

			// creates the binding for the field
			createBindings(modelAccess.yblobUploadComp, blobUploadComp);

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

			applyCaptions();

		}
		return blobUploadComp;
	}

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

	/*
	 * (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
	 */
	@SuppressWarnings("rawtypes")
	protected IObservableValue internalGetValueEndpoint() {
		// return the observable value for text
		return EMFObservables.observeValue(castEObject(getModel()), YECviewPackage.Literals.YBLOB_UPLOAD_COMPONENT__VALUE);
	}

	/**
	 * Creates the bindings for the given values.
	 *
	 * @param yblobUploadComp
	 *            the yblob upload comp
	 * @param blobUploadComp
	 *            the blob upload comp
	 */
	@SuppressWarnings("rawtypes")
	protected void createBindings(YBlobUploadComponent yblobUploadComp, BlobUploadComponent blobUploadComp) {
		// create the model binding from widget to ECView-model

		IObservableValue modelOV = EMFObservables.observeValue(castEObject(getModel()),
				YECviewPackage.Literals.YBLOB_UPLOAD_COMPONENT__VALUE);

		IVaadinObservableValue targetOV = observeUploadedBlobUuid(blobUploadComp);

		Binding b = createBindings(targetOV, modelOV);
		registerBinding(b);

		super.createBindings(yblobUploadComp, blobUploadComp, null);
	}

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

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

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

			// unbind all active bindings
			unbind();

			ComponentContainer parent = ((ComponentContainer) blobUploadComp.getParent());
			if (parent != null) {
				parent.removeComponent(blobUploadComp);
			}

			// remove assocations
			unassociateWidget(blobUploadComp);

			blobUploadComp = null;
		}
	}

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

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

		/** The yblob upload comp. */
		private final YBlobUploadComponent yblobUploadComp;

		/**
		 * Instantiates a new model access.
		 *
		 * @param yField
		 *            the y field
		 */
		public ModelAccess(YBlobUploadComponent yField) {
			super();
			this.yblobUploadComp = 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 yblobUploadComp.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 yblobUploadComp.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 yblobUploadComp.getLabel();
			return yblobUploadComp.getAuthorizationId();
		}

		/**
		 * Returns the label.
		 *
		 * @return the label i18n key
		 */
		public String getLabelI18nKey() {
//			return yblobUploadComp.getLabelI18nKey();
			return yblobUploadComp.getAuthorizationId();
		}
	}

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

	/**
	 * Observe uploaded blob uuid.
	 *
	 * @param component
	 *            the component
	 * @return the i vaadin observable value
	 */
	public static IVaadinObservableValue observeUploadedBlobUuid(BlobUploadComponent component) {
		return VaadinProperties.value().observeVaadinProperty(component);
	}

	/**
	 * Switch it.
	 */
	public void switchIt() {
		IEmbeddableEditpart ep = getEditpart();
		ep.requestUnrender();
		ep.requestRender();
	}
}