/**
 *                                                                            
 * Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
 *                                                                            
 * All rights reserved. This program and the accompanying materials           
 * are made available under the terms of the Eclipse Public License 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.osgi.hybrid.api;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;

import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.core.services.events.IEventBroker;
import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.e4.ui.model.application.ui.MUIElement;
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.modeling.EPartService;
import org.eclipse.e4.ui.workbench.modeling.IPartListener;
import org.eclipse.osbp.bpm.api.IBlipBPMConstants;
import org.eclipse.osbp.core.api.persistence.IPersistenceService;
import org.eclipse.osbp.dsl.common.datatypes.IDto;
import org.eclipse.osbp.runtime.web.vaadin.databinding.VaadinObservables;
import org.eclipse.osbp.ui.api.themes.IThemeResourceService;
import org.eclipse.osbp.ui.api.themes.IThemeResourceService.ThemeResourceType;
import org.eclipse.osbp.ui.api.useraccess.AbstractAuthorization;
import org.eclipse.osbp.ui.api.useraccess.AbstractPosition;
import org.eclipse.osbp.utils.vaadin.beeper.Beeper;
import org.eclipse.osbp.webserver.messagequeue.ECXMqMessageAttribute;
import org.eclipse.osbp.webserver.messagequeue.ECXMqMessageEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.vaadin.server.VaadinRequest;
import com.vaadin.ui.AbstractOrderedLayout;
import com.vaadin.ui.Audio;
import com.vaadin.ui.FormLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Video;

public abstract class AbstractHybridVaaclipseView implements IHybridVaadinVaaclipseListener, IPartListener {
	
	@Inject
	IEventBroker eventBroker;

	@Inject
	protected IPersistenceService persistenceService;

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

	public enum RenderMode {
		SYNCHRONOUSLY, ASYNCHRONOUSLY
	}

	private IEclipseContext fEclipseContext;
	private MApplication fE4App;
	private VerticalLayout fParent;
	private boolean fViewInitialized;

	private RenderMode renderMode = RenderMode.ASYNCHRONOUSLY;
	private boolean firstTime = true;
	private int pollingInterval = 2000;
	/** The beeper. */
	private Beeper beeper = new Beeper();
	private Audio audio = new Audio();
	private Video video = new Video();

	private RecursiveFocusBlurListener fRecursiveFocusBlurListener;

	private EPartService partService;

	public AbstractHybridVaaclipseView() {}
	/**
	 * <b><i><u>Warning:</u> never use initializing class attributes in the definition!<br>
	 * Due to Java specific internals the overriden method createView() will be called before that initializing will be done!<br>
	 * Instead put any initializing inside the overriden method createView()!</i></b>
	 * 
	 * @param parent
	 * @param context
	 * @param app
	 */
	public AbstractHybridVaaclipseView(final VerticalLayout parent, final IEclipseContext context, final MApplication app) {
		fE4App = app;
		fEclipseContext = context;
		fViewInitialized = false;
		fParent = parent;
		fRecursiveFocusBlurListener = RecursiveFocusBlurListener.attachFor(fParent);
//		parent.addComponent(beeper);
//		audio.setShowControls(false);
//		parent.addComponent(audio);
//		video.setShowControls(false);
	}

	@PostConstruct
	public void initView() {
		partService = fEclipseContext.get(EPartService.class);
		partService.addPartListener(this);
		HybridVaadinVaaclipseConnector.instance(fEclipseContext).addListener(this);
		HybridVaadinVaaclipseConnector.instance(fEclipseContext).setE4Application(fE4App);
		VaadinObservables.getRealm(UI.getCurrent());
		UI.getCurrent().setPollInterval(pollingInterval);
		createView(fParent);
		postInit(null);
		renderData(true);
	}

	@PreDestroy
	public void preDestroy() {
		fRecursiveFocusBlurListener.detach();
		HybridVaadinVaaclipseConnector.instance(fEclipseContext).removeListener(this);
		partService.removePartListener(this);
	}

	public void promptSecurityMessage(String message, AbstractOrderedLayout layout) {
		layout.removeAllComponents();
		FormLayout area = new FormLayout();
		layout.addComponent(area);

		Label msg = new Label(message);
		msg.setPrimaryStyleName("osbp");
		msg.setStyleName("osbpSecurityPrompt");
		if	(getThemeResourceService() != null) {
			msg.setIcon(getThemeResourceService().getThemeResource("locksview.gif", ThemeResourceType.IMAGE));
		}
		else {
			LOGGER.error("themeResourceService not set!");
		}
		area.addComponent(msg);
	}

	public final MApplication getApplication() {
		return fE4App;
	}

	public final VerticalLayout getParent() {
		return fParent;
	}

	public final IEclipseContext getContext() {
		return fEclipseContext;
	}

	public final MPart getPart() {
		return fEclipseContext.get(MPart.class);
	}

	public final String getProcessWorkloadDtoFqn() {
		return (String) getTransientDataVariable(IBlipBPMConstants.VARIABLE_PROCESS_WORKLOAD_DTO_FQN);
	}

	public final IDto getProcessInitialWorkloadDto() {
		return (IDto) getTransientDataVariable(IBlipBPMConstants.VARIABLE_PROCESS_WORKLOAD_DTO);
	}

	public final Class<?> getTaskOperativeDtoClass() {
		return (Class<?>) getTransientDataVariable(IBlipBPMConstants.VARIABLE_TASK_OPERATIVE_DTO_CLASS);
	}

	public final String getTaskOperativeDtoFqn() {
		return (String) getTransientDataVariable(IBlipBPMConstants.VARIABLE_TASK_OPERATIVE_DTO_FQN);
	}

	@SuppressWarnings("unchecked")
	public final List<IDto> getTaskInitialOperativeDtos() {
		return (List<IDto>) getTransientDataVariable(IBlipBPMConstants.VARIABLE_TASK_OPERATIVE_DTOS);
	}

	public final Object getTransientDataVariable(String variable) {
		MPerspective perspective = getPerspective();
		if (perspective != null) {
			Map<String, Object> data = perspective.getTransientData();
			if (data != null) {
				return data.get(variable);
			}
		}
		return null;
	}

	public final MPerspective getPerspective() {
		MUIElement step = getPart();
		while ((step != null) && !(step instanceof MPerspective)) {
			step = step.getParent();
		}
		return (MPerspective) step;
	}

	public final IPersistenceService getPersistenceService() {
		return fEclipseContext.get(IPersistenceService.class);
	}

	protected final boolean isViewInitialized() {
		return fViewInitialized;
	}

	/**
	 * <b><i><u>Warning:</u> put any initializing inside the your overriden method createView()!<br>
	 * Due to Java specific internals the overriden method createView() will be called before that initializing will be done!</i></b>
	 * 
	 * @param parent
	 */
	protected abstract void createView(final VerticalLayout parent);

	protected abstract void createComponents();

	// renderData is used for components that are not fully embedded in vaadin's connector structure
	// and must be repainted when parent window resizes
	// but can also be used to make component rendering asynchronously from view creation
	public void renderData() {
		LOGGER.debug("renderData not firsttime");
		renderData(false);
	}

	public void renderData(boolean firstTime) {
		// the first time we only want to be triggered by the initial createView process, not by changeLocale
		if (this.firstTime) {
			if (!firstTime) {
				LOGGER.debug("renderData ignored because not firsttime");
				return;
			} else {
				this.firstTime = false;
			}
		}
		if (UI.getCurrent() == null) {
			LOGGER.debug("renderData has no current ui");
			return;
		}
		if (renderMode == RenderMode.SYNCHRONOUSLY) {
			LOGGER.debug("render synchronously");
			UI.getCurrent().accessSynchronously(new Runnable() {
				@Override
				public void run() {
					createComponents();
				}
			});
		} else {
			LOGGER.debug("render asynchronously");
			UI.getCurrent().access(new Runnable() {
				@Override
				public void run() {
					createComponents();
				}
			});
		}
	}

	public IThemeResourceService getThemeResourceService() {
		if (fEclipseContext.containsKey(IThemeResourceService.class)) {
			return fEclipseContext.get(IThemeResourceService.class);
		}
		return null;
	}

	/**
	 * You <b>must call this at the end of the overridden init()</b>
	 */
	protected final void postInit(VaadinRequest request) {
		HybridVaadinVaaclipseConnector.instance(fEclipseContext).postInit(request);
		fViewInitialized = true;
		if (isAuthenticated()) {
			setAuthenticated(isAuthenticated());
		}
	}

	/**
	 * React in the application according to <code>authenticated</code>
	 * 
	 * @param authenticated
	 *            true if the user is authenticated now!
	 */
	@Override
	public void setAuthenticated(boolean authenticated) {
		// now send the list of perspectives
		HybridVaadinVaaclipseConnector.instance(fEclipseContext).updatePerspectiveList();
	}

	protected final boolean isAuthenticated() {
		return HybridVaadinVaaclipseConnector.instance(fEclipseContext).isAuthenticated();
	}

	protected final IDto getAuthenticatedUser() {
		return HybridVaadinVaaclipseConnector.instance(fEclipseContext).getUser();
	}

	protected final AbstractPosition getAuthenticatedPosition() {
		return HybridVaadinVaaclipseConnector.instance(fEclipseContext).getPosition();
	}

	protected final Collection<String> getAuthenticatedRoles() {
		return HybridVaadinVaaclipseConnector.instance(fEclipseContext).getRoles();
	}

	protected final AbstractAuthorization getAuthenticatedPermissions() {
		return HybridVaadinVaaclipseConnector.instance(fEclipseContext).getAuthorization();
	}

	protected final Set<String> getAllUsers() {
		return HybridVaadinVaaclipseConnector.instance(fEclipseContext).getAllUsers();
	}

	/**
	 * Try to authenticate with the credentials given!<br>
	 * {@link #setAuthenticated(boolean)} will explicit be called!
	 * 
	 * @param portalId
	 * @param userName
	 * @param password
	 * @return true if the user was authenticated successful
	 */
	// protected boolean tryToAuthenticate(String portalId, String userName, String password) {
	// return HybridVaadinVaaclipseConnector.instance().tryToAuthenticate(portalId, userName, password);
	// }

	/**
	 * Logout from the Shiro API and send a LOGOUT event via ActiveMQ
	 */
	protected void logout() {
		HybridVaadinVaaclipseConnector.instance(fEclipseContext).logout();
	}

	/**
	 * handle any message received via ActiveMQ
	 * 
	 * @param event
	 * @param body
	 */
	@Override
	public final boolean onMessage(ECXMqMessageEvent event, Map<ECXMqMessageAttribute, Object> body) {
		boolean retcode = false;
		switch (event) {
		case FOCUS_PERSPECTIVE:
			retcode = HybridVaadinVaaclipseConnector.instance(fEclipseContext).onFocusPerspective(body.get(ECXMqMessageAttribute.PERSPECTIVE_ID).toString());
			break;
		case REQUEST_ICON:
			retcode = HybridVaadinVaaclipseConnector.instance(fEclipseContext).requestIcon(body.get(ECXMqMessageAttribute.PERSPECTIVE_ID).toString());
			break;
		case TRY_AUTHENTICATE:
		case DISPOSE:
		case LOGOUT:
		default:
			break;
		}
		return retcode;
	}

	@Override
	public void partActivated(MPart part) {
		if(part != null) {
			HybridVaadinVaaclipseConnector.instance(fEclipseContext).activatePartStateRefresher(part);
			MPerspective active = HybridVaadinVaaclipseConnector.findCurrentPerspectiveFor(part);
			if (active instanceof MPerspective) {
				HybridVaadinVaaclipseConnector.instance(fEclipseContext).updatePerspectiveList();
				HybridVaadinVaaclipseConnector.instance(fEclipseContext).updateFocusPerspective(active.getElementId());
			}
		}
	}

	@Override
	public void partBroughtToTop(MPart part) {
		HybridVaadinVaaclipseConnector.instance(fEclipseContext).activatePartStateRefresher(part);
		LOGGER.debug("part {} brought to top", part);
	}

	@Override
	public void partDeactivated(MPart part) {
		LOGGER.debug("part {} deactivated", part);
	}

	@Override
	public void partHidden(MPart part) {
		LOGGER.debug("part {} hidden", part);
	}

	@Override
	public void partVisible(MPart part) {
		LOGGER.debug("part {} visible", part);
	}

	/**
	 * Try to authenticate with the credentials given!<br>
	 * {@link #setAuthenticated(boolean)} will explicit be called!
	 * 
	 * @param portalId
	 * @param userName
	 * @param password
	 * @return true if the user was authenticated successful
	 */
	protected boolean tryToAuthenticate(String portalId, String userName, String password) {
		return HybridVaadinVaaclipseConnector.instance(fEclipseContext).tryToAuthenticate(portalId, userName, password);
	}

	public RenderMode getRenderMode() {
		return renderMode;
	}

	public void setRenderMode(RenderMode renderMode) {
		this.renderMode = renderMode;
	}

	public int getPollingInterval() {
		return pollingInterval;
	}

	public void setPollingInterval(int pollingInterval) {
		this.pollingInterval = pollingInterval;
	}
	
	public Beeper getBeeper() {
		return beeper;
	}
	public Audio getAudio() {
		return audio;
	}
	public Video getVideo() {
		return video;
	}
//	abstract void activate(MPart part);
//	abstract void deactivate(MPart part);
}
