/**
 * 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.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map.Entry;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import java.util.stream.Collectors;
import java.util.stream.Stream;

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.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.databinding.EMFProperties;
import org.eclipse.osbp.blob.component.BlobComponent;
import org.eclipse.osbp.dsl.semantic.dto.util.NamingConventionsUtil;
import org.eclipse.osbp.ecview.core.common.editpart.IConverterEditpart;
import org.eclipse.osbp.ecview.core.common.editpart.IElementEditpart;
import org.eclipse.osbp.ecview.core.common.editpart.emf.ElementEditpart;
import org.eclipse.osbp.ecview.core.common.filter.IFilterablePresentation;
import org.eclipse.osbp.ecview.core.common.filter.IRefreshRowsPresentation;
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.YEmbeddableMultiSelectionEndpoint;
import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddableSelectionEndpoint;
import org.eclipse.osbp.ecview.core.common.model.core.YFlatAlignment;
import org.eclipse.osbp.ecview.core.common.model.datatypes.YDatadescription;
import org.eclipse.osbp.ecview.core.common.notification.ILifecycleEvent;
import org.eclipse.osbp.ecview.core.common.notification.ILifecycleService;
import org.eclipse.osbp.ecview.core.common.presentation.DelegatingConverterFactory;
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.YColumn;
import org.eclipse.osbp.ecview.core.extension.model.extension.YSelectionType;
import org.eclipse.osbp.ecview.core.extension.model.extension.YSortColumn;
import org.eclipse.osbp.ecview.core.extension.model.extension.YTable;
import org.eclipse.osbp.ecview.core.ui.core.editparts.extension.ITableEditpart;
import org.eclipse.osbp.ecview.extension.api.ILayoutingStrategy;
import org.eclipse.osbp.runtime.common.annotations.DtoUtils;
import org.eclipse.osbp.runtime.common.annotations.PropertiesUtil;
import org.eclipse.osbp.runtime.common.event.EventDispatcherEvent;
import org.eclipse.osbp.runtime.common.event.EventDispatcherEvent.EventDispatcherCommand;
import org.eclipse.osbp.runtime.common.event.EventDispatcherEvent.EventDispatcherDataTag;
import org.eclipse.osbp.runtime.common.event.IEventDispatcher;
import org.eclipse.osbp.runtime.common.i18n.I18nUtil;
import org.eclipse.osbp.runtime.common.i18n.II18nService;
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.converter.StringToFormattedNumberConverter;
import org.eclipse.osbp.runtime.web.vaadin.common.data.BeanServiceLazyLoadingContainer;
import org.eclipse.osbp.runtime.web.vaadin.common.data.DeepResolvingBeanItem;
import org.eclipse.osbp.runtime.web.vaadin.common.data.DeepResolvingBeanItemContainer;
import org.eclipse.osbp.runtime.web.vaadin.common.data.IBeanSearchService;
import org.eclipse.osbp.runtime.web.vaadin.common.data.IBeanSearchServiceFactory;
import org.eclipse.osbp.runtime.web.vaadin.common.data.IBeanToUniqueHashIdProvider;
import org.eclipse.osbp.runtime.web.vaadin.common.data.ILazyRefreshFilterable;
import org.eclipse.osbp.runtime.web.vaadin.common.data.INestedPropertyAble;
import org.eclipse.osbp.runtime.web.vaadin.common.resource.IResourceProvider;
import org.eclipse.osbp.ui.api.customfields.IBlobService;

import com.vaadin.data.Container;
import com.vaadin.data.Container.Filter;
import com.vaadin.data.Container.Filterable;
import com.vaadin.data.Item;
import com.vaadin.data.Property;
import com.vaadin.data.Property.ValueChangeListener;
import com.vaadin.data.util.IndexedContainer;
import com.vaadin.data.util.ObjectProperty;
import com.vaadin.data.util.converter.Converter;
import com.vaadin.data.util.converter.ConverterUtil;
import com.vaadin.server.ClientConnector;
import com.vaadin.server.ClientConnector.AttachEvent;
import com.vaadin.server.ClientConnector.DetachEvent;
import com.vaadin.server.ErrorMessage;
import com.vaadin.server.Resource;
import com.vaadin.server.ThemeResource;
import com.vaadin.ui.AbstractSelect.ItemCaptionMode;
import com.vaadin.ui.CheckBox;
import com.vaadin.ui.Component;
import com.vaadin.ui.ComponentContainer;
import com.vaadin.ui.Field;
import com.vaadin.ui.Table;
import com.vaadin.ui.Table.Align;
import com.vaadin.ui.Table.RowHeaderMode;
import com.vaadin.ui.UI;

/**
 * This presenter is responsible to render a table on the given layout.
 */
@SuppressWarnings({ "restriction", "serial" })
public class TablePresentation extends AbstractFieldWidgetPresenter<Component>
		implements IFilterablePresentation, IRefreshRowsPresentation, ClientConnector.DetachListener,
		ClientConnector.AttachListener, IEventDispatcher.Receiver {

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

	/** The table. */
	private Table table;

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

	/** The apply columns. */
	private boolean applyColumns;

	private boolean containerReadonly;

	private AdapterCustom adapter;

	private IEventDispatcher eventDispatcher;

	private IBlobService blobService;

	/**
	 * Constructor.
	 * 
	 * @param editpart
	 *            The editpart of that presenter
	 */
	public TablePresentation(IElementEditpart editpart) {
		super((ITableEditpart) editpart);
		this.modelAccess = new ModelAccess((YTable) editpart.getModel());
		adapter = new AdapterCustom();
		this.modelAccess.yField.eAdapters().add(adapter);
	}

	/**
	 * {@inheritDoc}
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	public Component doCreateWidget(Object parent) {
		if (table == null) {
			table = new CustomTable();
			table.addStyleName(CSS_CLASS_CONTROL);
			table.setMultiSelect(modelAccess.yField.getSelectionType() == YSelectionType.MULTI);
			table.setSelectable(true);
			table.setImmediate(true);
			setupComponent(table, getCastedModel());

			table.addValueChangeListener(new ValueChangeListener() {
				@Override
				public void valueChange(com.vaadin.data.Property.ValueChangeEvent event) {
					Class<?> bean = modelAccess.yField.getType();
					if (bean != null) {
						eventDispatcher = getViewContext().getService(IEventDispatcher.class.getName());
						blobService = getViewContext().getService(IBlobService.class.getName());
						String topic = NamingConventionsUtil.toFqnEntityName(bean.getName()) + "."
								+ DtoUtils.getIdField(bean).getName();
						EventDispatcherEvent evnt = new EventDispatcherEvent(EventDispatcherCommand.SELECT, topic,
								toString());
						Object value = table.getValue();
						if (value != null) {
							if (table.getContainerDataSource() instanceof DeepResolvingBeanItemContainer) {
								DeepResolvingBeanItemContainer container = (DeepResolvingBeanItemContainer) table
										.getContainerDataSource();
								DeepResolvingBeanItem<?> item = container.getItem(value);
								if (item != null) {
									evnt.addItem(EventDispatcherDataTag.ID, DtoUtils.getIdValue(item.getBean()));
									eventDispatcher.sendEvent(evnt);
								}
							}
						} else {
							evnt.addItem(EventDispatcherDataTag.ID, null);
							eventDispatcher.sendEvent(evnt);
						}
					}
				}
			});

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

			if (table.isMultiSelect()) {
				property = new ObjectProperty(new HashSet(), Set.class);
			} else {
				if (modelAccess.yField.getType() != null) {
					property = new ObjectProperty(null, modelAccess.yField.getType());
				} else {
					property = new ObjectProperty(null, Object.class);
				}
			}
			table.setPropertyDataSource(property);

			applyColumns = false;
			if (modelAccess.yField.getType() == String.class) {
				IndexedContainer datasource = new IndexedContainer();
				table.setContainerDataSource(datasource);
				table.setItemCaptionMode(ItemCaptionMode.ID);
			} else {
				if (modelAccess.yField.getType() != null) {
					IBeanSearchService<?> service = null;
					IBeanSearchServiceFactory factory = getViewContext()
							.getService(IBeanSearchServiceFactory.class.getName());
					if (factory != null) {
						service = factory.createService(modelAccess.yField.getType());
					}
					if (modelAccess.yField.isUseBeanService() && service != null) {
						ISharedStateContext sharedState = getViewContext()
								.getService(ISharedStateContext.class.getName());
						BeanServiceLazyLoadingContainer<?> datasource = new BeanServiceLazyLoadingContainer(service,
								modelAccess.yField.getType(), sharedState);
						table.setContainerDataSource(datasource);
						containerReadonly = true;
					} else {
						DeepResolvingBeanItemContainer datasource = new DeepResolvingBeanItemContainer(
								modelAccess.yField.getType());
						table.setContainerDataSource(datasource);
					}
					applyColumns = true;
				} else {
					IndexedContainer container = new IndexedContainer();
					container.addContainerProperty("for", String.class, null);
					container.addContainerProperty("preview", String.class, null);
					container.addItem(new String[] { "Some value", "other" });
					table.setContainerDataSource(container);
				}
			}

			String itemImageProperty = modelAccess.yField.getItemImageProperty();
			if (itemImageProperty != null && !itemImageProperty.equals("")) {
				table.setItemIconPropertyId(itemImageProperty);
				table.setRowHeaderMode(RowHeaderMode.EXPLICIT);
			}

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

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

			applyCaptions();

			initializeField(table);
		}
		return table;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.osbp.ecview.core.common.filter.IRefreshRowsPresentation#
	 * refreshRows()
	 */
	@Override
	public void refreshRows() {
		if (isRendered()) {
			table.refreshRowCache();
		}
	}

	/**
	 * Applies the column setting to the table.
	 */
	@SuppressWarnings({ "serial", "unchecked" })
	protected void applyColumns() {
		Class<?> type = modelAccess.yField.getType();

		// set the visible columns and icons
		List<String> columns = new ArrayList<>();
		Collection<?> propertyIds = table.getContainerDataSource().getContainerPropertyIds();

		if (!modelAccess.yField.getColumns().isEmpty()) {
			for (YColumn yColumn : modelAccess.yField.getColumns()) {
				if (yColumn.isVisible() && propertyIds.contains(yColumn.getPropertyPath()) || isNestedColumn(yColumn)) {
					columns.add(yColumn.getPropertyPath());
				}
			}

			// add nested properties
			if (table.getContainerDataSource() instanceof INestedPropertyAble) {
				INestedPropertyAble<?> container = (INestedPropertyAble<?>) table.getContainerDataSource();
				for (String property : columns) {
					if (property.contains(".")) {
						container.addNestedContainerProperty(property);
					}
				}
			}

			table.setVisibleColumns(columns.toArray(new Object[columns.size()]));
			table.setColumnCollapsingAllowed(true);

			II18nService i18nService = getViewContext().getService(II18nService.class.getName());
			IResourceProvider resourceProvider = (IResourceProvider) getViewContext()
					.getService(IResourceProvider.class.getName());
			// traverse the columns again and set other properties
			for (YColumn yColumn : modelAccess.yField.getColumns()) {
				if (yColumn.isVisible()
						&& (propertyIds.contains(yColumn.getPropertyPath()) || isNestedColumn(yColumn))) {
					String columnId = yColumn.getPropertyPath();

					table.setColumnHeader(columnId, getColumnHeader(yColumn));
					table.setColumnAlignment(columnId, toAlign(yColumn.getAlignment()));
					table.setColumnCollapsed(columnId, yColumn.isCollapsed());
					table.setColumnCollapsible(columnId, yColumn.isCollapsible());
					if (yColumn.getExpandRatio() >= 0) {
						table.setColumnExpandRatio(columnId, yColumn.getExpandRatio());
					}
					// Boolean check to display a checkbox instead of the
					// boolean value as String.
					if (yColumn.getType() == Boolean.class) {
						// check to avoid an IllegalArgumentException adding an
						// already existing ColumnGenerator.
						if (table.getColumnGenerator(columnId) == null) {
							table.addGeneratedColumn(columnId, new Table.ColumnGenerator() {
								@Override
								public Component generateCell(Table source, Object itemId, Object columnId) {
									Item item = table.getItem(itemId);
									CheckBox box = new CheckBox();
									box.setEnabled(false);
									Boolean value = (Boolean) item.getItemProperty(columnId).getValue();
									box.setValue(value);
									return box;
								}
							});
						}
					}
					// --------------
					if (yColumn.getIcon() != null && !yColumn.getIcon().equals("")) {
						if (i18nService != null) {
							String translation = i18nService.getValue(yColumn.getIcon(), UI.getCurrent().getLocale());
							if (translation != null && !translation.equals("")) {
								Resource icon = resourceProvider.getResource(translation);
								if (icon != null) {
									table.setColumnIcon(columnId, icon);
								}
							}
						} else {
							table.setColumnIcon(columnId, resourceProvider.getResource(yColumn.getIcon()));
						}
					}
					// Blob check to display a blob image
					if ((yColumn.getType() == String.class)
							&& ((yColumn.getProperties() != null) && (!yColumn.getProperties().isEmpty()))) {
						Stream<Entry<String, String>> propertyStream = yColumn.getProperties().stream()
								.filter(prop -> prop.getKey().equalsIgnoreCase(ILayoutingStrategy.PROPERTY_BLOB));
						// Only if one 'Blob' or 'blob' property entry exists
						if (propertyStream.count() == 1) {
							String displayResolution = yColumn.getProperties().stream()
									.filter(prop -> prop.getKey().equalsIgnoreCase(ILayoutingStrategy.PROPERTY_BLOB))
									.map(p -> p.getValue()).collect(Collectors.joining());
							// check to avoid an IllegalArgumentException adding
							// an
							// already existing ColumnGenerator.
							if (table.getColumnGenerator(columnId) == null) {
								table.addGeneratedColumn(columnId, new Table.ColumnGenerator() {

									@Override
									public Component generateCell(Table source, Object itemId, Object columnId) {
										Item item = table.getItem(itemId);
										BlobComponent blob = new BlobComponent(blobService, (String) item.getItemProperty(columnId).getValue(), Integer.parseInt(displayResolution));
										return blob;
									}
								});
							}
						}
					}

				}
			}

			// apply the converters
			//
			for (

			YColumn yColumn : modelAccess.yField.getColumns()) {
				if (yColumn.getConverter() == null) {
					// try to derive the converter from the datatype property at
					// field level
					String columnId = yColumn.getPropertyPath();
					Class<?> resultClass = table.getContainerDataSource().getType(columnId);
					if (Number.class.isAssignableFrom(resultClass)
							&& PropertiesUtil.hasKey(type, columnId, "decimalformat")) {
						String format = PropertiesUtil.getValue(type, columnId, "decimalformat");
						if (format != null && !format.isEmpty()) {
							table.setConverter(columnId, new StringToFormattedNumberConverter(format,
									(Class<? extends Number>) resultClass));
						}
					}
				} else {
					@SuppressWarnings("rawtypes")
					Converter converter = (Converter) DelegatingConverterFactory.getInstance().createConverter(
							getViewContext(),
							(IConverterEditpart) ElementEditpart.getEditpart(getViewContext(), yColumn.getConverter()));
					if (converter != null) {
						String columnId = yColumn.getPropertyPath();
						table.setConverter(columnId, converter);
					}
				}
			}
		}

		// apply the sort order
		applySortOrder();

		applyCellStyles();

		// apply the dirty flag
		// applyDirtyFlag(type);
	}

	@SuppressWarnings("serial")
	protected void applyCellStyles() {
		table.setCellStyleGenerator(new Table.CellStyleGenerator() {

			@Override
			public String getStyle(Table source, Object itemId, Object propertyId) {
				if (itemId == null || propertyId == null) {
					return "";
				}
				if (Number.class.isAssignableFrom(source.getContainerDataSource().getType(propertyId))) {
					return " v-align-right";
				}
				return "";
			}
		});
	}

	// protected void applyDirtyFlag(Class<?> type) {
	// final String dirtyProperty = getDirtyProperty(type);
	// // if a dirty property is available, we use it
	// if (dirtyProperty != null) {
	// table.setCellStyleGenerator(new Table.CellStyleGenerator() {
	// private static final long serialVersionUID = -2462674164411654020L;
	// @Override
	// public String getStyle(Table source, Object itemId,
	// Object propertyId) {
	// if (propertyId == null) {
	// return null;
	// }
	// if (propertyId.equals(dirtyProperty)) {
	// try {
	// boolean dirty = DtoUtils.invokeDirtyGetter(itemId);
	// return dirty ? "dirty" : null;
	// } catch (IllegalAccessException e) {
	// }
	// } else {
	// Class<?> propertyType = source.getContainerDataSource()
	// .getType(propertyId);
	// if (Number.class.isAssignableFrom(propertyType)) {
	// return "v-align-right";
	// }
	// }
	// }
	// table.setCellStyleGenerator(new Table.CellStyleGenerator() {
	// @Override
	// public String getStyle(Table source, Object itemId,
	// Object propertyId) {
	// if (propertyId == null) {
	// return null;
	// }
	// });
	// }

	protected void applySortOrder() {
		if (!modelAccess.yField.getSortOrder().isEmpty()
				&& table.getContainerDataSource() instanceof Container.Sortable) {
			List<String> sortCol = new ArrayList<>();
			List<Boolean> sortDirection = new ArrayList<>();
			for (YSortColumn yColumn : modelAccess.yField.getSortOrder()) {
				// add the nested sort columns to the container
				if (isNestedColumn(yColumn)) {
					if (table.getContainerDataSource() instanceof INestedPropertyAble) {
						INestedPropertyAble<?> container = (INestedPropertyAble<?>) table.getContainerDataSource();
						container.addNestedContainerProperty(yColumn.getPropertyPath());
					}
				}

				sortCol.add(yColumn.getPropertyPath());
				sortDirection.add(yColumn.isAsc());
			}
			Container.Sortable sortable = (Container.Sortable) table.getContainerDataSource();

			boolean[] asc = new boolean[sortDirection.size()];
			for (int i = 0; i < sortDirection.size(); i++) {
				asc[i] = sortDirection.get(i);
			}

			ILifecycleService lfService = getViewContext().getService(ILifecycleService.class.getName());
			if(!lfService.getState().equals(ILifecycleEvent.TYPE_RENDERING)) {
				sortable.sort(sortCol.toArray(new String[sortCol.size()]), asc);
				if (!sortCol.isEmpty()) {
					table.setSortContainerPropertyId(sortCol.get(0));
					table.setSortAscending(asc[0]);
				}
			}
	
		}
	}

	public void doSort() {
		if (table != null) {
			table.sort();
		}
	}

	/**
	 * Gets the dirty property.
	 *
	 * @param type
	 *            the type
	 * @return the dirty property
	 */
	protected String getDirtyProperty(Class<?> type) {
		String temp = null;
		java.lang.reflect.Field dirtyField = DtoUtils.getDirtyField(type);
		if (dirtyField != null) {
			temp = dirtyField.getName();
		}
		return temp;
	}

	/**
	 * Checks if is nested column.
	 *
	 * @param yColumn
	 *            the y column
	 * @return true, if is nested column
	 */
	protected boolean isNestedColumn(YColumn yColumn) {
		return yColumn.getPropertyPath() != null && yColumn.getPropertyPath().contains(".");
	}

	/**
	 * Checks if is nested column.
	 *
	 * @param yColumn
	 *            the y column
	 * @return true, if is nested column
	 */
	protected boolean isNestedColumn(YSortColumn yColumn) {
		return yColumn.getPropertyPath() != null && yColumn.getPropertyPath().contains(".");
	}

	/**
	 * Returns the column header.
	 *
	 * @param yColumn
	 *            the y column
	 * @return the column header
	 */
	private String getColumnHeader(YColumn yColumn) {
		YDatadescription yDt = yColumn.getDatadescription();
		if (yDt == null) {
			return yColumn.getPropertyPath();
		}

		String result = null;
		II18nService service = getI18nService();
		if (service != null && yDt.getLabelI18nKey() != null) {
			result = service.getValue(yDt.getLabelI18nKey(), getLocale());
		}

		if (result == null || result.equals("")) {
			result = yDt.getLabel();
		}

		if (result == null || result.equals("")) {
			result = yColumn.getPropertyPath();
		}

		return result;
	}

	/**
	 * To align.
	 *
	 * @param alignment
	 *            the alignment
	 * @return the align
	 */
	private Align toAlign(YFlatAlignment alignment) {
		switch (alignment) {
		case LEFT:
			return Align.LEFT;
		case CENTER:
			return Align.CENTER;
		case RIGHT:
			return Align.RIGHT;
		}
		return Align.LEFT;
	}

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

		// applies the column properties
		if (applyColumns) {
			applyColumns();
		}

		Util.applyCaptions(getI18nService(), modelAccess.getLabel(), modelAccess.getLabelI18nKey(), getLocale(), table);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.osbp.ecview.core.common.filter.IFilterablePresentation#
	 * applyFilter(java.lang.Object)
	 */
	@Override
	public void applyFilter(Object filter) {
		Container container = table.getContainerDataSource();
		if (container instanceof Container.Filterable) {
			Container.Filterable filterable = (Filterable) container;
			filterable.removeAllContainerFilters();
			if (filter != null) {
				filterable.addContainerFilter((Filter) filter);
			} else if (container instanceof ILazyRefreshFilterable) {
				ILazyRefreshFilterable lazyFilterable = (ILazyRefreshFilterable) container;
				lazyFilterable.removeAllContainerFilters();
			}
		}
	}

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

	/*
	 * (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);
		} else if (bindableValue instanceof YEmbeddableMultiSelectionEndpoint) {
			return internalGetMultiSelectionEndpoint();
		}
		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(ExtensionModelPackage.Literals.YTABLE__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(ExtensionModelPackage.Literals.YTABLE__SELECTION,
				yEndpoint.getAttributePath());

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

	/**
	 * Returns the observable to observe the selection.
	 *
	 * @return the i observable list
	 */
	protected IObservableList internalGetMultiSelectionEndpoint() {
		// return the observable value for text
		return EMFProperties.list(ExtensionModelPackage.Literals.YTABLE__MULTI_SELECTION).observe(getModel());
	}

	/**
	 * Creates the bindings for the given values.
	 *
	 * @param yField
	 *            the y field
	 * @param field
	 *            the field
	 */
	protected void createBindings(YTable yField, Table field) {
		// create the model binding from ridget to ECView-model
		registerBinding(createBindingsContainerContents(castEObject(getModel()),
				ExtensionModelPackage.Literals.YTABLE__COLLECTION, field, yField.getType(), containerReadonly));

		// create the model binding from ridget to ECView-model
		if (modelAccess.yField.getSelectionType() == YSelectionType.MULTI) {
			// create the model binding from ridget to ECView-model
			registerBinding(createBindingsMultiSelection(castEObject(getModel()),
					ExtensionModelPackage.Literals.YTABLE__MULTI_SELECTION, field, yField.getType()));
		} else {
			// create the model binding from ridget to ECView-model
			registerBinding(createBindingsSelection(castEObject(getModel()),
					ExtensionModelPackage.Literals.YTABLE__SELECTION, field, yField.getType()));

		}

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

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

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

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

			// unbind all active bindings
			unbind();

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

			// remove assocations
			unassociateWidget(table);

			table = null;
		}
	}

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

			modelAccess.yField.eAdapters().remove(adapter);

		} finally {
			super.internalDispose();
		}
	}

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

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

		/**
		 * Instantiates a new model access.
		 *
		 * @param yField
		 *            the y field
		 */
		public ModelAccess(YTable 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 class CustomTable extends Table {

		/** The item icon property id. */
		private Object itemIconPropertyId;
		private String itemIdHash;
		private boolean updateMode;

		private Timer sortTimer;
		private boolean isSorting;

		@SuppressWarnings("unchecked")
		CustomTable() {
			addValueChangeListener(e -> {
				if (getContainerDataSource() instanceof IBeanToUniqueHashIdProvider) {
					IBeanToUniqueHashIdProvider<Object> hashIdProvider = (IBeanToUniqueHashIdProvider<Object>) getContainerDataSource();
					Object selection = e.getProperty().getValue();
					this.itemIdHash = hashIdProvider.getUniqueHashId(selection);
				}
			});
			addItemSetChangeListener(e -> {
				if (isSorting || getSortContainerPropertyId() == null || getUI() == null) {
					return;
				}
				if (sortTimer != null) {
					sortTimer.cancel();
				}
				sortTimer = new Timer();
				sortTimer.schedule(new TimerTask() {
					@Override
					public void run() {
						try {
							isSorting = true;
							getUI().accessSynchronously(() -> {
								sort();
								if (modelAccess.yField.isScrollToBottom()) {
									setCurrentPageFirstItemIndex(size() - 1);
								}
							});
						} finally {
							isSorting = false;
						}
					}
				}, 125);
			});
		}

		/*
		 * (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()
		 */
		@Override
		public Object getItemIconPropertyId() {
			return itemIconPropertyId != null ? itemIconPropertyId : super.getItemIconPropertyId();
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see com.vaadin.ui.AbstractSelect#getItemIcon(java.lang.Object)
		 */
		@Override
		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();
				if (icon instanceof String) {
					return new ThemeResource((String) icon);
				}
			}
			return null;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see com.vaadin.ui.Table#formatPropertyValue(java.lang.Object,
		 * java.lang.Object, com.vaadin.data.Property)
		 */
		@Override
		@SuppressWarnings({ "unchecked", "rawtypes" })
		protected String formatPropertyValue(Object rowId, Object colId, Property<?> property) {
			if (property == null) {
				return "";
			}
			Converter<String, Object> converter = null;

			if (hasConverter(colId)) {
				converter = getConverter(colId);
			} else {
				converter = (Converter) ConverterUtil.getConverter(String.class, property.getType(), getSession());
			}
			Object value = property.getValue();
			if (converter != null) {
				return converter.convertToPresentation(value, String.class, getLocale());
			} else {
				if (value instanceof Enum<?>) {
					return I18nUtil.translateEnum(getI18nService(), value, getLocale());
				} else if (value instanceof Boolean) {
					return I18nUtil.translateBoolean(getI18nService(), (Boolean) value, getLocale());
				} else if (value instanceof Number) {
					return I18nUtil.translateNumber(getI18nService(), (Number) value, getLocale());
				}
			}
			return (null != value) ? value.toString() : "";
		}

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

		/*
		 * (non-Javadoc)
		 * 
		 * @see com.vaadin.ui.AbstractField#focus()
		 */
		@Override
		public void focus() {
			super.focus();

			setValue(getCurrentPageFirstItemId());
		}

		@Override
		@SuppressWarnings("unchecked")
		public void setContainerDataSource(Container newDataSource) {
			super.setContainerDataSource(newDataSource);

			if (getContainerDataSource() instanceof DeepResolvingBeanItemContainer) {
				@SuppressWarnings("rawtypes")
				final DeepResolvingBeanItemContainer ds = (DeepResolvingBeanItemContainer) getContainerDataSource();
				ds.addItemSetChangeListener(e -> {

					// lazy update the table selection
					if (!updateMode && itemIdHash != null) {
						updateMode = true;
						final String targetItemIdHash = itemIdHash;
						getUI().accessSynchronously(() -> {
							for (Object itemId : e.getContainer().getItemIds()) {
								if (targetItemIdHash.equals(ds.getUniqueHashId(itemId))) {
									table.setValue(itemId);
									break;
								}
							}
							updateMode = false;
						});
					}
				});
			}
		}
	}

	private class AdapterCustom extends AdapterImpl {
		@Override
		public void notifyChanged(Notification notification) {
			int featureId = notification.getFeatureID(YTable.class);
			switch (notification.getEventType()) {
			case Notification.SET:
				if (featureId == ExtensionModelPackage.YTABLE__DO_SORT) {
					doSort();
				}
				break;
			default:

			}
		}
	}

	@Override
	public void receiveEvent(EventDispatcherEvent event) {
		switch (event.getCommand()) {
		case REFRESH:
			// if(!event.getSender().equals("net.osbee.sample.foodmart.tables.CashRegister"))
			// {
			// if(event.getTopic().equals("net.osbee.sample.foodmart.entities.CashRegister")){
			refreshRows();
			// }
			// }
			break;
		case SELECT:
			break;
		default:
			break;
		}
	}

	@Override
	public void attach(AttachEvent event) {
		eventDispatcher.addEventReceiver(this);
	}

	@Override
	public void detach(DetachEvent event) {
		eventDispatcher.removeEventReceiver(this);
	}
}