/*
 *                                                                            
 *  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                                 
 *                                                                            
 *  Initial contribution:                                                      
 *     Loetz GmbH & Co. KG
 * 
 */
package org.eclipse.osbp.abstractstatemachine;

import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.channels.SelectableChannel;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicBoolean;

import javax.annotation.PreDestroy;
import javax.swing.Timer;

import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.osbp.dsl.common.datatypes.IDto;
import org.eclipse.osbp.preferences.ProductConfiguration;
import org.eclipse.osbp.runtime.common.filter.IQuery;
import org.eclipse.osbp.runtime.common.session.ISession;
import org.eclipse.osbp.ui.api.customfields.IBlobService;
import org.eclipse.osbp.ui.api.message.IMessageRequester;
import org.eclipse.osbp.ui.api.message.MessageEvent;
import org.eclipse.osbp.ui.api.message.MessageEvent.EventType;
import org.eclipse.osbp.ui.api.message.MessageRequesterEvent;
import org.eclipse.osbp.ui.api.metadata.IDSLMetadataService;
import org.eclipse.osbp.ui.api.report.IReportProvider;
import org.eclipse.osbp.ui.api.statemachine.IDataProvider;
import org.eclipse.osbp.ui.api.statemachine.IEventSource;
import org.eclipse.osbp.ui.api.statemachine.IPeripheral;
import org.eclipse.osbp.ui.api.statemachine.IStateMachine;
import org.eclipse.osbp.ui.api.themes.IThemeResourceService;
import org.eclipse.osbp.ui.api.user.IUser;
import org.eclipse.osbp.utils.vaadin.MessageDialog;
import org.eclipse.osbp.utils.vaadin.YesNoDialog;
import org.eclipse.osbp.vaadin.addons.keyevents.KeyEventExtension;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.slf4j.Logger;

import com.vaadin.event.ShortcutAction.KeyCode;
import com.vaadin.server.Page;
import com.vaadin.server.WebBrowser;
import com.vaadin.ui.Component;
import com.vaadin.ui.HasComponents;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;

public abstract class AbstractStateMachine implements IStateMachine, IMessageRequester.ClickRecipient {
	private static final String ENABLED = "Enabled";
	private static Logger logger = org.slf4j.LoggerFactory.getLogger("statemachine");
	protected Collection<IEventSource.Enabler> enablerList = new CopyOnWriteArraySet<>();
	protected Collection<IDataProvider.Provider> providerList = new CopyOnWriteArraySet<>();
	protected Collection<IPeripheral.Command> peripheralList = new CopyOnWriteArraySet<>();
	protected Map<String, MessageDialog> messageDialogs = new HashMap<>();
	protected Map<String, YesNoDialog> yesnoDialogs = new HashMap<>();
	protected WebBrowser webBrowser = Page.getCurrent().getWebBrowser();
	protected IUser user;
	protected Locale locale;
	protected IDSLMetadataService dslMetadataService;
	protected IThemeResourceService themeResourceService;
	protected IReportProvider reportProvider;
	protected IBlobService blobService;
	protected Map<String, Map<String, Object>> storage = new HashMap<>();
	protected SelectableChannel channel;
	protected String lastTrigger;
	protected IEclipseContext eclipseContext;
	protected LinkedBlockingQueue<MessageEvent> queue = new LinkedBlockingQueue<>();
	protected boolean remotePortOverridden = false;

	protected Map<Integer, String> keyMapper = new HashMap<Integer, String>() {
		private static final long serialVersionUID = 8801421284339992078L;
		{
			put(KeyCode.TAB, "TAB");
			put(KeyCode.ENTER, "ENTER");
			put(KeyCode.PAGE_UP, "PGUP");
			put(KeyCode.PAGE_DOWN, "PGDOWN");
			put(KeyCode.BACKSPACE, "BACKSPACE");
			put(KeyCode.INSERT, "INSERT");
			put(KeyCode.DELETE, "DELETE");
			put(KeyCode.HOME, "HOME");
			put(KeyCode.END, "END");
			put(KeyCode.ARROW_DOWN, "DOWNARROW");
			put(KeyCode.ARROW_UP, "UPARROW");
			put(KeyCode.ARROW_LEFT, "LEFTARROW");
			put(KeyCode.ARROW_RIGHT, "RIGHTARROW");
			put(KeyCode.ESCAPE, "ESC");
			put(KeyCode.F1, "F1");
			put(KeyCode.F2, "F2");
			put(KeyCode.F3, "F3");
			put(KeyCode.F4, "F4");
			put(KeyCode.F5, "F5");
			put(KeyCode.F6, "F6");
			put(KeyCode.F7, "F7");
			put(KeyCode.F8, "F8");
			put(KeyCode.F9, "F9");
			put(KeyCode.F10, "F10");
			put(KeyCode.F11, "F11");
			put(KeyCode.F12, "F12");
		}
	};
	private KeyEventExtension extension = null;
	private AtomicBoolean active = new AtomicBoolean(false);
	private AtomicBoolean blocking = new AtomicBoolean(false);
	private int remotePort = 9090;

	@Override
	public void installKeyEventConsumer(VerticalLayout layout) {
		extension = KeyEventExtension.addTo(layout);
		extension.setCallback(this::keyPressed);
	}

	@Override
	public void uninstallKeyEventConsumer() {
		if (extension != null) {
			extension.remove();
			extension = null;
		}
	}

	protected Component findById(HasComponents root, String id) {
		Iterator<Component> iterate = root.iterator();
		while (iterate.hasNext()) {
			Component c = iterate.next();
			if (id.equals(c.getId())) {
				return c;
			}
			if (c instanceof HasComponents) {
				Component cc = findById((HasComponents) c, id);
				if (cc != null)
					return cc;
			}
		}
		return null;
	}

	protected void keyPressed(org.eclipse.osbp.vaadin.addons.keyevents.client.Event e) {
		if (keyMapper.containsKey(e.charCode)) {
			logger.debug("keymapper code {}", keyMapper.get(e.charCode));
			processEvent(this, new MessageEvent(EventType.FUNCTIONALKEYBOARD, keyMapper.get(e.charCode)));
		} else {
			if(e.charCode > 95 && e.charCode < 106 ) {
				e.charCode -= 48;
			} else if(!e.shiftKeyDown && e.charCode > 57 && e.charCode < 91) {
				e.charCode += 32; 
			} else if(e.shiftKeyDown && e.charCode > 47 && e.charCode < 58) {
				e.charCode -= 16; 
			} else if(e.charCode == 192) {	// ö
				if(e.shiftKeyDown) {
					e.charCode = 0xD6;
				} else {
					e.charCode = 0xF6;
				}
			} else if(e.charCode == 222) {	// ä
				if(e.shiftKeyDown) {
					e.charCode = 0xC4;
				} else {
					e.charCode = 0xE4;
				}
			} else if(e.charCode == 186) {	// ü
				if(e.shiftKeyDown) {
					e.charCode = 0xDC;
				} else {
					e.charCode = 0xFC;
				}
			} else if(e.charCode == 219) {	// ß
				if(e.shiftKeyDown) {
					e.charCode = 63;
				} else {
					e.charCode = 0xDF;
				}
			}
			if (Character.isLetterOrDigit(e.charCode) || Character.isSpace((char)e.charCode)) {
				String evtCode = Character.toString((char) e.charCode);
				logger.debug("alpha or digit {}", evtCode);
				processEvent(this, new MessageEvent(EventType.KEYBOARD, Character.toString((char) e.charCode)));
			}
		}
	}

	@Override
	public void processEvent(final IStateMachine statemachine, final MessageEvent event) {
		synchronized (queue) {
			logger.debug("enqueue event {}", event);
			queue.add(event);
		}
	}

	protected abstract void doProcessEvent(final IStateMachine statemachine, final MessageEvent event);

	private void addEventProvider(IEventSource.Enabler listener) {
		enablerList.add(listener);
	}

	private void removeEventProvider(IEventSource.Enabler listener) {
		enablerList.remove(listener);
	}

	@Override
	public void registerEnabler(IEventSource.Enabler listener) {
		addEventProvider(listener);
	}

	@Override
	public void unregisterEnabler(IEventSource.Enabler listener) {
		removeEventProvider(listener);
	}

	@Override
	public void setUser(IUser user) {
		this.user = user;
	}

	@Override
	public IUser getUser() {
		return user;
	}

	@Override
	public String getUserName() {
		return user.getUserName();
	}

	@Override
	public String getUserPassword() {
		return user.getExtraPassword();
	}

	@Override
	public String getUserEmail() {
		return user.getEmail();
	}

	@Override
	public String getUserPosition() {
		return user.getPosition();
	}

	@Override
	public String getUserPrintService() {
		return user.getPrintService();
	}

	@Override
	public void setLocale(Locale locale) {
		this.locale = locale;
	}

	@Override
	public Locale getLocale() {
		return locale;
	}

	@Override
	public void setDslMetadataService(IDSLMetadataService dslMetadataService) {
		this.dslMetadataService = dslMetadataService;
	}

	@Override
	public IDSLMetadataService getDslMetadataService() {
		return dslMetadataService;
	}

	@Override
	public IThemeResourceService getThemeResourceService() {
		return themeResourceService;
	}

	@Override
	public void setThemeResourceService(IThemeResourceService themeResourceService) {
		this.themeResourceService = themeResourceService;
	}

	@Override
	public void setReportProvider(IReportProvider reportprovider) {
		this.reportProvider = reportprovider;
	}

	@Override
	public IReportProvider getReportProvider() {
		return reportProvider;
	}

	@Override
	public IBlobService getBlobService() {
		return blobService;
	}

	@Override
	public void setBlobService(IBlobService blobService) {
		this.blobService = blobService;
	}

	@Override
	public void enable(String id, Boolean enable) {
		for (IEventSource.Enabler listener : enablerList) {
			listener.enable(listener, id, enable);
		}
	}

	@Override
	public void toggle(String id) {
		for (IEventSource.Enabler listener : enablerList) {
			listener.toggle(listener, id + ENABLED);
		}
		for (IDataProvider.Provider listener : providerList) {
			listener.toggle(listener, id + ENABLED);
		}
		for (IPeripheral.Command listener : peripheralList) {
			listener.toggle(listener, id + ENABLED);
		}
	}

	@Override
	public Object get(String id) {
		Object value;
		for (IEventSource.Enabler listener : enablerList) {
			value = listener.get(listener, id);
			if (value != null) {
				return value;
			}
		}
		for (IDataProvider.Provider listener : providerList) {
			value = listener.get(listener, id);
			if (value != null) {
				return value;
			}
		}
		for (IPeripheral.Command listener : peripheralList) {
			value = listener.get(listener, id);
			if (value != null) {
				return value;
			}
		}
		return null;
	}

	@Override
	public Object get(String id, String parameter) {
		Object value;
		for (IEventSource.Enabler listener : enablerList) {
			value = listener.get(listener, id, parameter);
			if (value != null) {
				return value;
			}
		}
		for (IDataProvider.Provider listener : providerList) {
			value = listener.get(listener, id, parameter);
			if (value != null) {
				return value;
			}
		}
		for (IPeripheral.Command listener : peripheralList) {
			value = listener.get(listener, id, parameter);
			if (value != null) {
				return value;
			}
		}
		return null;
	}
	
	@Override
	public void set(String id, Object content) {
		for (IEventSource.Enabler listener : enablerList) {
			listener.set(listener, id, content);
		}
		for (IDataProvider.Provider listener : providerList) {
			listener.set(listener, id, content);
		}
		for (IPeripheral.Command listener : peripheralList) {
			listener.set(listener, id, content);
		}
	}

	@Override
	public void set(String id, String device, Object content) {
		for (IPeripheral.Command listener : peripheralList) {
			listener.set(listener, id, device, content);
		}
	}

	@Override
	public void clear(String id) {
		for (IEventSource.Enabler listener : enablerList) {
			listener.clear(listener, id);
		}
		for (IDataProvider.Provider listener : providerList) {
			listener.clear(listener, id);
		}
		for (IPeripheral.Command listener : peripheralList) {
			listener.clear(listener, id);
		}
	}

	@Override
	public void append(String id, String key) {
		for (IEventSource.Enabler listener : enablerList) {
			listener.append(listener, id, key);
		}
	}

	@Override
	public void remove(String id, int pos) {
		for (IEventSource.Enabler listener : enablerList) {
			listener.remove(listener, id, pos);
		}
	}

	@Override
	public void caption(String id, String value) {
		for (IEventSource.Enabler listener : enablerList) {
			listener.caption(listener, id, value);
		}
	}

	@Override
	public void image(String id, String imageName) {
		for (IEventSource.Enabler listener : enablerList) {
			listener.image(listener, id, imageName);
		}
	}

	@Override
	public void addDataProvider(IDataProvider.Provider listener) {
		providerList.add(listener);
	}

	@Override
	public void removeDataProvider(IDataProvider.Provider listener) {
		providerList.remove(listener);
	}

	@Override
	public void registerDataProvider(IDataProvider.Provider listener) {
		addDataProvider(listener);
	}

	@Override
	public void unregisterDataProvider(IDataProvider.Provider listener) {
		removeDataProvider(listener);
	}

	public void addPeripheral(IPeripheral.Command listener) {
		peripheralList.add(listener);
	}

	public void removePeripheral(IPeripheral.Command listener) {
		peripheralList.remove(listener);
	}

	@Override
	public void registerPeripheral(IPeripheral.Command listener) {
		addPeripheral(listener);
	}

	@Override
	public void unregisterPeripheral(IPeripheral.Command listener) {
		removePeripheral(listener);
	}

	@Override
	public Boolean find(String dtoName, IQuery query) {
		Boolean retVal;
		for (IDataProvider.Provider listener : providerList) {
			retVal = listener.find(listener, dtoName, query);
			if (retVal != null) {
				return retVal;
			}
		}
		return false;
	}

	@Override
	public Boolean find(String dtoName, String fieldName, Object search) {
		Boolean retVal;
		for (IDataProvider.Provider listener : providerList) {
			retVal = listener.find(listener, dtoName, fieldName, search);
			if (retVal != null) {
				return retVal;
			}
		}
		return false;
	}

	@Override
	public Collection<? extends IDto> findAll(String dtoName, IQuery query) {
		Collection<? extends IDto> retVal;
		for (IDataProvider.Provider listener : providerList) {
			retVal = listener.findAll(dtoName, query);
			if (retVal != null) {
				return retVal;
			}
		}
		return Collections.emptyList();
	}

	@Override
	public Collection<? extends IDto> findAll(String dtoName, String fieldName, Object search) {
		Collection<? extends IDto> retVal;
		for (IDataProvider.Provider listener : providerList) {
			retVal = listener.findAll(dtoName, fieldName, search);
			if (retVal != null) {
				return retVal;
			}
		}
		return Collections.emptyList();
	}

	@Override
	public void addTo(String dtoName, String listName, IDto dto) {
		for (IDataProvider.Provider listener : providerList) {
			listener.addTo(listener, dtoName, listName, dto);
		}
	}

	@Override
	public void removeFrom(String dtoName, String listName, IDto dto) {
		for (IDataProvider.Provider listener : providerList) {
			listener.removeFrom(listener, dtoName, listName, dto);
		}
	}

	@Override
	public void update(String dtoName) {
		for (IDataProvider.Provider listener : providerList) {
			listener.update(listener, dtoName, (IDto) listener.get(listener, dtoName));
		}
	}

	@Override
	public void reload(String dtoName) {
		for (IDataProvider.Provider listener : providerList) {
			listener.reload(listener, dtoName, (IDto) listener.get(listener, dtoName));
		}
	}

	@Override
	public void delete(String dtoName) {
		for (IDataProvider.Provider listener : providerList) {
			listener.delete(listener, dtoName, (IDto) listener.get(listener, dtoName));
		}
	}

	@Override
	public String getIPAddress() {
		// must define -Djava.net.preferIPv4Stack=true to always get IPv4 in
		// dual stack environments
		return webBrowser.getAddress(); // May be null, especially if running in
										// a Portlet.
	}

	@Override
	public String getHostName() {
		String hostName = null;
		try {
			InetAddress netAddress = InetAddress.getByName(webBrowser.getAddress());
			hostName = netAddress.getHostName().toLowerCase();
			logger.error("**** browser returned this host-name: {} ****", hostName);
		} catch (UnknownHostException e) {
			logger.error("{}", e);
		}
		return hostName;
	}
	
	@Override
	public int getRemotePort() {
		if(!remotePortOverridden) {
			if(ProductConfiguration.getJavaPosPortConfiguration() != null && !ProductConfiguration.getJavaPosPortConfiguration().isEmpty()) {
				return Integer.parseInt(ProductConfiguration.getJavaPosPortConfiguration());
			}
		}
		return remotePort;
	}
	
	@Override
	public void setRemotePort(int port) {
		remotePortOverridden = true;
		this.remotePort = remotePort;
	}

	@Override
	public boolean isItMe(String hostName) {
		String hostAddress;
		try {
			InetAddress netAddress = InetAddress.getByName(hostName);
			hostAddress = netAddress.getHostAddress();
			logger.error("**** browser returned this host-address: {} ****", hostAddress);
		} catch (UnknownHostException e) {
			logger.error("{}", e);
			return false;
		}
		boolean ret = getIPAddress().equals(hostAddress);
		if(!ret) {
			logger.error("**** browser host-address and requested host are not equal! Requested: {} ****", hostName);
		}
		return ret;
	}

	@Override
	public DateTime getNow() {
		return DateTime.now(DateTimeZone.UTC);
	}

	@Override
	public String getUserAgentInfo() {
		return webBrowser.getBrowserApplication();
	}

	@Override
	public Boolean isTouchDevice() {
		return webBrowser.isTouchDevice();
	}

	@Override
	public int getSceenWidth() {
		return webBrowser.getScreenWidth();
	}

	@Override
	public int getScreenHeight() {
		return webBrowser.getScreenHeight();
	}

	@PreDestroy
	void destroy() {
	}

	@Override
	public Locale getBrowserLocale() {
		return webBrowser.getLocale();
	}

	@Override
	public Boolean isHttps() {
		return webBrowser.isSecureConnection();
	}

	@Override
	public void start() {
		active.set(true);
		final UI ui = getEclipseContext().get(UI.class);
		Runnable runnable = () -> {
			while (active.get()) {
				if(!blocking.get()) {
					MessageEvent event;
					try {
						event = queue.take();
						ui.access(() -> {
							logger.debug("doProcess event {}", event);
							doProcessEvent(AbstractStateMachine.this, event);
						});
					} catch (InterruptedException e) {
						logger.debug("dequeuing was interrupted {}", e);
						Thread.currentThread().interrupt();
					}
				}
				try {
					Thread.sleep(10);
				} catch (InterruptedException e) {
					// TODO sleep interrupted
				}
			}
		};

		Thread thread = new Thread(runnable, "Statemachine processor " + getClass().getName());
		thread.setDaemon(true);
		thread.start();
	}

	@Override
	public void schedule(IStateMachine statemachine, int milliseconds, MessageEvent event) {
		Timer timer = new Timer(milliseconds, action -> statemachine.processEvent(statemachine, event));
		timer.setRepeats(false);
		timer.start();
	}

	/**
	 * @param doubleStr
	 * @return Double independent of locale
	 */
	@Override
	public Double parseDouble(String doubleStr) {
		String doubleStrIn = doubleStr.replaceAll("[^\\d,\\.]++", "");
		if (doubleStrIn.length() == 0) {
			return 0.0;
		}
		if (doubleStrIn.matches(".+\\.\\d+,\\d+$"))
			return Double.parseDouble(doubleStrIn.replaceAll("\\.", "").replaceAll(",", "."));
		if (doubleStrIn.matches(".+,\\d+\\.\\d+$"))
			return Double.parseDouble(doubleStrIn.replaceAll(",", ""));
		return Double.parseDouble(doubleStrIn.replaceAll(",", "."));
	}

	/**
	 * Format a double.
	 *
	 * @param value
	 *            the value
	 * @param length
	 *            the total length of the resulting string
	 * @param precision
	 *            the precision after decimal separator
	 * @return the string
	 */
	@Override
	public String formatDouble(Double value, int length, int precision) {
		String format = String.format("%% %d.%df", length, precision);
		return String.format(locale, format, value);
	}

	@Override
	public String getTranslation(String token) {
		if (dslMetadataService != null && locale != null) {
			return dslMetadataService.translate(locale.toLanguageTag(), token);
		}
		return token;
	}

	@Override
	public void closeMessage(String messageId) {
		if (messageDialogs.containsKey(messageId)) {
			MessageDialog messageDialog = messageDialogs.get(messageId);
			messageDialog.close();
			UI.getCurrent().removeWindow(messageDialog);
			messageDialogs.remove(messageId);
		}
	}

	@Override
	public void openMessage(String messageId) {
		openMessage(messageId, false);
	}

	@Override
	public void openMessage(String messageId, boolean okButton) {
		MessageDialog messageDialog = new MessageDialog(messageId, getTranslation(messageId));
		if (okButton) {
			messageDialog.addButton(getTranslation("ok"), new MessageEvent(EventType.MESSAGECLOSE, messageId));
			messageDialog.addButtonListener(this);
		}
		messageDialogs.put(messageId, messageDialog);
		UI.getCurrent().addWindow(messageDialog);
	}

	@Override
	public void openQuestion(String messageId, EventType type, String yesEvent, String noEvent, String cancelEvent) {
		MessageDialog messageDialog = new MessageDialog(messageId, getTranslation(messageId));
		messageDialog.addButton(getTranslation("yes"), new MessageEvent(type, yesEvent));
		messageDialog.addButton(getTranslation("no"), new MessageEvent(type, noEvent));
		messageDialog.addButton(getTranslation("cancel"), new MessageEvent(type, cancelEvent));
		messageDialog.addButtonListener(this);
		messageDialogs.put(messageId, messageDialog);
		UI.getCurrent().addWindow(messageDialog);
	}

	@Override
	public void messageButtonPressed(MessageRequesterEvent e) {
		MessageDialog messageDialog = messageDialogs.get(e.getId());
		messageDialog.close();
		UI.getCurrent().removeWindow(messageDialog);
		messageDialogs.remove(e.getId());
		this.processEvent(this, e.getEventData());
	}

	@Override
	public void dispatchMessages(MessageEvent event) {
		if (event.getType() == MessageEvent.EventType.TRIGGER) {
			lastTrigger = event.getId();
		}
		switch (event.getType()) {
		case ERROR:
			openMessage(event.getId(), true);
			break;
		case MESSAGEOPEN:
			openMessage(event.getId());
			break;
		case MESSAGECLOSE:
			closeMessage(event.getId());
			break;
		case STATUSOPEN:
		case STATUSCLOSE:
		default:
			break;
		}
	}

	@Override
	public Object getStorage(String key, String attribute) {
		if (storage.containsKey(key) && storage.get(key).containsKey(attribute)) {
			return storage.get(key).get(attribute);
		}
		return null;
	}

	@Override
	public Set<String> getStorageAttributes(String key) {
		if (storage.containsKey(key)) {
			return storage.get(key).keySet();
		}
		return Collections.emptySet();
	}

	@Override
	public void putStorage(String key, String attribute, Object content) {
		if (!storage.containsKey(key)) {
			storage.put(key, new HashMap<String, Object>());
		}
		storage.get(key).put(attribute, content);
	}

	@Override
	public void openChannel(SelectableChannel channel) {
		this.channel = channel;
	}

	@Override
	public SelectableChannel getChannel() {
		return channel;
	}

	@Override
	public void closeChannel() {
		if (channel != null) {
			try {
				channel.close();
			} catch (IOException e) { // NOSONAR
				// do nothing
			}
		}
	}

	@Override
	public String getLastTrigger() {
		return lastTrigger;
	}

	@Override
	public void setEclipseContext(IEclipseContext eclipseContext) {
		this.eclipseContext = eclipseContext;
		this.dslMetadataService = eclipseContext.get(IDSLMetadataService.class);
		this.themeResourceService = eclipseContext.get(IThemeResourceService.class);
		this.reportProvider = eclipseContext.get(IReportProvider.class);
		this.blobService = eclipseContext.get(IBlobService.class);
	}

	@Override
	public IEclipseContext getEclipseContext() {
		return eclipseContext;
	}

	@Override
	public void sendSlaveData(Map<String, Object> data) {
		String currentInstanceId = (String) getEclipseContext().get("e4ApplicationInstanceId");
		List<ISession> sessions = POSServiceBinder.getSessionManager()
				.getSessions(s -> s.get("e4ApplicationInstanceId").equals(currentInstanceId));
		if (!sessions.isEmpty()) {
			List<ISession> slaves = sessions.get(0).getSlaves();
			for (ISession slave : slaves) {
				slave.async(e -> {
					slave.sendData(data);
					return true;
				}, null);
			}
		}
	}
	
	@Override
	public void blockQueueTaking(boolean block) {
		logger.debug("switch blocking {}", block);
		blocking.set(block);
	}
	
}
