/**
 *                                                                            
 *  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.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.list.IObservableList;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.emf.databinding.EMFObservables;
import org.eclipse.emf.databinding.EMFProperties;
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.YEmbeddableCollectionEndpoint;
import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddableSelectionEndpoint;
import org.eclipse.osbp.ecview.core.databinding.emf.model.ECViewModelBindable;
import org.eclipse.osbp.ecview.extension.editparts.components.IPairComboBoxEditpart;
import org.eclipse.osbp.ecview.extension.model.YECviewPackage;
import org.eclipse.osbp.ecview.extension.model.YPairComboBox;
import org.eclipse.osbp.runtime.common.state.ISharedStateContext;
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.common.data.BeanServiceLazyLoadingContainer;
import org.eclipse.osbp.runtime.web.vaadin.common.data.DeepResolvingBeanItemContainer;
import org.eclipse.osbp.runtime.web.vaadin.common.data.IBeanSearchServiceFactory;
import org.eclipse.osbp.runtime.web.vaadin.components.widget.LazyLoadingComboBox;
import org.eclipse.osbp.runtime.web.vaadin.databinding.VaadinObservables;
import org.eclipse.xtext.util.Pair;
import org.eclipse.xtext.util.Tuples;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.vaadin.data.Container;
import com.vaadin.data.Container.Sortable;
import com.vaadin.data.Property;
import com.vaadin.data.util.ObjectProperty;
import com.vaadin.server.Resource;
import com.vaadin.server.ThemeResource;
import com.vaadin.ui.AbstractSelect.ItemCaptionMode;
import com.vaadin.ui.Component;
import com.vaadin.ui.ComponentContainer;
import com.vaadin.ui.Field;

@SuppressWarnings("restriction")
public class PairComboBoxPresentation extends AbstractFieldWidgetPresenter<Component> {

	/** The Constant LOGGER. */
	private static final Logger LOGGER = LoggerFactory.getLogger(PairComboBoxPresentation.class);

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

	/** The combo. */
	private LazyLoadingComboBox combo;

	/** The property. */
	@SuppressWarnings("rawtypes")
	private ObjectProperty property;

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

	/**
	 * {@inheritDoc}
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public Component doCreateWidget(Object parent) {
		if (combo == null) {

			combo = new CustomComboBox();
			combo.addStyleName(CSS_CLASS_CONTROL);
			combo.setImmediate(true);
			setupComponent(combo, getCastedModel());

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

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

			try {
				property = new ObjectProperty(null, modelAccess.yField.getType());
				combo.setPropertyDataSource(property);

				if (modelAccess.yField.getType() != null) {
					if (!modelAccess.yField.isUseBeanService()) {
						DeepResolvingBeanItemContainer datasource = new DeepResolvingBeanItemContainer(modelAccess.yField.getType());
						combo.setContainerDataSource(datasource);
					} else {
						IBeanSearchServiceFactory factory = getViewContext().getService(IBeanSearchServiceFactory.class.getName());
						if (factory != null) {
							ISharedStateContext sharedState = getViewContext().getService(ISharedStateContext.class.getName());
							BeanServiceLazyLoadingContainer<?> datasource = new BeanServiceLazyLoadingContainer(
									factory.createService(modelAccess.yField.getType()), modelAccess.yField.getType(), sharedState);
							combo.setContainerDataSource(datasource);
						}
					}
				}

				String itemCaptionProperty = modelAccess.yField.getCaptionProperty();
				if (itemCaptionProperty != null && !itemCaptionProperty.equals("")) {
					combo.setItemCaptionPropertyId(itemCaptionProperty);
					combo.setItemCaptionMode(ItemCaptionMode.PROPERTY);

					Container container = combo.getContainerDataSource();
					if (container instanceof Container.Sortable) {
						Container.Sortable sortable = (Sortable) container;
						sortable.sort(new Object[] { itemCaptionProperty }, new boolean[] { true });
					}
				} else {
					combo.setItemCaptionMode(ItemCaptionMode.ID);
				}

				String itemImageProperty = modelAccess.yField.getImageProperty();
				if (itemImageProperty != null && !itemImageProperty.equals("")) {
					combo.setItemIconPropertyId(itemImageProperty);
				}

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

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

				applyCaptions();

				initializeField(combo);
			} catch (Exception e) {
				LOGGER.error("{}", e);
			}
		}
		return combo;
	}

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

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

	/*
	 * (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 YEmbeddableCollectionEndpoint) {
			return internalGetCollectionEndpoint();
		} else if (bindableValue instanceof YEmbeddableSelectionEndpoint) {
			return internalGetSelectionEndpoint((YEmbeddableSelectionEndpoint) bindableValue);
		}
		throw new IllegalArgumentException("Not a valid input: " + bindableValue);
	}

	/**
	 * Returns the observable to observe the collection.
	 *
	 * @return the i observable list
	 */
	protected IObservableList internalGetCollectionEndpoint() {
		// return the observable value for text
		return EMFProperties.list(YECviewPackage.Literals.YPAIR_COMBO_BOX__COLLECTION).observe(getModel());
	}

	/**
	 * Returns the observable to observe the selection.
	 *
	 * @param yEndpoint
	 *            the y endpoint
	 * @return the i observable value
	 */
	protected IObservableValue internalGetSelectionEndpoint(YEmbeddableSelectionEndpoint yEndpoint) {

		String attributePath = ECViewModelBindable.getAttributePath(YECviewPackage.Literals.YPAIR_COMBO_BOX__SELECTION,
				yEndpoint.getAttributePath());

		// return the observable value for text
		return ECViewModelBindable.observeValue(castEObject(getModel()), attributePath, modelAccess.yField.getType(),
				modelAccess.yField.getEmfNsURI());
	}

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

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

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

			// unbind all active bindings
			unbind();

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

			// remove assocations
			unassociateWidget(combo);

			combo = null;
		}
	}

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

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

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

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

	/**
	 * Converts the string value of the item icon property to
	 * {@link ThemeResource}.
	 */
	@SuppressWarnings("serial")
	private static class CustomComboBox extends LazyLoadingComboBox {

		/** The item icon property id. */
		private Object itemIconPropertyId;

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * com.vaadin.ui.AbstractSelect#setItemIconPropertyId(java.lang.Object)
		 */
		@Override
		public void setItemIconPropertyId(Object propertyId) throws IllegalArgumentException {
			if (propertyId == null) {
				super.setItemIconPropertyId(propertyId);
			} else if (!getContainerPropertyIds().contains(propertyId)) {
				super.setItemIconPropertyId(propertyId);
			} else if (String.class.isAssignableFrom(getType(propertyId))) {
				itemIconPropertyId = propertyId;
			} else {
				super.setItemIconPropertyId(propertyId);
			}
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see com.vaadin.ui.AbstractSelect#getItemIconPropertyId()
		 */
		public Object getItemIconPropertyId() {
			return itemIconPropertyId != null ? itemIconPropertyId : super.getItemIconPropertyId();
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see com.vaadin.ui.AbstractSelect#getItemIcon(java.lang.Object)
		 */
		public Resource getItemIcon(Object itemId) {
			if (itemIconPropertyId == null) {
				return super.getItemIcon(itemId);
			} else {
				final Property<?> ip = getContainerProperty(itemId, getItemIconPropertyId());
				if (ip == null) {
					return null;
				}
				final Object icon = ip.getValue();
				try {
					if (icon instanceof String) {
						return new ThemeResource((String) icon);
					}
				} catch (Exception e) {
					// nothing to do
				}
			}
			return 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);
	}

	/**
	 * Creates the bindings for the given values.
	 *
	 * @param yField
	 *            the y field
	 * @param field
	 *            the field
	 */
	protected void createBindings(YPairComboBox yField, LazyLoadingComboBox field) {
		// create the model binding from ridget to ECView-model
		// registerBinding(createBindings_ContainerContents(castEObject(getModel()),
		// YECviewPackage.Literals.YPAIR_COMBO_BOX__COLLECTION,
		// field));
		// create the model binding from ridget to ECView-model
		registerBinding(createBindings_ContainerContents(castEObject(getModel()), YECviewPackage.Literals.YPAIR_COMBO_BOX__COLLECTION,
				field, yField.getType()));

		// create the model binding from ridget to ECView-model
		// registerBinding(createBindingsPairSelection(castEObject(getModel()),
		// YECviewPackage.Literals.YPAIR_COMBO_BOX__SELECTION, field,
		// yField.getType()));
		registerBinding(createBindingsPairSelection(castEObject(getModel()), YECviewPackage.Literals.YPAIR_COMBO_BOX__SELECTION, field));

		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 createBindingsPairSelection(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 PairToTextConverter());
			UpdateValueStrategy modelToTarget = new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE);
			modelToTarget.setConverter(new TextToPairConverter());

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

	private static class TextToPairConverter extends Converter {

		public TextToPairConverter() {
			super(String.class, Pair.class);
		}

		@Override
		public Object convert(Object fromObject) {
			if (fromObject == null) {
				return null;
			}
			return Tuples.create(extractSimpleName((String) fromObject), (String) fromObject);
			// return fromObject;
		}

		private String extractSimpleName(String fqn) {
			String[] splittedFqn = fqn.split("\\.");
			String name = "";
			int length = splittedFqn.length;
			if (length > 0) {
				name = splittedFqn[length - 1];
			}
			return name;
		}
	}

	private static class PairToTextConverter extends Converter {

		public PairToTextConverter() {
			super(Pair.class, String.class);
		}

		@SuppressWarnings("unchecked")
		@Override
		public Object convert(Object fromObject) {
			if (fromObject == null) {
				return "";
			}
			return ((Pair<String, String>) fromObject).getSecond();
		}
	}

}
