/**
 *                                                                            
 * Copyright (c) 2011, 2019 - 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:   
 * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation 
 */
package org.eclipse.osbp.vaaclipse.addons.softwarefactory.perspective;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;
import java.util.function.Consumer;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;
import javax.inject.Named;
import javax.swing.Timer;

import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.core.di.annotations.Optional;
import org.eclipse.e4.core.services.events.IEventBroker;
import org.eclipse.e4.ui.di.Focus;
import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.e4.ui.model.application.ui.advanced.MPerspective;
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
import org.eclipse.e4.ui.workbench.IPresentationEngine;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.osbp.blob.component.BlobConverter;
import org.eclipse.osbp.core.api.persistence.IPersistenceService;
import org.eclipse.osbp.dsl.common.datatypes.IDto;
import org.eclipse.osbp.dsl.dto.lib.impl.DtoServiceAccess;
import org.eclipse.osbp.dsl.semantic.entity.LEntity;
import org.eclipse.osbp.ecview.core.common.beans.ISlot;
import org.eclipse.osbp.ecview.core.common.context.IConfiguration;
import org.eclipse.osbp.ecview.core.common.context.IContext;
import org.eclipse.osbp.ecview.core.common.context.IViewContext;
import org.eclipse.osbp.ecview.core.common.editpart.IFieldEditpart;
import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddable;
import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddableEvent;
import org.eclipse.osbp.ecview.core.common.model.core.YField;
import org.eclipse.osbp.ecview.core.common.model.core.YView;
import org.eclipse.osbp.ecview.core.common.model.core.util.BindingIdUtil;
import org.eclipse.osbp.ecview.core.common.notification.AbstractReloadRequestService;
import org.eclipse.osbp.ecview.core.common.notification.IReloadRequestService;
import org.eclipse.osbp.ecview.core.common.services.IWidgetAssocationsService;
import org.eclipse.osbp.ecview.core.common.store.IViewStore;
import org.eclipse.osbp.ecview.core.common.validation.IFieldValidationManager;
import org.eclipse.osbp.ecview.core.extension.model.extension.ExtensionModelPackage;
import org.eclipse.osbp.ecview.core.extension.model.extension.YButton;
import org.eclipse.osbp.ecview.core.extension.model.extension.listener.YButtonClickListener;
import org.eclipse.osbp.ecview.core.util.emf.ModelUtil;
import org.eclipse.osbp.ecview.extension.api.IFocusingStrategy;
import org.eclipse.osbp.ecview.extension.api.ILayoutingStrategy;
import org.eclipse.osbp.ecview.extension.presentation.vaadin.components.common.ECViewComponent;
import org.eclipse.osbp.ecview.semantic.uimodel.UiBeanSlot;
import org.eclipse.osbp.osgi.hybrid.api.AbstractHybridVaaclipseView;
import org.eclipse.osbp.runtime.common.annotations.DirtyStateAdapter;
import org.eclipse.osbp.runtime.common.annotations.DtoUtils;
import org.eclipse.osbp.runtime.common.annotations.IsDirty;
import org.eclipse.osbp.runtime.common.annotations.IsNew;
import org.eclipse.osbp.runtime.common.annotations.IsPositioned;
import org.eclipse.osbp.runtime.common.annotations.IsValid;
import org.eclipse.osbp.runtime.common.event.EventDispatcherEvent;
import org.eclipse.osbp.runtime.common.event.EventDispatcherEvent.EventDispatcherDataTag;
import org.eclipse.osbp.runtime.common.event.IEventDispatcher;
import org.eclipse.osbp.runtime.common.event.SelectionStore;
import org.eclipse.osbp.runtime.common.filter.IDTOHistorizedService;
import org.eclipse.osbp.runtime.common.filter.IDTOService;
import org.eclipse.osbp.runtime.common.filter.IDTOService;
import org.eclipse.osbp.runtime.common.validation.IStatus;
import org.eclipse.osbp.runtime.common.validation.ValidationKind;
import org.eclipse.osbp.runtime.web.vaadin.components.dialogs.AcceptDeleteDialog;
import org.eclipse.osbp.runtime.web.vaadin.components.dialogs.AcceptLoosingDataDialog;
import org.eclipse.osbp.runtime.web.vaadin.components.dialogs.AcceptSaveDialog;
import org.eclipse.osbp.runtime.web.vaadin.components.dialogs.QueryDeleteDialog;
import org.eclipse.osbp.runtime.web.vaadin.databinding.VaadinObservables;
import org.eclipse.osbp.ui.api.contextfunction.IViewEmbeddedProvider;
import org.eclipse.osbp.ui.api.customfields.IBlobConverter;
import org.eclipse.osbp.ui.api.customfields.IBlobService;
import org.eclipse.osbp.ui.api.e4.IE4Dialog;
import org.eclipse.osbp.ui.api.functionlibrary.IFunctionLibraryService;
import org.eclipse.osbp.ui.api.metadata.IDSLMetadataService;
import org.eclipse.osbp.ui.api.perspective.IPerspectiveProvider;
import org.eclipse.osbp.ui.api.report.IReportProvider;
import org.eclipse.osbp.ui.api.statemachine.IDataProvider;
import org.eclipse.osbp.ui.api.statemachine.IPeripheral;
import org.eclipse.osbp.ui.api.statemachine.IStateMachine;
import org.eclipse.osbp.ui.api.statemachine.IStateMachineParticipant;
import org.eclipse.osbp.ui.api.themes.EnumCssClass;
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 org.eclipse.osbp.utils.common.EntityUtils;
import org.eclipse.osbp.utils.vaadin.DTOInfoDialog;
import org.eclipse.osbp.utils.vaadin.SelectDialog;
import org.eclipse.osbp.utils.vaadin.ViewLayoutManager;
import org.eclipse.osbp.vaaclipse.addons.common.api.IE4Topics;
import org.eclipse.osbp.vaaclipse.addons.common.api.status.IStatusManager;
import org.eclipse.osbp.vaaclipse.addons.common.api.status.IStatusScope;
import org.eclipse.osbp.vaaclipse.common.ecview.E4EventBrokerAdapter;
import org.eclipse.osbp.vaaclipse.common.ecview.ECViewToE4ServiceBridge;
import org.eclipse.osbp.vaaclipse.common.ecview.api.IECViewContainer;
import org.eclipse.osbp.xtext.action.ActionDSLPackage;
import org.eclipse.osbp.xtext.action.ActionToolbar;
import org.eclipse.osbp.xtext.action.DialogActionEnum;
import org.eclipse.osbp.xtext.action.UIActionEnum;
import org.eclipse.osbp.xtext.action.common.IToolbarAction;
import org.eclipse.osbp.xtext.dialogdsl.Dialog;
import org.eclipse.osbp.xtext.dialogdsl.DialogFieldHook;
import org.eclipse.xtext.xbase.lib.Pair;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.vaadin.event.LayoutEvents.LayoutClickEvent;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Component;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Notification;
import com.vaadin.ui.Notification.Type;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;

/**
 * The Class ECViewDialog.
 *
 * @param <DTO>
 *            the generic type
 */
@SuppressWarnings("all")
public class DialogProvider<DTO> extends AbstractHybridVaaclipseView implements 
	IUser.UserLocaleListener, IEventDispatcher.Receiver, IFieldValidationManager.Listener , IE4Dialog, 
	IViewEmbeddedProvider, YButtonClickListener{

	/** The Constant log. */
	protected final static Logger log = LoggerFactory.getLogger("vaaclipseDialog");

	/** The Constant BEAN_SLOT__VALIDATION_ERROR. */
	protected static final String BEAN_SLOT__VALIDATION_ERROR = "validationError";

	/** The dialog label. */
	protected String dialogLabel;

	/** The event broker. */
	@Inject
	protected IECViewContainer ecviewContainer;

	/** The event broker. */
	@Inject
	protected IEventBroker eventBroker;

	/** The theme resource service. */
	@Inject
	protected IThemeResourceService themeResourceService;

	/** The translator class service. */
	@Inject
	protected IDSLMetadataService dslMetadataService;

	/** The report provider. */
	@Inject IReportProvider reportProvider;

	/** The blob service. */
	@Inject IBlobService blobService;

	/** The view store. */
	@Inject
	protected IViewStore viewStore;

	/** The currently active part. */
	@Inject
	@Optional
	protected MPart mPart;

	/** The persistence service. */
	@Inject
	protected IPersistenceService persistenceService;

	/** The event dispatcher. */
	@Inject
	protected IEventDispatcher eventDispatcher;

	/** The status manager. */
	@Inject
	protected IStatusManager statusManager;

	/** The eclipse context. */
	@Inject
	protected IEclipseContext eclipseContext;

	/** The rendering engine. */
	@Inject
	protected IPresentationEngine renderingEngine;

	/** The function library service. */
	@Inject
	protected IFunctionLibraryService functionLibraryService;

	/** The user. */
	@Inject
	protected IUser user;

	/** The view context. */
	protected IViewContext viewContext;

	/** The ecview component. */
	protected ECViewComponent ecviewComponent;

	/** The rendering params. */
	protected Map<String, Object> renderingParams;

	/** The uuid. */
	protected String uuid = UUID.randomUUID().toString();

	/** The layout manager. */
	protected ViewLayoutManager layoutManager;

	/** The dto service. */
	private IDTOService<DTO> dtoService;

	/** The toolbar helper. */
	private IToolbarAction toolbar;

	/** Flag whether the dto is newly created */
	private boolean newCreatedDto = false;

	/** The select dialog to get the desired base- or sub-class. */
	private SelectDialog selectDialog;

	/** The select window for the dialog. */
	private Window selectWindow;

	/** The dirty state adapter. */
	private DirtyStateAdapter dirtyStateAdapter;

	/** The ecview field validation manager. */
	private IFieldValidationManager ecviewFieldValidationManager;

	/** The validation result. */
	private Set<IStatus> validationResult;

	/** The info window for last update etc. */
	private DTOInfoDialog infoWindow;
	
	/** The last used base dto. */
	private Class<?> lastBaseDto;
	
	/** The field that gets focus. */
	private EventHandler onFocusField;
	
	/** The underlying xtext dialog model. */
	private Dialog dialogModel = null; 
	
	@Inject
	@Named("Focusing")
	private IFocusingStrategy focusingStrategy;
	
	/** The reload request service for suggesttext fields. */
	private IReloadRequestService reloadRequestService = new AbstractReloadRequestService() {
		@Override
		public void requestReload(YEmbeddable component, Object newDto) {
			updateBindings(newDto);
			setNewCreatedDto(newDto == null);
		}
	};

	/** The widget association service. */
	private IWidgetAssocationsService<Component, EObject>  associationService;

	private ArrayList<Button> taskButtons;

	private List<Consumer<DTO>> saveListeners;

	private boolean manualInput = false;

	private Timer timer;

	private boolean oldDirty = false;

	private String dtoName;
	
	private Map<String, Object> subTypes;

	private String viewId;

	private String entityName;

	private String primaryKey;

	private Class<?> dto;

	private Object numColumns;

	private Class<?> dialogFunctionGroup;

	private Method initializationMethod;
	private Method preSaveMethod;
	private Method postSaveMethod;
	private Map<YField, Pair<Method, Method>> fieldHooks = new HashMap<>();

	private VerticalLayout parent;

	private YView yView;

	/**
	 * Instantiates a new abstract ec view dialog.
	 *
	 * @param parent
	 *            the parent
	 * @param context
	 *            the context
	 * @param app
	 *            the app
	 */
	@Inject
	public DialogProvider(final VerticalLayout parent, final IEclipseContext context, final MApplication app) {
		super(parent, context, app);
		uuid = UUID.randomUUID().toString();
	}

	public DialogProvider() {
		uuid = UUID.randomUUID().toString();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.osbp.osgi.hybrid.api.AbstractHybridVaaclipseView#createView
	 * (com.vaadin.ui.VerticalLayout)
	 */
	@Override
	public void createView(final VerticalLayout externalParent) {
		if(externalParent != null) {
			parent = externalParent;
		} else {
			parent = new VerticalLayout();
		}
		parent.addStyleName(EnumCssClass.DIALOG_VIEW.toString());
		layoutManager = new ViewLayoutManager();
		if(dialogModel.isHasBackgroundImage()) {
			layoutManager.init(parent, viewId.replaceAll("\\.","-") + "-"+dialogModel.getBackgroundImage(), themeResourceService.getThemeResourceRelativePath(dialogModel.getBackgroundImage(), ThemeResourceType.IMAGE));
		} else {
			layoutManager.init(parent);
		}
		
		ecviewComponent.setSizeFull();
		layoutManager.getDataArea().addComponent(ecviewComponent);
		layoutManager.setLabelValue(dslMetadataService.translate(user.getLocale().toLanguageTag(), dialogLabel));
		selectDialog = new SelectDialog();
		// create toolbar
		if(dialogModel.getToolbar() != null) {
			String toolBarId = dslMetadataService.getFullyQualifiedName(dialogModel.getToolbar());
			ActionToolbar toolBarModel = (ActionToolbar) dslMetadataService.getMetadata(toolBarId, ActionDSLPackage.Literals.ACTION_TOOLBAR);
			toolbar = (IToolbarAction) dslMetadataService.getClassInstance(toolBarModel, "action");
			toolbar.createToolbar(eclipseContext, renderingEngine, themeResourceService, uuid);
		} 
		if(dialogModel.isEmbedded()) {
			createEmbeddedToolbar();
		}
	}

	private void initDialog() {
		if(mPart != null) {
	    	dialogModel = (Dialog) mPart.getTransientData().get(IPerspectiveProvider.TRANSIENT_DIALOG_MODEL);
	    } else {
	    	dialogModel = (Dialog) eclipseContext.get(IPerspectiveProvider.TRANSIENT_EMBEDDED_DIALOG_MODEL);
	    }
		viewId = dslMetadataService.getECViewId(dialogModel);
		dtoName = dslMetadataService.getFullyQualifiedName(dialogModel.getDto());
		if(dtoName != null) {
			LEntity entity = EntityUtils.getEntityFromDto(dialogModel.getDto());
			entityName = entity!=null?EntityUtils.getFQNForLEntity(entity):"";
			primaryKey = entity!=null?dslMetadataService.getFullyQualifiedName(entity)+"."+entity.getIdAttributeName():"";
			dto = dslMetadataService.getClass(dialogModel.getDto(), "dto");
			dtoService = (IDTOService<DTO>) DtoServiceAccess.getService(dto);
			subTypes = dslMetadataService.getAllSubtypes(user.getLocale().toLanguageTag(), dto);
		}
		dialogLabel = dialogModel.getName();
		numColumns = dialogModel.getNumColumns();

		dirtyStateAdapter = new DirtyStateAdapter();
		eclipseContext.set(IE4Dialog.class, this);
		if (viewStore != null) {
			ecviewComponent = new ECViewComponent(new ECViewComponent.ViewProviderCallback() {
				@Override
				public YView getView(String viewId, Map<String, Object> properties) {
					// use the view store to find a user saved view
					return viewStore.getMostRecentView(user.getUserName(), viewId);
				}
			});
		} else {
			ecviewComponent = new ECViewComponent();
		}
		renderingParams = createRenderingParams();
		viewContext = ecviewComponent.setValue(viewId, null, renderingParams);
		if (viewContext == null) {
			String message = "ViewContext could not be set for '" + viewId + "'";
			log.error("{}", message);
			Notification.show(message, Type.ERROR_MESSAGE);
		} else {
			viewContext.setLocale(user.getLocale());
			viewContext.createBeanSlot(BEAN_SLOT__VALIDATION_ERROR, Boolean.class);
			viewContext.setBean(BEAN_SLOT__VALIDATION_ERROR, Boolean.FALSE);
			if(mPart != null) {
				mPart.getContext().set(IViewContext.class, viewContext);
			}
			associationService = viewContext.getService(IWidgetAssocationsService.ID);
			// bridges the validation from ECView core to Vaaclipse
			setupValidationBridge();
			yView = (YView) viewContext.getViewEditpart().getModel();
			if (yView == null) {
				Notification.show("Dialog could not be found!", Type.ERROR_MESSAGE);
				return;
			}
		}
		addSaveAndNewListener();

		if(dialogModel.getGroup() != null) {
			dialogFunctionGroup = functionLibraryService.getFunctionLibraryClass(dslMetadataService.getFullyQualifiedName(dialogModel.getGroup()));
			if(dialogModel.getInitialization() != null) {
				initializationMethod = functionLibraryService.getMethod(dialogFunctionGroup, dialogModel.getInitialization().getName());
			}
			if(dialogModel.getPreSave() != null) {
				preSaveMethod = functionLibraryService.getMethod(dialogFunctionGroup, dialogModel.getPreSave().getName());
			}
			if(dialogModel.getPostSave() != null) {
				postSaveMethod = functionLibraryService.getMethod(dialogFunctionGroup, dialogModel.getPostSave().getName());
			}
			for(DialogFieldHook fieldHook:dialogModel.getFieldHooks()) {
				Method preFocus = null;
				Method postFocus = null;
				if(fieldHook.getPreFocus() != null) {
					preFocus = functionLibraryService.getMethod(dialogFunctionGroup, fieldHook.getPreFocus().getName());
				}
				if(fieldHook.getPostFocus() != null) {
					postFocus = functionLibraryService.getMethod(dialogFunctionGroup, fieldHook.getPostFocus().getName());
				}
				Pair functions = new Pair(preFocus, postFocus);
				YField fld = (YField)associationService.getModelElement(viewId+"."+dialogModel.getDto().getName()+"."+fieldHook.getAttribute().getName());
				if(fld != null) {
					fieldHooks.put(fld, functions);
					fld.eAdapters().add(new AdapterImpl() {
						@Override
						public void notifyChanged(org.eclipse.emf.common.notify.Notification notification) {
							if (notification.getEventType() == org.eclipse.emf.common.notify.Notification.SET) {
								if(notification.getFeatureID(ExtensionModelPackage.class) == ExtensionModelPackage.YTEXT_FIELD__LAST_FOCUS_EVENT) {
									YField fld = (YField)((YEmbeddableEvent)notification.getNewValue()).getEmbeddable();
									if(fieldHooks.containsKey(fld) && fieldHooks.get(fld) != null) {
										executeDialogFunction("pre field "+fld.getName(), fieldHooks.get(fld).getKey(), fld);
									}
								}
								if(notification.getFeatureID(ExtensionModelPackage.class) == ExtensionModelPackage.YTEXT_FIELD__LAST_BLUR_EVENT) {
									YField fld = (YField)((YEmbeddableEvent)notification.getNewValue()).getEmbeddable();
									if(fieldHooks.containsKey(fld) && fieldHooks.get(fld) != null) {
										executeDialogFunction("post field "+fld.getName(), fieldHooks.get(fld).getValue(), fld);
									}
								}
							}
						}
					});
				}
			}
		}
	}
	
	private void addSaveAndNewListener() {
		List<EObject> elements = associationService.getModelElements();
		for(EObject element:elements) {
			if(element instanceof YButton && ((YButton)element).getTags().contains(ILayoutingStrategy.TAG__SAVEANDNEW)) {
				((YButton)element).addClickListener(this);
				((YButton)element).getTags().add(uuid);
			}
		}
	}

	public Component getContent() {
		return parent;
	}

	@Override
	public void validationChanged(IFieldValidationManager.Event event) {
		// add them to the Vaaclipse status manager
		IStatusScope scope = statusManager.getScopeFor(mPart);
		scope.modifyStatus(event.getOldStatus(), event.getNewStatus());
		applyValidationResult();
	}

	/**
	 * Apply the validation result to the view.
	 */
	protected void applyValidationResult() {
		// set the validation result
		viewContext.setBean(BEAN_SLOT__VALIDATION_ERROR, Boolean.FALSE);
		log.debug("applyValidationResult {}", ((Boolean)viewContext.getBean(BEAN_SLOT__VALIDATION_ERROR)).booleanValue());
	}

	@IsValid
	public boolean isDataValid() {
		if(viewContext == null) {
			return true;
		}
		Boolean result = (Boolean) viewContext.getBean(BEAN_SLOT__VALIDATION_ERROR);
		if(result == null || !result) {
			eventBroker.send(IE4Topics.ToolBarEvents.NOTIFY_TOOLBAR_DIALOG_STATE, createStateLabelEvent(IE4Topics.ToolBarEvents.Labels.VALIDITY, IE4Topics.ToolBarEvents.States.VALID, getStateLabelUUID()));
		} else {
			eventBroker.send(IE4Topics.ToolBarEvents.NOTIFY_TOOLBAR_DIALOG_STATE, createStateLabelEvent(IE4Topics.ToolBarEvents.Labels.VALIDITY, IE4Topics.ToolBarEvents.States.INVALID, getStateLabelUUID()));
		}
		if(result == null) {
			return true;
		}
		return !result;
	}
	
	@Focus
	public void setFocus() {
		if(viewContext != null && mPart != null) {
			String fieldId = null;
			LayoutClickEvent event = mPart.getContext().get(LayoutClickEvent.class);
			if(event != null && event.getClickedComponent() instanceof UI) {
				fieldId = event.getClickedComponent().getId();
			}
			focusingStrategy.focusField(yView, fieldId);
		}
	}
	
	@IsDirty
	public boolean isDirty() {
		Object currentDto = viewContext.getBean(IViewContext.MAIN_BEAN_SLOT);
		return isDirtyDto(currentDto);
	}
	
	private boolean isDirtyDto(Object dto) {
		boolean dirty = false;
		if (dto != null) {
			// check if any dto in the dto tree is dirty
			DirtyStateAdapter adapter = DtoUtils.getAdapter(DirtyStateAdapter.class, dto);
			if (adapter != null) {
				dirty = adapter.isDirty();
				if(dirty != oldDirty ) {
					log.debug("dirty state adapter returned {} for dto {}", dirty, dto.getClass().getName());
					oldDirty = dirty;
				}
			}
		}
		if(dirty) {
			eventBroker.send(IE4Topics.ToolBarEvents.NOTIFY_TOOLBAR_DIALOG_STATE, createStateLabelEvent(IE4Topics.ToolBarEvents.Labels.STATE, IE4Topics.ToolBarEvents.States.DIRTY, getStateLabelUUID()));
		} else {
			eventBroker.send(IE4Topics.ToolBarEvents.NOTIFY_TOOLBAR_DIALOG_STATE, createStateLabelEvent(IE4Topics.ToolBarEvents.Labels.STATE, IE4Topics.ToolBarEvents.States.CLEAN, getStateLabelUUID()));
		}
		return dirty;
	}
	
	@IsPositioned
	public boolean isDtoPositioned() {
		boolean isPositioned = false;
		DTO currentDto = (DTO)viewContext.getBean(IViewContext.MAIN_BEAN_SLOT);
		if (currentDto != null) {
			if(DtoUtils.getIdValue(currentDto) != null) {
				isPositioned = true;
			}
		}
		return isPositioned;
	}

	@IsNew
	public boolean isNewDto() {
		return newCreatedDto;
	}
	
	/**
	 * Deletes the current dto entry.
	 */
	protected void doDelete() {
		DTO deletedDto = (DTO) viewContext.getBean(IViewContext.MAIN_BEAN_SLOT);
		dtoService.delete(deletedDto);
	    Notification.show(dslMetadataService.translate(user.getLocale().toLanguageTag(), "deleted"),Notification.Type.HUMANIZED_MESSAGE);
		// initial state of the dialog has to be NEW. This
		// fills
		// the view context with a initial blank bean.
		createNew(dto);
	}

	/**
	 * Check other dialogs whether we could use their selection to prefill owners.
	 * Check eclipse context for information to prefill owners
	 *
	 * @param newDto the new dto
	 */
	private void prefillOwners(Object newDto) {
		if(mPart != null) {
			MPerspective mPersp = mPart.getContext().get(MPerspective.class);
			if (mPersp != null) {
				for (Field field : DtoUtils.getOwnerDomainReferences(newDto.getClass())) {
					// look in dialog's contexts
					List<IViewContext> contexts = ecviewContainer.getECViews(mPersp);
					for (IViewContext context : contexts) {
						if (this.viewContext == context) {
							continue;
						}
						Object bean = context.getBean(IViewContext.MAIN_BEAN_SLOT);
						if (bean instanceof IDto) {
							// must reload owner cause else will set owner to dirty on perspective
							IDTOService<? extends Object> ownerService = DtoServiceAccess.getService(bean.getClass());
							Object idVal=DtoUtils.getIdValue(bean);
							if(idVal != null) {
								Object beanCopy = ownerService.get(idVal);
								if(beanCopy != null) {
									DtoUtils.setValue(newDto, field.getName(), beanCopy);
								}
							}
						}
					}
					// look in context for selection
					String key = EntityUtils.getQualifiedEntityNameForQualifiedDtoName(field.getType().getName())+"."+DtoUtils.getIdField(field.getType()).getName();
					Object idObj = SelectionStore.getSelectionFromPerspectiveContext(mPart, key);
					if(!(idObj instanceof List<?>) && idObj != null) {
						IDTOService<? extends Object> ownerService = DtoServiceAccess.getService(field.getType());
						Object beanCopy = ownerService.get(idObj);
						if(beanCopy != null) {
							DtoUtils.setValue(newDto, field.getName(), beanCopy);
						}
					}
				}
			}
		}
	}

	/**
	 * If there comes a selections event with a potential owner we use it to prefill owners.
	 *
	 * @param event the event
	 */
	private void reflectOwners(final EventDispatcherEvent event) {
		List<Field> owners = DtoUtils.getOwnerDomainReferences(dto);
		for(Field field:owners) {
			String key = EntityUtils.getQualifiedEntityNameForQualifiedDtoName(field.getType().getName())+"."+DtoUtils.getIdField(field.getType()).getName();
			if(key.equals(event.getTopic())) {
				Object currentDto = viewContext.getBean(IViewContext.MAIN_BEAN_SLOT);
				if(currentDto != null) {
					Object bean = getDtoFromEvent(event, field.getType().getName());
					if(bean != null) {
						DtoUtils.setValue(currentDto, field.getName(), bean);
						DtoUtils.getAdapter(DirtyStateAdapter.class, currentDto).resetDirty();
					}
				}
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.osbp.osgi.hybrid.api.AbstractHybridVaaclipseView#
	 * createComponents ()
	 */
	@Override
	public void createComponents() {
		if(!dialogModel.isStateful()) {
			// initial state of the dialog has to be NEW. This fills the view
			// context with a initial blank bean.
			createNew(dto);
		}
		if(dialogModel.isEmbedded()) {
			// OSBP UI Code
			viewContext = ecviewComponent.setValue(viewId, null, renderingParams);
			viewContext.setLocale(user.getLocale());
			YView yView = (YView) viewContext.getViewEditpart().getModel();
			
			if (yView == null) {
				Notification.show("Dialog could not be found!", Type.ERROR_MESSAGE);
				return;
			}
		}
	}
	
	/**
	 * Setup validation bridge.
	 */
	protected void setupValidationBridge() {
		// create a validation enhancer. If an error message is added to the
		// field validation manager. The enhancer will set the id of the mpart
		// to the status.
		ecviewFieldValidationManager = viewContext.getService(IFieldValidationManager.class.getName());
		ecviewFieldValidationManager.setEnhancer(new IFieldValidationManager.Enhancer() {
			@Override
			public void enhance(IStatus status) {
				if(mPart != null) {
					status.putProperty(IStatus.PROP_UI_APPLICATION_ID, mPart.getElementId());
				} else {
					status.putProperty(IStatus.PROP_UI_APPLICATION_ID, dialogModel.getName());
				}
			}
		});

		ecviewFieldValidationManager.addListener(this);
	}

	protected boolean validate(DTO mainDto) {
		if(mainDto == null) {
			return true;
		}
		log.debug("{}", "validation start");
		Set<IStatus> oldValidationResult = validationResult != null ? new HashSet<>(validationResult)
				: new HashSet<>();

		validationResult = dtoService.validate(mainDto, ValidationKind.OTHER, renderingParams);

		for (IStatus status : validationResult) {
			// set the application id to the status
			if(mPart != null) {
				status.putProperty(IStatus.PROP_UI_APPLICATION_ID, mPart.getElementId());
			} else {
				status.putProperty(IStatus.PROP_UI_APPLICATION_ID, dialogModel.getName());
			}

			if (status.containsProperty(IStatus.PROP_FIELD_ID)
					&& status.containsProperty(IStatus.PROP_FIELD_I18N_KEY)) {
				continue;
			}

			// fix the field id. Therefore we try to find the yField that is
			// bound to the property path of javax.validation result.
			if (!status.containsProperty(IStatus.PROP_FIELD_ID)) {
				if (status.containsProperty(IStatus.PROP_JAVAX_PROPERTY_PATH)) {
					String path = (String) status.getProperty(IStatus.PROP_JAVAX_PROPERTY_PATH);

					// if path points to a collection, then remove all the
					// collection stuff, since Vaadin can not focus rows
					if (path.matches(".*\\[\\d*\\].*")) {
						path = path.substring(0, path.indexOf("["));
					}

					// using a regex to find the yElement:
					// "beanslot/.*/{propertyPath}"
					YEmbeddable yElement = (YEmbeddable) viewContext
							.findBoundField(String.format("%s.*/%s", BindingIdUtil.BEANSLOT, path));
					if (yElement != null) {
						status.putProperty(IStatus.PROP_FIELD_ID, yElement.getId());
						status.putProperty(IStatus.PROP_FIELD_I18N_KEY, yElement.getLabelI18nKey());
					}
				}
			}
		}

		// now update the field with the new Status instances
		//
		for (IStatus status : oldValidationResult) {
			String fieldId = (String) status.getProperty(IStatus.PROP_FIELD_ID);
			if (fieldId != null && !fieldId.trim().equals("")) {
				YEmbeddable yElement = (YEmbeddable) viewContext.findYEmbeddableElement(fieldId);
				IFieldEditpart editpart = ModelUtil.findEditpart(yElement);
				if (editpart != null) {
					editpart.removeExternalStatus(status);
				}
			}
			log.debug("remove old status {}", status.getMessage());
		}

		for (IStatus status : validationResult) {
			String fieldId = (String) status.getProperty(IStatus.PROP_FIELD_ID);
			if (fieldId != null && !fieldId.trim().equals("")) {
				YEmbeddable yElement = (YEmbeddable) viewContext.findYEmbeddableElement(fieldId);
				IFieldEditpart editpart = ModelUtil.findEditpart(yElement);
				if (editpart != null) {
					editpart.addExternalStatus(status);
				}
			}
			log.debug("add new status {}", status.getMessage());
		}
		if(!validationResult.isEmpty()) {
			log.debug("{}", "get scope for statusManager");
			statusManager.getScopeFor(mPart).modifyStatus(oldValidationResult, validationResult);
		}
		return validationResult.isEmpty();
	}

	/**
	 * Removes the old view.
	 */
	private void removeOldView() {
		if (viewContext != null) {
			viewContext.dispose();
		}
		if (layoutManager.getDataArea().getComponentCount() > 0) {
			layoutManager.getDataArea().removeAllComponents();
		}

	}

	/**
	 * Creates the rendering parameters.
	 *
	 * @return the map
	 */
	protected Map<String, Object> createRenderingParams() {
		Map<String, Object> params = new HashMap<>();
		Map<String, Object> services = new HashMap<>();
		params.put(IViewContext.PARAM_SERVICES, services);
		params.put(IViewContext.PROP_SLOT, IViewContext.MAIN_BEAN_SLOT);
		params.put(IViewContext.PARAM_THIRDPARTY_SERVICE_PROVIDER, new ECViewToE4ServiceBridge(eclipseContext));
		services.put(org.eclipse.osbp.runtime.common.event.IEventBroker.class.getName(),
				new E4EventBrokerAdapter(eventBroker));
		services.put(IUser.class.getName(), user);
		// this service will handle reload requests from YSuggestTextField
		services.put(IReloadRequestService.class.getName(), reloadRequestService);
		
		if(dialogModel.isStateful()) {
		    IConfiguration config = new IConfiguration() {
		    	@Override
		    	public void beforeUiRendering(IContext viewContext) {
		    		for(UiBeanSlot slot : dialogModel.getUiView().getBeanSlots()) {
		    			if(dslMetadataService.hasSupertype(slot.getJvmType(), IDto.class)) {
		    				Class<?> dtoClass = dslMetadataService.getClass(slot.getJvmType().getQualifiedName(), "dto");
		    				viewContext.createBeanSlot(slot.getName(), dtoClass).setValue(dslMetadataService.getClassInstance(dtoClass, "dto"));
		    			} else if(dslMetadataService.hasSupertype(slot.getJvmType(), IStateMachineParticipant.class) || dslMetadataService.hasSupertype(slot.getJvmType(), IPeripheral.class)) {
		    				Class<?> participantClass = dslMetadataService.getClass(slot.getJvmType().getQualifiedName(), "statemachine");
		    				IStateMachineParticipant participantInstance = (IStateMachineParticipant)dslMetadataService.getClassInstance(participantClass, "statemachine");
		    				participantInstance.setLocale(user.getLocale());
		    				viewContext.createBeanSlot(slot.getName(), participantClass).setValue(participantInstance);
		    			} else if(dslMetadataService.hasSupertype(slot.getJvmType(), IStateMachine.class)) {
		    				Class<?> statemachineClass = dslMetadataService.getClass(slot.getJvmType().getQualifiedName(), "statemachine");
		    				IStateMachine statemachineInstance = (IStateMachine)dslMetadataService.getClassInstance(statemachineClass, "statemachine");
		    				statemachineInstance.setLocale(user.getLocale());
		    				statemachineInstance.setUser(user);
		    				statemachineInstance.setEclipseContext(eclipseContext);
		    				viewContext.createBeanSlot(slot.getName(), statemachineClass).setValue(statemachineInstance);
		    			} else if(dslMetadataService.hasSupertype(slot.getJvmType(), IBlobConverter.class)) {
				    		viewContext.createBeanSlot(slot.getName(), BlobConverter.class).setValue(new BlobConverter(blobService));
		    			}
		    		}
		    		viewContext.setLocale(user.getLocale());
		    	}
		    	@Override
		    	public void afterUiRendering(IContext context) {
		    	}
		    	@Override
		    	public void beforeBind(IContext context) {
		    	}
		    	@Override
		    	public void afterBind(IContext context) {
		    		for(UiBeanSlot slot : dialogModel.getUiView().getBeanSlots()) {
		    			if(dslMetadataService.hasSupertype(slot.getJvmType(), IStateMachineParticipant.class)) {
		    				((IStateMachineParticipant)context.getBeanSlot(slot.getName()).getValue()).init();
		    			}
		    			if(dslMetadataService.hasSupertype(slot.getJvmType(), IDataProvider.class)) {
				    		for(UiBeanSlot innerslot : dialogModel.getUiView().getBeanSlots()) {
				    			if(dslMetadataService.hasSupertype(innerslot.getJvmType(), IDto.class)) {
						    		if (context.getBeanSlot(innerslot.getName()) != null) {
						    			((IDataProvider)context.getBeanSlot(slot.getName()).getValue()).addDatasource(innerslot.getName(), context.getBeanSlot(innerslot.getName()).getValueType());
						    		}
				    			}
				    		}
		    			}
		    		}
		    		// at the very end - start the statemachines
		    		for(UiBeanSlot slot : dialogModel.getUiView().getBeanSlots()) {
		    			if(dslMetadataService.hasSupertype(slot.getJvmType(), IStateMachine.class)) {
		    				((IStateMachine)context.getBeanSlot(slot.getName()).getValue()).start();
		    			}
		    		}
		    	}
		    };
		    params.put(IViewContext.PARAM_CONFIGURATION, config);
		}
		return params;
	}

	/**
	 * Shows a dialog which warns about loosing data.
	 *
	 * @param context
	 *            the context
	 * @param currentDto
	 *            the current dto
	 * @param newDto
	 *            the new dto
	 */
	protected void showLoosingDataDialog(Object newDto, Object currentDto) {
		if (isDirtyDto(currentDto)) {
			AcceptLoosingDataDialog.showDialog(dslMetadataService, themeResourceService, new Runnable() {
				@Override
				public void run() {
					viewContext = ecviewComponent.setValue(viewId, newDto, renderingParams);
					setNewCreatedDto(false);
					updateBindings(newDto);
				}
			}, null);
		} else if(newDto == null) {
			createNew(dto);
		} else {
			setNewCreatedDto(false);
			updateBindings(newDto);
		}
	}

//	protected void showSaveDialog(Object newDto) {
//		final Object dto = newDto;
//		AcceptSaveDialog.showDialog(dslMetadataService, themeResourceService, new Runnable() {
//			@Override
//			public void run() {
//				viewContext = ecviewComponent.setValue(viewId, dto, renderingParams);
//			}
//		}, null);
//	}

	protected void showDeleteDialog(Object currentDto) {
		if(isDirtyDto(currentDto)) {
			AcceptDeleteDialog.showDialog(dslMetadataService, themeResourceService, new Runnable() {
				@Override
				public void run() {
					createNew(dto);
				}
			}, null);
		} else {
			createNew(dto);
		}
	}
	
	protected void showQueryDeleteDialog() {
		QueryDeleteDialog.showDialog(dslMetadataService, themeResourceService, new Runnable() {
			@Override
			public void run() {
				doDelete();
			}
		}, null);
	}

	@Override
	public void localeChanged(final Locale locale) {
		if(viewContext != null) {
			viewContext.setLocale(locale);
		}
		if (layoutManager != null && dialogLabel != null) {
			layoutManager.setLabelValue(
					dslMetadataService.translate(user.getLocale().toLanguageTag(), dialogLabel));
		}
		if(infoWindow != null) {
			infoWindow.setLocale(locale);
		}
		// set locale to all statemachine beans
		if(getViewContext() != null && getViewContext().getValueBeans() != null) {
			for(Entry<String, ISlot> slotEntry:getViewContext().getValueBeans().entrySet()) {
				if(slotEntry.getValue() instanceof IStateMachineParticipant) {
					((IStateMachineParticipant)slotEntry.getValue().getValue()).setLocale(locale);
				}
			}
		}
	}

	@Override
	public void receiveEvent(final EventDispatcherEvent event) {
		switch (event.getCommand()) {
		case OK:		// comes from SelectionDialog of subtypes
			if (viewContext != null && event.getSender().equals(viewId)
				&& event.getData().containsKey(EventDispatcherDataTag.OBJECT)) {
				if (selectWindow != null) {
					selectWindow.close();
					UI.getCurrent().removeWindow(selectWindow);
					selectWindow = null;
					createNew((Class<?>)event.getData().get(EventDispatcherDataTag.OBJECT));
				}
			}
			break;
		case CLOSE:
			if(viewContext != null && event.getSender().equals(viewId) && event.getTopic().equals("DTOInfoDialog")) {
				if(infoWindow != null) {
					infoWindow.close();
					UI.getCurrent().removeWindow(infoWindow);
					infoWindow = null;
				}
			}
			break;
		case SELECT:
			if (manualInput) {
				return;
			}
			MPerspective perspective = null;
			ArrayList<String> allowedSenderParts = null;
			if(mPart != null) {
				perspective = eclipseContext.get(MPerspective.class);
				allowedSenderParts = (ArrayList<String>) eclipseContext.getActive(MPart.class).getTransientData().get(IPerspectiveProvider.EventDispatcherConstants.ACCEPTED_SENDERS);
			}
			if((event.getPerspective() == null || (perspective != null && event.getPerspective().equals(perspective))) && ((allowedSenderParts != null && allowedSenderParts.contains(event.getSender())) || allowedSenderParts == null)){
				if (dtoService != null && viewContext != null && !event.getSender().equals(viewId)) {
					if(event.getTopic().equals(dtoName) || event.getTopic().equals(primaryKey)) {
						handleSelectEvent(event);
					} else if(newCreatedDto){	// while in mode "new" then reflect all external selections to the owner fields
						reflectOwners(event);
					}
	    		}
			}
			break;
		case REFRESH:
			if (!event.getSender().equals(viewId) && event.getTopic().equals(entityName)) {
				if (!newCreatedDto) {
					final UI currentUi = eclipseContext.get(UI.class); 
					DTO currentDto = (DTO) viewContext.getBean(IViewContext.MAIN_BEAN_SLOT);
					IDto newDto = (IDto) dtoService.get(DtoUtils.getIdValue(currentDto));
					currentUi.accessSynchronously(new Runnable() {
						@Override
						public void run() {
							VaadinObservables.activateRealm(currentUi);
							showLoosingDataDialog(newDto, currentDto);
						}
					});
				}
			}
			break;
		case SAVE:
			if (!event.getSender().equals(viewId) && event.getTopic().equals(entityName)) {
				if (event.getData().containsKey(EventDispatcherDataTag.ID)) {
					final UI currentUi = eclipseContext.get(UI.class); 
					Object eventDataId = event.getData().get(EventDispatcherDataTag.ID);
					DTO currentDto = (DTO) viewContext.getBean(IViewContext.MAIN_BEAN_SLOT);
					Object currentDtoId = DtoUtils.getIdValue(currentDto);
					IDto newDto = (IDto) dtoService.get(eventDataId);
					if (eventDataId != null && idEquals(eventDataId, currentDtoId)) {
						currentUi.accessSynchronously(new Runnable() {
							@Override
							public void run() {
								VaadinObservables.activateRealm(currentUi);
								showLoosingDataDialog(newDto, currentDto);
							}
						});
					}
				}
			}
			break;
		case DELETE:
			if (!event.getSender().equals(viewId) && event.getTopic().equals(entityName)) {
				if (event.getData().containsKey(EventDispatcherDataTag.ID)) {
					final UI currentUi = eclipseContext.get(UI.class); 
					Object eventDataId = event.getData().get(EventDispatcherDataTag.ID);
					DTO currentDto = (DTO) viewContext.getBean(IViewContext.MAIN_BEAN_SLOT);
					Object currentDtoId = DtoUtils.getIdValue(currentDto);
					if (eventDataId != null && idEquals(eventDataId, currentDtoId)) {
						currentUi.accessSynchronously(new Runnable() {
							@Override
							public void run() {
								VaadinObservables.activateRealm(currentUi);
								showDeleteDialog(currentDto);
							}
						});
					}
				}
			}
			break;
		case ACTION:
			if (uuid.equals(event.getTopic()) && event.getData().containsKey(EventDispatcherDataTag.BUTTON_ID)) {
				Object id = event.getData().get(EventDispatcherDataTag.BUTTON_ID);
				if (id instanceof DialogActionEnum) {
					DialogActionEnum enumId = (DialogActionEnum) id;
					switch (enumId) {
					case DIALOG_ACTION_NEW:
						makeNew();
						break;
					case DIALOG_ACTION_SAVE_AS_NEW:
						actionSaveAsNew();
					    break;
					case DIALOG_ACTION_SAVE_AND_NEW:
						actionSaveAndNew();
						break;
					case DIALOG_ACTION_SAVE:
						actionSave();
						break;
					case DIALOG_ACTION_DELETE:
						showQueryDeleteDialog();
						break;
					case DIALOG_ACTION_CANCEL:
						actionCancel();
						break;
					}
				} else if (id instanceof UIActionEnum) {
					UIActionEnum uiEnumId = (UIActionEnum) id;
					switch (uiEnumId) {
					case DATABASE_INFO:
						if(infoWindow == null) {
							infoWindow = new DTOInfoDialog(eclipseContext, user.getLocale(), viewId, "DTOInfoDialog");
							infoWindow.setDto(viewContext.getBean(IViewContext.MAIN_BEAN_SLOT));
							UI.getCurrent().addWindow(infoWindow);
						}
						break;
					}
				}
				// force focus on me for validation report
				eclipseContext.activate();
			}
			break;
		}
	}

	private void actionCancel() {
		DTO reloadedDto = dtoService.reload((DTO) viewContext.getBean(IViewContext.MAIN_BEAN_SLOT));
		setNewCreatedDto(reloadedDto == null);
		updateBindings(reloadedDto);
	}

	private void actionSave() {
		DTO savedDto = (DTO) viewContext.getBean(IViewContext.MAIN_BEAN_SLOT);
		if(validate(savedDto)) {
			if( executeDialogFunction("pre save", preSaveMethod, savedDto) )
				dtoService.update(savedDto);
			DTO newDto = dtoService.reload(savedDto);
			executeDialogFunction("post save", postSaveMethod, newDto);
	    	updateBindings(newDto);
	    	setNewCreatedDto(false);
		    Notification.show(dslMetadataService.translate(user.getLocale().toLanguageTag(), "saved"),Notification.Type.HUMANIZED_MESSAGE);
		}
	}

	private void actionSaveAndNew() {
		DTO savedDto = (DTO) viewContext.getBean(IViewContext.MAIN_BEAN_SLOT);
		if(validate(savedDto)) {
			if( executeDialogFunction("pre save", preSaveMethod, savedDto) )
				dtoService.update(savedDto);
			DTO newDto = dtoService.reload(savedDto);
			executeDialogFunction("post save", postSaveMethod, newDto);
			if(lastBaseDto != null) {
				createNew(lastBaseDto);
			} else {
				makeNew();
			}
			Notification.show(dslMetadataService.translate(user.getLocale().toLanguageTag(), "savedandnew"),Notification.Type.HUMANIZED_MESSAGE);
		}
	}

	private void actionSaveAsNew() {
		DTO newDto = (DTO) DtoUtils.copyDto(viewContext.getBean(IViewContext.MAIN_BEAN_SLOT));
		if(validate(newDto)) {
			if( executeDialogFunction("pre save", preSaveMethod, newDto) )
				dtoService.update(newDto);
			newDto = dtoService.reload(newDto);
			executeDialogFunction("post save", postSaveMethod, newDto);
			updateBindings(newDto);
			setNewCreatedDto(false);
		    Notification.show(dslMetadataService.translate(user.getLocale().toLanguageTag(), "savedas"),Notification.Type.HUMANIZED_MESSAGE);
		}
	}

	private boolean executeDialogFunction(String what, Method method, Object obj) {
		if(method != null) {
			Boolean retVal = false;
			Exception ex = null;
			try {
				retVal = (Boolean) method.invoke(dialogFunctionGroup, obj, eclipseContext);
			} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
				ex = e;
			}
			if(!retVal) {
				String message = what+" "+method.getName()+" failed";
				if(ex != null) {
					message += " due to exception " + ex.getCause();
				}
				Notification.show(message, Type.ERROR_MESSAGE);
				return false;
			}
		}
		return true;
	}

	private void handleSelectEvent(EventDispatcherEvent event) {
		log.debug("buffer select. Class:{} ObjectID:{}", getClass().getName(), System.identityHashCode(this));
		if(timer != null && timer.isRunning()) {
			log.debug("{}", "buffered select restarted.");
			timer.restart();
		} else {
			timer = new Timer(50, new ActionListener(){
				@Override
				public void actionPerformed(ActionEvent e) {
					final UI currentUi = eclipseContext.get(UI.class); 
					Object newDto = getDtoFromEvent(event);
					Object currentDto = viewContext.getBean(IViewContext.MAIN_BEAN_SLOT);
					currentUi.accessSynchronously(new Runnable() {
						@Override
						public void run() {
							VaadinObservables.activateRealm(currentUi);
							showLoosingDataDialog(newDto, currentDto);
						}
					});
				}
			});
			timer.setRepeats(false);
			timer.start();
		}
	}

	private Object getDtoFromEvent(EventDispatcherEvent event) {
		return getDtoFromEvent(event, null);
	}
	
	private Object getDtoFromEvent(EventDispatcherEvent event, String refDtoName) {
		Object dto = null;
		if (event.getData().containsKey(EventDispatcherDataTag.ID)) {
			Object id = event.getData().get(EventDispatcherDataTag.ID);
			if (id != null) {
				if(refDtoName == null) {
					if(dtoService instanceof IDTOHistorizedService) {
						dto = ((IDTOHistorizedService<DTO>)dtoService).get(id, true);
					} else {
						dto = dtoService.get(id);
					}
				} else {
					dto = DtoServiceAccess.getService(refDtoName).get(id);
				}
			}
		} else if (event.getData().containsKey(EventDispatcherDataTag.DTO)) {
			dto = event.getData().get(EventDispatcherDataTag.DTO);
		}
		return dto;
	}

	private void makeNew() {
		if (subTypes.size() > 1) {
			selectWindow = selectDialog.init(eventDispatcher, viewId, uuid, subTypes, dto, dslMetadataService.translate(user.getLocale().toLanguageTag(), "Select SubType"), dslMetadataService.translate(user.getLocale().toLanguageTag(), "Ok"));
			UI.getCurrent().addWindow(selectWindow);
		} else {
			createNew(dto);
			lastBaseDto = dto;
		}
	}

	/**
	 * Creates a new dto.
	 *
	 * @param type
	 *            the type for the dto, could be a sub-type
	 */
	protected Object createNew(Class<?> type) {
		log.debug("create new");
		Object newDto = null;
		try {
			if(type != null){				
				newDto = type.newInstance();
				setNewCreatedDto(true);
				prefillOwners(newDto);
				initializeDto(newDto);
				if(DtoUtils.getAdapter(DirtyStateAdapter.class, newDto) == null) {
					log.debug("register dirty adapter {}", newDto.getClass().getName());
					DtoUtils.registerAdapter(dirtyStateAdapter, newDto);
				}
				DtoUtils.getAdapter(DirtyStateAdapter.class, newDto).resetDirty();
				DtoUtils.getAdapter(DirtyStateAdapter.class, newDto).setActive(true);
				updateBindings(newDto);
				viewContext.setBean(BEAN_SLOT__VALIDATION_ERROR, Boolean.FALSE);
			}
		} catch (InstantiationException | IllegalAccessException e) {
			log.error("{}", e);
		}
		return newDto;
	}

	private void initializeDto(Object newDto) {
		if(initializationMethod != null) {
			executeDialogFunction("initializing", initializationMethod, newDto);
		}
	}

	@PostConstruct
	public void activate() {
	    initDialog();
		user.addUserLocaleListener(this);
		eventDispatcher.addEventReceiver(this);
		if(!dialogModel.isEmbedded()) {
			super.initView();
			onFocusField = new EventHandler() {
				@Override
				public void handleEvent(Event event) {
					String[] names = event.getPropertyNames();
					String partId = (String) event.getProperty(IE4Topics.PartEvents.PROP_MPART_ID);
					String fieldId = (String) event.getProperty(IE4Topics.PartEvents.PROP_FIELD_ID);
					if(mPart.getElementId().equals(partId)) {
						focusingStrategy.focusField(yView, fieldId);
					}
				}
			};
			eventBroker.subscribe(IE4Topics.PartEvents.FOCUS_FIELD_TOPIC, onFocusField);
			if(dialogModel.isStateful()) {
				if(getViewContext() != null && getViewContext().getValueBeans() != null) {
					for(String selector:getViewContext().getValueBeans().keySet()) {
						ISlot slot = getViewContext().getBeanSlot(selector);
						if(IPeripheral.class.isAssignableFrom(slot.getValueType())) {
							((IPeripheral)slot.getValue()).initDevices(getBeeper(), getAudio(), getVideo());
						} else if(IStateMachine.class.isAssignableFrom(slot.getValueType())) {
							((IStateMachine)slot.getValue()).installKeyEventConsumer(getParent());
						}
					}
				}
			}
		}
	}
	
	@PreDestroy
	public void deactivate() {
		if(dialogModel.isStateful()) {
			if(getViewContext() != null && getViewContext().getValueBeans() != null) {
				for(String selector:getViewContext().getValueBeans().keySet()) {
					ISlot slot = getViewContext().getBeanSlot(selector);
					if(IPeripheral.class.isAssignableFrom(slot.getValueType())) {
						((IPeripheral)slot.getValue()).releaseDevices();
					} else if(IStateMachine.class.isAssignableFrom(slot.getValueType())) {
						((IStateMachine)slot.getValue()).uninstallKeyEventConsumer();
					}
				}
			}
		}
		user.removeUserLocaleListener(this);
		eventDispatcher.removeEventReceiver(this);
		if(!dialogModel.isEmbedded()) {
			eventBroker.unsubscribe(onFocusField);
			if(infoWindow != null) {
				infoWindow.close();
				UI.getCurrent().removeWindow(infoWindow);
				infoWindow = null;
			}
			super.destroyView();
		}
	}

	protected Map<String, Object> createStateLabelEvent(IE4Topics.ToolBarEvents.Labels labelType, IE4Topics.ToolBarEvents.States state, String uuid) {
		Map<String, Object> properties = new HashMap<>();
		properties.put(IE4Topics.ToolBarEvents.STATE_LABEL, labelType.name());
		properties.put(IE4Topics.ToolBarEvents.STATE_STATE, state.name());
		properties.put(IE4Topics.ToolBarEvents.STATE_UUID, uuid);
		return properties;
	}
	
	private boolean idEquals(Object id, Object id2) {
		if (id2.getClass().isAssignableFrom(id.getClass())) {
			if (id instanceof String) {
				return ((String) id).equals(id2);
			} else if (id instanceof Integer) {
				return ((Integer) id).intValue() == ((Integer) id2).intValue();
			}
		}
		return false;
	}

	/**
	 * Update data with a new dto
	 *
	 * @param newDto
	 *            the new dto
	 */
	private void updateBindings(Object newDto) {
		viewContext = ecviewComponent.setValue(viewId, newDto, renderingParams);
		if(newDto != null) {
			log.debug("update bindings for dto:{}", newDto.getClass().getName());
			if(infoWindow != null) {
				infoWindow.setDto(newDto);
			}
			DtoUtils.getAdapter(DirtyStateAdapter.class, newDto).setActive(true);
		}
	}

	protected void setNewCreatedDto(boolean state) {
		newCreatedDto = state;
		reloadRequestService.setMode(!state);
		if(newCreatedDto) {
			eventBroker.send(IE4Topics.ToolBarEvents.NOTIFY_TOOLBAR_DIALOG_STATE, createStateLabelEvent(IE4Topics.ToolBarEvents.Labels.MODE, IE4Topics.ToolBarEvents.States.ADD_ENTRY, getStateLabelUUID()));
		} else {
			eventBroker.send(IE4Topics.ToolBarEvents.NOTIFY_TOOLBAR_DIALOG_STATE, createStateLabelEvent(IE4Topics.ToolBarEvents.Labels.MODE, IE4Topics.ToolBarEvents.States.MODIFY_ENTRY, getStateLabelUUID()));
		}
	}
	
	@Override
	public String getStateLabelUUID() {
		if(toolbar != null) {
			return toolbar.getStateLabelUUID();
		}
		return null;
	}
	
	/**
	 * Sets the input to the dialog.
	 * 
	 * @param dto
	 */
	@Override
	public void setInput(Object dto) {
		this.dto = (Class<?>) dto;
		if (dto != null && viewContext != null) {
			dtoService = (IDTOService<DTO>) DtoServiceAccess.getService(this.dto);
			DTO persistentDto = dtoService.get(DtoUtils.getIdValue(dto));
			viewContext.setBean(IViewContext.MAIN_BEAN_SLOT, persistentDto);
		}
	}

	/**
	 * If true, then EventDispatcherEvents are being ignored.
	 * 
	 * @param manualInput
	 */
	@Override
	public void setEnableManualInput(boolean manualInput) {
		this.manualInput = manualInput;
	}

	/**
	 * Creates the embedded toolbar for embedded dialogs.
	 */
	private void createEmbeddedToolbar() {
		taskButtons = new ArrayList<Button>();
		HorizontalLayout tools = new HorizontalLayout();
		tools.addStyleName("os-embedded-toolbar");
		tools.setSpacing(false);

		Button b = new Button(null, new Button.ClickListener() {
			public void buttonClick(ClickEvent event) {
				DTO savedDto = (DTO) viewContext.getBean(IViewContext.MAIN_BEAN_SLOT);
				if(validate(savedDto)) {
					dtoService.update(savedDto);
					DTO newDto = dtoService.reload(savedDto);
			    	updateBindings(newDto);
			    	setNewCreatedDto(false);
				    Notification.show(dslMetadataService.translate(user.getLocale().toLanguageTag(), "saved"),Notification.Type.HUMANIZED_MESSAGE);
				    notifySaveListeners(newDto);
				}
			}
		});
		b.setIcon(themeResourceService.getThemeResource("dssave", ThemeResourceType.ICON));
		b.setDescription(null);
		b.setEnabled(true);
		b.addStyleName("v-button-small");
		tools.addComponent(b);
		taskButtons.add(b);
		layoutManager.getDataArea().addComponentAsFirst(tools);
	}

	/**
	 * Adds a new save listener.
	 * 
	 * @param listener
	 */
	public void addSaveListener(Consumer<DTO> listener) {
		if (saveListeners == null) {
			saveListeners = new ArrayList<>();
		}
		saveListeners.add(listener);
	}

	/**
	 * Removes the given save listener.
	 * 
	 * @param listener
	 */
	public void removeSaveListener(Consumer<DTO> listener) {
		if (saveListeners == null) {
			return;
		}
		saveListeners.remove(listener);
	}

	protected void notifySaveListeners(DTO dto) {
		if (saveListeners == null) {
			return;
		}

		for (Consumer<DTO> listener : saveListeners.toArray(new Consumer[saveListeners.size()])) {
			listener.accept(dto);
		}
	}

	/**
	 * Gets the uuid.
	 *
	 * @return the uuid
	 */
	protected String getUUID() {
		return uuid;
	}

	public IEclipseContext getEclipseContext() {
		return eclipseContext;
	}

	public IViewContext getViewContext() {
		return viewContext;
	}

	public IUser getUser() {
		return user;
	}

	public IDSLMetadataService getDslMetadataService() {
		return dslMetadataService;
	}

	public IThemeResourceService getThemeResourceService() {
		return themeResourceService;
	}

	public IReportProvider getReportProvider() {
		return reportProvider;
	}

	public IBlobService getBlobService() {
		return blobService;
	}

	@Override
	public void clicked(YButton yButton) {
		// only if the click is for this instance
		for(String tag:yButton.getTags()) {
			if(uuid.equals(tag)) {
				actionSaveAndNew();
			}
		}
	}
}
