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

import org.eclipse.core.databinding.Binding;
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.EMFProperties;
import org.eclipse.osbp.ecview.core.common.binding.observables.ContextObservables;
import org.eclipse.osbp.ecview.core.common.editpart.IElementEditpart;
import org.eclipse.osbp.ecview.core.common.model.core.YCollectionBindable;
import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddable;
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.common.presentation.IWidgetPresentation;
import org.eclipse.osbp.ecview.core.common.uri.URIHelper;
import org.eclipse.osbp.ecview.core.databinding.emf.model.ECViewModelBindable;
import org.eclipse.osbp.ecview.core.extension.model.extension.ExtensionModelPackage;
import org.eclipse.osbp.ecview.core.extension.model.extension.YMasterDetail;
import org.eclipse.osbp.ecview.core.ui.core.editparts.extension.IMasterDetailEditpart;
import org.eclipse.osbp.ecview.core.ui.core.editparts.extension.presentation.IMasterDetailPresentation;
import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.IConstants;
import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.AbstractVaadinWidgetPresenter;
import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.internal.util.Util;

import com.vaadin.ui.Component;
import com.vaadin.ui.ComponentContainer;
import com.vaadin.ui.CssLayout;
import com.vaadin.ui.VerticalLayout;

// TODO: Auto-generated Javadoc
/**
 * This presenter is responsible to render a text field on the given layout.
 */
@SuppressWarnings("restriction")
public class MasterDetailPresentation extends
		AbstractVaadinWidgetPresenter<ComponentContainer> implements
		IMasterDetailPresentation<ComponentContainer> {

	/** The model access. */
	private final ModelAccess modelAccess;
	
	/** The component base. */
	private VerticalLayout componentBase;

	/** The master base. */
	private CssLayout masterBase;
	
	/** The detail base. */
	private CssLayout detailBase;
	
	/** The master presentation. */
	private IWidgetPresentation<?> masterPresentation;
	
	/** The detail presentation. */
	private IWidgetPresentation<?> detailPresentation;
	
	/** The master collection binding. */
	private Binding masterCollectionBinding;

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

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ComponentContainer doCreateWidget(Object parent) {
		if (componentBase == null) {
			componentBase = new VerticalLayout();
			componentBase.addStyleName(CSS_CLASS_CONTROL_BASE);
			if (modelAccess.isCssIdValid()) {
				componentBase.setId(modelAccess.getCssID());
			} else {
				componentBase.setId(getEditpart().getId());
			}

			associateWidget(componentBase, modelAccess.yField);

			// create the container for master an detail
			masterBase = new CssLayout();
			masterBase.setStyleName(IConstants.CSS_CLASS_MASTER_BASE);
			masterBase.setSizeFull();
			componentBase.addComponent(masterBase);

			associateWidget(masterBase, modelAccess.yField);

			detailBase = new CssLayout();
			masterBase.setStyleName(IConstants.CSS_CLASS_DETAIL_BASE);
			detailBase.setSizeFull();
			componentBase.addComponent(detailBase);

			associateWidget(detailBase, modelAccess.yField);

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

			// render master an detail
			if (masterPresentation != null) {
				createMasterWidget();
			}

			if (detailPresentation != null) {
				Component detailWidget = (Component) detailPresentation
						.createWidget(detailBase);
				if (detailWidget != null) {
					detailBase.removeAllComponents();
					detailBase.addComponent(detailWidget);
				}
			}

		}
		return componentBase;
	}

	/**
	 * Creates the bindings for the given values.
	 *
	 * @param yField
	 *            the y field
	 */
	protected void createBindings(YMasterDetail yField) {

		// create the model binding from ECView-Model to the collection bean
		// slot
		URI uri = URIHelper.view().bean(getCollectionBeanSlot())
				.fragment("value").toURI();
		IObservableList targetObservableList = ContextObservables.observeList(
				getViewContext(), uri, modelAccess.yField.getType());
		IObservableList modelObservable = EMFProperties.list(
				ExtensionModelPackage.Literals.YMASTER_DETAIL__COLLECTION)
				.observe(getModel());
		registerBinding(createBindings(targetObservableList, modelObservable));

	}

	/**
	 * Creates a bean slot that is the input for the detail fields. It is used
	 * by the presentation to bind the detail fields to that slot.
	 *
	 * @return the selection bean slot
	 */
	protected String getSelectionBeanSlot() {
		return "selection_" + getEditpart().getId();
	}

	/**
	 * Create a bean slot which is the input for the master detail. It is used
	 * by the presentation to bind the table, list,... to that slot.
	 *
	 * @return the collection bean slot
	 */
	protected String getCollectionBeanSlot() {
		return "input_" + getEditpart().getId();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.AbstractVaadinWidgetPresenter#doUpdateLocale(java.util.Locale)
	 */
	@Override
	protected void doUpdateLocale(Locale locale) {

		// update the captions
		applyCaptions();
	}

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

	/* (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 NullPointerException("BindableValue must not be null!");
		}

		if (bindableValue instanceof YEmbeddableSelectionEndpoint) {
			return internalGetSelectionEndpoint((YEmbeddableSelectionEndpoint) bindableValue);
		} else if (bindableValue instanceof YEmbeddableCollectionEndpoint) {
			return internalGetCollectionEndpoint();
		}
		throw new IllegalArgumentException("Not a valid input: "
				+ bindableValue);
	}

	/**
	 * Returns the observable to observe value.
	 *
	 * @return the i observable list
	 */
	protected IObservableList internalGetCollectionEndpoint() {
		// delegate the binding to the proper bean slot
		URI uri = URIHelper.view().bean(getCollectionBeanSlot()).toURI();
		IObservableList modelObservableList = ContextObservables.observeList(
				getViewContext(), uri, modelAccess.yField.getType());
		return modelObservableList;
	}

	/**
	 * 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(
				ExtensionModelPackage.Literals.YMASTER_DETAIL__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 ComponentContainer getWidget() {
		return componentBase;
	}

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

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

			// unbind all active bindings
			unbind();

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

			// remove assocations
			unassociateWidget(componentBase);

			componentBase = null;

			if (masterPresentation != null) {
				disposeMasterWidget();
			}

			if (detailPresentation != null) {
				detailPresentation.unrender();
				detailBase.removeAllComponents();
			}
		}
	}

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

			// do NOT dispose. Will be handled by editpart.
			masterPresentation = null;
			detailPresentation = null;

		} finally {
			super.internalDispose();
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ecview.core.ui.core.editparts.extension.presentation.IMasterDetailPresentation#getMaster()
	 */
	@Override
	public IWidgetPresentation<?> getMaster() {
		return masterPresentation;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ecview.core.ui.core.editparts.extension.presentation.IMasterDetailPresentation#getDetail()
	 */
	@Override
	public IWidgetPresentation<?> getDetail() {
		return detailPresentation;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ecview.core.ui.core.editparts.extension.presentation.IMasterDetailPresentation#setMaster(org.eclipse.osbp.ecview.core.common.presentation.IWidgetPresentation)
	 */
	@Override
	public void setMaster(IWidgetPresentation<?> master) {
		if (this.masterPresentation == master) {
			return;
		}

		if (this.masterPresentation != null) {
			disposeMasterWidget();
		}

		this.masterPresentation = master;

		if (isRendered()) {
			if (this.masterPresentation != null) {
				createMasterWidget();
			}
		}
	}

	/**
	 * Creates the master widget and does the databinding.
	 */
	public void createMasterWidget() {

		Component masterWidget = (Component) masterPresentation
				.createWidget(masterBase);
		if (masterWidget != null) {
			masterBase.removeAllComponents();
			masterBase.addComponent(masterWidget);
		}

		YEmbeddable yMaster = (YEmbeddable) masterPresentation.getModel();
		if (yMaster instanceof YCollectionBindable) {
			createMasterCollectionBinding((YCollectionBindable) yMaster);
		}
	}

	/**
	 * Disposes the master widget and removes active bindings.
	 */
	protected void disposeMasterWidget() {
		masterPresentation.dispose();
		masterBase.removeAllComponents();

		if (masterCollectionBinding != null) {
			masterCollectionBinding.dispose();
			masterCollectionBinding = null;
		}
	}

	/**
	 * Creates a binding from the master element to the proper bean slot.
	 *
	 * @param yMasterCollectionBindable
	 *            the y master collection bindable
	 */
	protected void createMasterCollectionBinding(
			YCollectionBindable yMasterCollectionBindable) {

		YEmbeddableCollectionEndpoint yMasterEndpoint = yMasterCollectionBindable
				.createCollectionEndpoint();
		IObservableList targetObservableList = (IObservableList) this.masterPresentation
				.getObservableValue(yMasterEndpoint);
		URI uri = URIHelper.view().bean(getCollectionBeanSlot())
				.fragment("value").toURI();
		IObservableList modelObservableList = ContextObservables.observeList(
				getViewContext(), uri, modelAccess.yField.getType());

		masterCollectionBinding = createBindings(targetObservableList,
				modelObservableList);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ecview.core.ui.core.editparts.extension.presentation.IMasterDetailPresentation#setDetail(org.eclipse.osbp.ecview.core.common.presentation.IWidgetPresentation)
	 */
	@Override
	public void setDetail(IWidgetPresentation<?> detail) {
		if (this.detailPresentation == detail) {
			return;
		}

		if (this.detailPresentation != null) {
			this.detailPresentation.dispose();
			detailBase.removeAllComponents();
		}

		this.detailPresentation = detail;

		if (isRendered()) {
			if (this.detailPresentation != null) {
				this.detailPresentation.createWidget(detailBase);
			}
		}
	}

	/**
	 * A helper class.
	 */
	private static class ModelAccess {
		
		/** The y field. */
		private final YMasterDetail yField;

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