/**
 * 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 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.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.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
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.core.common.notification.IReloadRequestService;
import org.eclipse.osbp.ecview.core.extension.model.extension.ExtensionModelPackage;
import org.eclipse.osbp.ecview.core.extension.model.extension.YSuggestTextField;
import org.eclipse.osbp.ecview.core.extension.model.extension.YSuggestTextFieldEvents;
import org.eclipse.osbp.ecview.core.ui.core.editparts.extension.ISuggestTextFieldEditpart;
import org.eclipse.osbp.runtime.common.state.ISharedStateContext;
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.IBeanSearchServiceFactory;
import org.eclipse.osbp.vaadin.addons.suggesttext.SuggestTextField;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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;

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

	private static final Logger LOGGER = LoggerFactory
			.getLogger(SuggestTextFieldPresentation.class);

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

	/** The text. */
	private SuggestTextField text;

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

	/** The adapter. */
	private Adapter adapter;

	/** The value binding. */
	private Binding valueBinding;

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

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

			adapter = new Adapter();
			modelAccess.yField.eAdapters().add(adapter);

			text = new CustomTextField();
			text.addStyleName(CSS_CLASS_CONTROL);
			text.getTextField().setNullRepresentation("");
			text.setImmediate(true);
			text.setLimit(10);
			text.setAutoHide(modelAccess.yField.isAutoHidePopup());
			setupComponent(text, getCastedModel());

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

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

			text.addSelectionChangedListener(new SuggestTextField.SelectionChangedListener() {
				@Override
				public void selectionChanged(
						SuggestTextField.SelectionChangedEvent event) {
					Object itemId = event.getItemId();
					internalSetLastSuggestion(itemId);
				}
			});

			if (modelAccess.yField.getType() != null) {
				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);
					text.setContainerDataSource(datasource);

					text.setCaptionPropertyId(modelAccess.yField
							.getItemCaptionProperty());
					text.setFilterPropertyId(modelAccess.yField
							.getItemFilterProperty());

					String uuidProp = modelAccess.yField.getItemUUIDProperty();
					if (uuidProp != null && !uuidProp.equals("")) {
						text.setUniqueIdPropertyId(modelAccess.yField
								.getItemUUIDProperty());
					}
				}
			}

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

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

			applyCaptions();

			initializeField(text.getTextField());
		}
		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 != null ? text.getTextField() : null;
	}

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

	/**
	 * Creates the bindings for the given values.
	 *
	 * @param yField
	 *            the y field
	 * @param field
	 *            the field
	 */
	protected void createBindings(YSuggestTextField yField,
			SuggestTextField field) {
		updateValueBinding(field);

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

	/**
	 * The value binding takes respect to the
	 * modelAccess.yField.isUseSuggestions(). If suggestions are used, value
	 * changes in the UI MUST NOT be updated to the model.
	 *
	 * @param field
	 *            the field
	 */
	protected void updateValueBinding(SuggestTextField field) {
		if (valueBinding != null) {
			unregisterBinding(valueBinding);
		}

		if (field == null) {
			return;
		}

		field.setSuggestionEnabled(modelAccess.yField.isUseSuggestions());

		if (modelAccess.yField.isUseSuggestions()) {
			// in suggest mode do not update from UI to model
			valueBinding = createBindingsValue(castEObject(getModel()),
					ExtensionModelPackage.Literals.YSUGGEST_TEXT_FIELD__VALUE,
					field.getTextField(), new UpdateValueStrategy(
							UpdateValueStrategy.POLICY_NEVER),
					new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE));
		} else {
			valueBinding = createBindingsValue(castEObject(getModel()),
					ExtensionModelPackage.Literals.YSUGGEST_TEXT_FIELD__VALUE,
					field.getTextField(), new UpdateValueStrategy(
							UpdateValueStrategy.POLICY_UPDATE),
					new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE));
		}

		// create the model binding from ridget to ECView-model
		registerBinding(valueBinding);
	}

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

			modelAccess.yField.eAdapters().remove(adapter);
			adapter = 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);
			unassociateWidget(text.getTextField());

			text = null;
		}
	}

	/**
	 * Sets the use suggestions.
	 *
	 * @param newBooleanValue
	 *            the new use suggestions
	 */
	public void setUseSuggestions(boolean newBooleanValue) {
		updateValueBinding(text);
	}

	/**
	 * Executes the given event.
	 * 
	 * @param event
	 */
	protected void doExecuteEvent(YSuggestTextFieldEvents event) {
		if (!isRendered()) {
			return;
		}

		if (modelAccess.yField.isAutoHidePopup()) {
			LOGGER.warn("Using events with autoHidePopup==true, may cause side effects, "
					+ "since a click to the UI outside the popup will close the popup automatically");
		}

		switch (event) {
		case OPEN_POPUP:
			text.openPopup();
			break;
		case CLOSE_POPUP:
			text.closePopup();
			break;
		case NAVIGATE_NEXT:
			text.navigateToNext();
			break;
		case NAVIGATE_PREV:
			text.navigateToPrevious();
			break;
		case SELECT:
			text.selectCurrent();
			break;
		case CLEAR:
			text.setValue(null);
			text.closePopup();
			internalSetLastSuggestion(null);
			break;
		}
	}

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

	protected void internalSetLastSuggestion(Object itemId) {
		IReloadRequestService service = getViewContext()
				.getService(IReloadRequestService.class.getName());
		if (service != null && itemId != null) {
			service.requestReload(getCastedModel(),
					itemId);
		}
		modelAccess.yField.setLastSuggestion(itemId);
	}

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

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

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

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

	/**
	 * The Class CustomTextField.
	 */
	@SuppressWarnings("serial")
	private class CustomTextField extends SuggestTextField {

		/*
		 * (non-Javadoc)
		 * 
		 * @see com.vaadin.ui.AbstractComponent#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;
		}

	}

	/**
	 * The Class Adapter.
	 */
	private class Adapter extends AdapterImpl {

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * org.eclipse.emf.common.notify.impl.AdapterImpl#notifyChanged(org.
		 * eclipse.emf.common.notify.Notification)
		 */
		@Override
		public void notifyChanged(Notification msg) {
			if (msg.getFeature() == ExtensionModelPackage.Literals.YSUGGEST_TEXT_FIELD__USE_SUGGESTIONS) {
				setUseSuggestions(msg.getNewBooleanValue());
			} else if (msg.getFeature() == ExtensionModelPackage.Literals.YSUGGEST_TEXT_FIELD__AUTO_HIDE_POPUP) {
				text.setAutoHide(msg.getNewBooleanValue());
			} else if (msg.getFeature() == ExtensionModelPackage.Literals.YSUGGEST_TEXT_FIELD__EVENT) {
				YSuggestTextFieldEvents event = (YSuggestTextFieldEvents) msg
						.getNewValue();
				if (event != null) {
					doExecuteEvent(event);
				}
			}
		}
	}
}
