/*
 *                                                                            
 *  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 v1.0       
 *  which accompanies this distribution, and is available at                  
 *  http://www.eclipse.org/legal/epl-v10.html                                 
 *                                                                            
 *  Initial contribution:                                                      
 *     Loetz GmbH & Co. KG
 * 
 */
package org.eclipse.osbp.abstractstatemachine;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.FileLocator;
import org.eclipse.osbp.preferences.ProductConfiguration;
import org.eclipse.osbp.ui.api.message.MessageEvent;
import org.eclipse.osbp.ui.api.message.MessageEvent.EventType;
import org.eclipse.osbp.ui.api.pos.ISignatureEvent;
import org.eclipse.osbp.ui.api.pos.ISignatureListener;
import org.eclipse.osbp.ui.api.pos.IZVTTransactionData;
import org.eclipse.osbp.ui.api.pos.PenData;
import org.eclipse.osbp.ui.api.statemachine.IPeripheral;
import org.eclipse.osbp.ui.api.statemachine.IStateMachine;
import org.osgi.framework.FrameworkUtil;

import jpos.BaseControl;
import jpos.CashDrawer;
import jpos.CashDrawerConst;
import jpos.CashDrawerControl114;
import jpos.JposException;
import jpos.LineDisplay;
import jpos.LineDisplayConst;
import jpos.LineDisplayControl114;
import jpos.POSPrinter;
import jpos.POSPrinterConst;
import jpos.POSPrinterControl114;
import jpos.config.JposEntryRegistry;
import jpos.epson.EpsonLineDisplayConst;
import jpos.epson.EpsonPOSPrinterConst;
import jpos.events.ErrorEvent;
import jpos.events.ErrorListener;
import jpos.events.OutputCompleteEvent;
import jpos.events.OutputCompleteListener;
import jpos.events.StatusUpdateEvent;
import jpos.events.StatusUpdateListener;
import jpos.loader.simple.SimpleServiceManager;
import jpos.util.DefaultProperties;
import jpos.util.JposProperties;
import jpos.util.JposPropertiesConst;

/**
 * PeripheralService is a bridge between javaPOS and the state machine
 * participant.
 */
public abstract class AbstractPeripheralService extends AbstractStateMachineParticipant
		implements IPeripheral, IPeripheral.Command, StatusUpdateListener, ErrorListener, OutputCompleteListener, ISignatureListener {

	/** The devices. */
	protected Map<String, BaseControl> devices = new HashMap<>();

	/** The slip notifications enabled. */
	private boolean slipNotificationsEnabled = false;

	/** The windows created. */
	protected int windowsCreated = 0;

	/** The pt IP. */
	protected String ptIP;

	/** The pt port. */
	protected Integer ptPort;

	/** The props. */
	protected JposEntryRegistry props;

	/** is init done correctly? */
	protected boolean initDone = false;
	
	private List<PenData> penData = new ArrayList<>();

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * foodmartdialogdslplugin.AbstractStateMachineParticipant#setStatemachine
	 * (org.eclipse.osbp.ui.api.abstractstatemachine.IStateMachine)
	 */
	@Override
	public void setStatemachine(IStateMachine statemachine) {
		super.setStatemachine(statemachine);
		statemachine.registerPeripheral(this);
		if (POSServiceBinder.getPosService() != null) {
			POSServiceBinder.getPosService().setStatemachine(statemachine);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see foodmartdialogdslplugin.AbstractStateMachineParticipant#init()
	 */
	@Override
	public void init() {
		LOGGER.debug("Library path=" + System.getProperty("java.library.path"));
		// load all names of configured devices, instantiate and cache it
		String configFile = ProductConfiguration.getJavaPosConfiguration();
		if (configFile == null || configFile.length() == 0) {
			LOGGER.debug("POS setupfile is not registered in product preferences");
			return;
		}
		try {
			new URL(configFile);
			System.setProperty(JposPropertiesConst.JPOS_POPULATOR_FILE_URL_PROP_NAME, configFile);
		} catch (MalformedURLException e) {
			System.setProperty(JposPropertiesConst.JPOS_POPULATOR_FILE_PROP_NAME, configFile);
		}
		System.setProperty(JposPropertiesConst.JPOS_REG_POPULATOR_CLASS_PROP_NAME,
				"jpos.config.simple.xml.SimpleXmlRegPopulator");
		System.setProperty(JposPropertiesConst.JPOS_SERVICE_MANAGER_CLASS_PROP_NAME,
				"jpos.loader.simple.SimpleServiceManager");
		JposProperties jposProperties = new DefaultProperties();
		jposProperties.loadJposProperties();
		SimpleServiceManager serviceManager = new SimpleServiceManager(jposProperties);
		serviceManager.getEntryRegistry().load();
		props = serviceManager.getEntryRegistry();
		if (props != null && props.getSize() != 0) {
			initDone = initDevices();
		} else {
			LOGGER.debug("no devices are configured in file:{}", configFile);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.osbp.ui.api.statemachine.IPeripheral#isInitDone()
	 */
	@Override
	public boolean isInitDone() {
		return initDone;
	}

	// line display code
	/**
	 * Sets the display line.
	 *
	 * @param deviceName
	 *            the device name
	 * @param displayLine
	 *            the new display line
	 */
	public void setDisplayLine(String deviceName, String displayLine) {
		if (!initDone || !devices.containsKey(deviceName)) {
			return;
		}
		String[] parts = displayLine.split("\\|");
		try {
			if (parts.length > 1) {
				((LineDisplay) devices.get(deviceName)).displayText(parts[0], new Integer(parts[1].trim()));
			} else {
				((LineDisplay) devices.get(deviceName)).displayText(parts[0], LineDisplayConst.DISP_DT_NORMAL);
			}
		} catch (JposException e) {
			LOGGER.error("general error displayLine for device:{} text:{} ex:{}", deviceName, displayLine, e);
		} catch (Exception ex) {
			LOGGER.error("general error displayLine for device:{} text:{} ex:{}", deviceName, displayLine, ex);
		}
	}

	/**
	 * Registers a bitmap.
	 *
	 * @param deviceName
	 *            the device name
	 * @param registerBitmap
	 *            encodes a pipe separated tuple bitmapNumber, bitmapFilename
	 */
	public void setPrinterBitmap(String deviceName, String registerBitmap) {
		if (!initDone || !devices.containsKey(deviceName)) {
			return;
		}
		String[] parts = registerBitmap.split("\\|");
		String path = null;
		File file = null;
		try {
			// get absolute physical path of bundle
			file = FileLocator.getBundleFile(FrameworkUtil.getBundle(this.getClass()));
		} catch (IOException e) {
			LOGGER.error("jpos error setRegisterBitmap:{} ex:{}", registerBitmap, e);
			return;
		}
		if (file != null) {
			path = file.getAbsolutePath() + "/" + parts[1];
		}
		if (path != null) {
			try {
				if (((POSPrinterControl114) devices.get(deviceName)).getCapRecBitmap()) {
					int lineWidth = ((POSPrinterControl114) devices.get(deviceName)).getRecLineWidth();
					((POSPrinterControl114) devices.get(deviceName)).setBitmap(new Integer(parts[0]),
							POSPrinterConst.PTR_S_RECEIPT, path, lineWidth / 2, POSPrinterConst.PTR_BM_CENTER);
				}
			} catch (JposException e) {
				LOGGER.error("jpos error setRegisterBitmap for device:{} and:{} ex:{}", deviceName, registerBitmap, e);
			} catch (Exception ex) {
				LOGGER.error("general error registerBitmap for device:{} text:{} ex:{}", deviceName, registerBitmap,
						ex);
			}
		}
	}

	/**
	 * Registers a bitmap.
	 *
	 * @param deviceName
	 *            the device name
	 * @param registerBitmap
	 *            encodes a pipe separated tuple bitmapNumber, bitmapFilename
	 */
	public void setDisplayBitmap(String deviceName, String registerBitmap) {
		if (!initDone || !devices.containsKey(deviceName)) {
			return;
		}
		String[] parts = registerBitmap.split("\\|");
		String path = null;
		File file = null;
		try {
			// get absolute physical path of bundle
			file = FileLocator.getBundleFile(FrameworkUtil.getBundle(this.getClass()));
		} catch (IOException e) {
			LOGGER.error("jpos error setRegisterBitmap for device:{} and:{} ex:{}", deviceName, registerBitmap, e);
			return;
		}
		if (file != null) {
			path = file.getAbsolutePath() + "/" + parts[1];
		}
		if (path != null) {
			try {
				if (((LineDisplayControl114) devices.get(deviceName)).getCapBitmap()) {
					((LineDisplayControl114) devices.get(deviceName)).setBitmap(new Integer(parts[0]), parts[1],
							LineDisplayConst.DISP_BM_ASIS, LineDisplayConst.DISP_BM_LEFT, LineDisplayConst.DISP_BM_TOP);
				}
			} catch (JposException e) {
				LOGGER.error("jpos error setDisplayBitmap for device:{} and:{} ex:{}", deviceName, registerBitmap, e);
			} catch (Exception ex) {
				LOGGER.error("jpos error setDisplayBitmap for device:{} and:{} genericex:{}", deviceName,
						registerBitmap, ex);
			}
		}
	}

	/**
	 * Sets the display bitmap.
	 *
	 * @param deviceName
	 *            the device name
	 * @param displayBitmap
	 *            the new display bitmap
	 */
	public void setDisplayBitmap(String deviceName, Integer displayBitmap) {
		if (!initDone || !devices.containsKey(deviceName)) {
			return;
		}
		String text = String.format("\\u%03db|%dB", displayBitmap, displayBitmap);
		try {
			int[] pram2 = new int[1];
			Object pram3 = new Object();

			((LineDisplayControl114) devices.get(deviceName)).directIO(EpsonLineDisplayConst.DISP_DI_GRAPHIC, pram2,
					pram3);
			((LineDisplayControl114) devices.get(deviceName)).createWindow(0, 0, 64, 256, 64, 256);
			((LineDisplayControl114) devices.get(deviceName)).displayText(text, LineDisplayConst.DISP_DT_NORMAL);
		} catch (JposException e) {
			LOGGER.error("jpos error setDisplayBitmap for device:{} and:{} ex:{}", deviceName, displayBitmap, e);
		}
	}

	/**
	 * Sets the device brightness.
	 *
	 * @param deviceName
	 *            the device name
	 * @param deviceBrightness
	 *            the new device brightness
	 */
	public void setDeviceBrightness(String deviceName, Integer deviceBrightness) {
		if (!initDone || !devices.containsKey(deviceName)) {
			return;
		}
		try {
			((LineDisplayControl114) devices.get(deviceName)).setDeviceBrightness(deviceBrightness);
		} catch (JposException e) {
			LOGGER.error("jpos error deviceBrightness for device:{} and:{} ex:{}", deviceName, deviceBrightness, e);
		}
	}

	/**
	 * Sets the blink rate.
	 *
	 * @param deviceName
	 *            the device name
	 * @param blinkRate
	 *            the new blink rate
	 */
	public void setBlinkRate(String deviceName, Integer blinkRate) {
		if (!initDone || !devices.containsKey(deviceName)) {
			return;
		}
		try {
			((LineDisplayControl114) devices.get(deviceName)).setBlinkRate(blinkRate);
		} catch (JposException e) {
			LOGGER.error("jpos error blinkRate for device:{} and:{} ex:{}", deviceName, blinkRate, e);
		}
	}

	/**
	 * Sets the cursor type.
	 *
	 * @param deviceName
	 *            the device name
	 * @param cursorType
	 *            see: LineDisplayConst
	 */
	public void setCursorType(String deviceName, Integer cursorType) {
		if (!initDone || !devices.containsKey(deviceName)) {
			return;
		}
		try {
			((LineDisplayControl114) devices.get(deviceName)).setCursorType(cursorType);
		} catch (JposException e) {
			LOGGER.error("jpos error cursorType for device:{} and:{} ex:{}", deviceName, cursorType, e);
		}
	}

	/**
	 * Sets the marquee format.
	 *
	 * @param deviceName
	 *            the device name
	 * @param marqueeFormat
	 *            the new marquee format
	 */
	public void setMarqueeFormat(String deviceName, Integer marqueeFormat) {
		if (!initDone || !devices.containsKey(deviceName)) {
			return;
		}
		try {
			((LineDisplayControl114) devices.get(deviceName)).setMarqueeFormat(marqueeFormat);
		} catch (JposException e) {
			LOGGER.error("jpos error marqueeFormat for device:{} and:{} ex:{}", deviceName, marqueeFormat, e);
		}
	}

	/**
	 * Sets the marquee repeat wait.
	 *
	 * @param deviceName
	 *            the device name
	 * @param marqueeRepeatWait
	 *            the new marquee repeat wait
	 */
	public void setMarqueeRepeatWait(String deviceName, Integer marqueeRepeatWait) {
		if (!initDone || !devices.containsKey(deviceName)) {
			return;
		}
		try {
			((LineDisplayControl114) devices.get(deviceName)).setMarqueeRepeatWait(marqueeRepeatWait);
		} catch (JposException e) {
			LOGGER.error("jpos error marqueeRepeatWait for device:{} and:{} ex:{}", deviceName, marqueeRepeatWait, e);
		}
	}

	/**
	 * Sets the marquee type.
	 *
	 * @param deviceName
	 *            the device name
	 * @param marqueeType
	 *            the new marquee type
	 */
	public void setMarqueeType(String deviceName, Integer marqueeType) {
		if (!initDone || !devices.containsKey(deviceName)) {
			return;
		}
		try {
			((LineDisplayControl114) devices.get(deviceName)).setMarqueeType(marqueeType);
		} catch (JposException e) {
			LOGGER.error("jpos error marqueeType for device:{} and:{} ex:{}", deviceName, marqueeType, e);
		}
	}

	/**
	 * Sets the marquee unit wait.
	 *
	 * @param deviceName
	 *            the device name
	 * @param marqueeUnitWait
	 *            the new marquee unit wait
	 */
	public void setMarqueeUnitWait(String deviceName, Integer marqueeUnitWait) {
		if (!initDone || !devices.containsKey(deviceName)) {
			return;
		}
		try {
			((LineDisplayControl114) devices.get(deviceName)).setMarqueeUnitWait(marqueeUnitWait);
		} catch (JposException e) {
			LOGGER.error("jpos error marqueeUnitWait for device:{} and:{} ex:{}", deviceName, marqueeUnitWait, e);
		}
	}

	/**
	 * wraps: createWindow(int viewportRow, int viewportColumn, int
	 * viewportHeight , int viewportWidth, int windowHeight, int windowWidth);.
	 *
	 * @param deviceName
	 *            the device name
	 * @param createWindow
	 *            the new creates the window
	 */
	public void setCreateWindow(String deviceName, String createWindow) {
		if (!initDone || !devices.containsKey(deviceName)) {
			return;
		}
		String[] parts = createWindow.split("\\|");
		try {
			((LineDisplayControl114) devices.get(deviceName)).createWindow(new Integer(parts[0].trim()),
					new Integer(parts[1].trim()), new Integer(parts[2].trim()), new Integer(parts[3].trim()),
					new Integer(parts[4].trim()), new Integer(parts[5].trim()));
			windowsCreated++;
		} catch (JposException e) {
			LOGGER.error("jpos error createWindow for device:{} and:{} ex:{}", deviceName, createWindow, e);
		} catch (Exception ex) {
			LOGGER.error("jpos error createWindow for device:{} and:{} genericex:{}", deviceName, createWindow, ex);
		}
	}

	/**
	 * Sets the destroy window.
	 *
	 * @param deviceName
	 *            the device name
	 * @param destroyWindow
	 *            the new destroy window
	 */
	public void setDestroyWindow(String deviceName, String destroyWindow) { // NOSONAR
		if (!initDone || !devices.containsKey(deviceName)) {
			return;
		}
		try {
			if (windowsCreated > 0) {
				((LineDisplayControl114) devices.get(deviceName)).destroyWindow();
				windowsCreated--;
			}
		} catch (JposException e) {
			LOGGER.error("jpos error destroyWindow for device:" + deviceName + " {}", e);
		}
	}

	/**
	 * Sets the scroll.
	 *
	 * @param deviceName
	 *            the device name
	 * @param scroll
	 *            encodes a pipe separated tuple: direction, units
	 */
	public void setScroll(String deviceName, String scroll) {
		if (!initDone || !devices.containsKey(deviceName)) {
			return;
		}
		String[] parts = scroll.split("\\|");
		try {
			((LineDisplayControl114) devices.get(deviceName)).scrollText(new Integer(parts[0].trim()),
					new Integer(parts[1].trim()));
		} catch (JposException e) {
			LOGGER.error("jpos error scroll for device:{} and:{} ex:{}", deviceName, scroll, e);
		} catch (Exception ex) {
			LOGGER.error("jpos error scroll for device:{} and:{} genericex:{}", deviceName, scroll, ex);
		}
	}

	/**
	 * Sets the inter character wait.
	 *
	 * @param deviceName
	 *            the device name
	 * @param interCharacterWait
	 *            the new inter character wait
	 */
	public void setInterCharacterWait(String deviceName, Integer interCharacterWait) {
		if (!initDone || !devices.containsKey(deviceName)) {
			return;
		}
		try {
			((LineDisplayControl114) devices.get(deviceName)).setInterCharacterWait(interCharacterWait);
		} catch (JposException e) {
			LOGGER.error("jpos error interCharacterWait for device:{} and:{} ex:{}", deviceName, interCharacterWait, e);
		}
	}

	/**
	 * Sets the display at.
	 *
	 * @param deviceName
	 *            the device name
	 * @param displayTextAt
	 *            encodes a pipe separated quadruple: row, column, text,
	 *            attribute
	 */
	public void setDisplayTextAt(String deviceName, String displayTextAt) {
		if (!initDone || !devices.containsKey(deviceName)) {
			return;
		}
		String[] parts = displayTextAt.split("\\|");
		try {
			if (parts.length > 3) {
				((LineDisplayControl114) devices.get(deviceName)).displayTextAt(new Integer(parts[0].trim()),
						new Integer(parts[1].trim()), parts[2], new Integer(parts[3].trim()));
			} else {
				((LineDisplayControl114) devices.get(deviceName)).displayTextAt(new Integer(parts[0].trim()),
						new Integer(parts[1].trim()), parts[2], LineDisplayConst.DISP_DT_NORMAL);
			}
		} catch (JposException e) {
			LOGGER.error("jpos error displayTextAt for device:{} and:{} ex:{}", deviceName, displayTextAt, e);
		} catch (Exception ex) {
			LOGGER.error("jpos error displayTextAt for device:{} and:{} genericex:{}", deviceName, displayTextAt, ex);
		}
	}

	/**
	 * clears the display.
	 *
	 * @param deviceName
	 *            the device name
	 * @param clearDisplay
	 *            is nt used
	 */
	public void setClearDisplay(String deviceName, String clearDisplay) {
		if (!initDone || !devices.containsKey(deviceName)) {
			return;
		}
		try {
			if (windowsCreated > 0) {
				((LineDisplayControl114) devices.get(deviceName)).destroyWindow();
				windowsCreated--;
			}
			((LineDisplayControl114) devices.get(deviceName)).clearText();
		} catch (JposException e) {
			LOGGER.error("jpos error clearDisplay for device:{} and:{} ex:{}", deviceName, clearDisplay, e);
		}
	}

	/**
	 * opens the drawer.
	 *
	 * @param deviceName
	 *            the device name
	 * @param openDrawer
	 *            is ignored
	 */
	public void setOpenDrawer(String deviceName, Integer openDrawer) { // NOSONAR
		if (!initDone || !devices.containsKey(deviceName)) {
			return;
		}
		try {
			((CashDrawerControl114) devices.get(deviceName)).openDrawer();
		} catch (JposException e) {
			LOGGER.error("jpos error openDrawer for device:" + deviceName + " {}", e);
		}
	}

	/**
	 * prints to receipt printer in normal mode.
	 *
	 * @param deviceName
	 *            the device name
	 * @param printNormal
	 *            text to print
	 */
	public void setPrintNormal(String deviceName, String printNormal) {
		if (!initDone || !devices.containsKey(deviceName)) {
			return;
		}
		try {
			((POSPrinterControl114) devices.get(deviceName)).printNormal(POSPrinterConst.PTR_S_RECEIPT, printNormal);
		} catch (JposException e) {
			LOGGER.error("jpos error printNormal for device:" + deviceName + " {}", e);
		}
	}

	/**
	 * prints footer, feeds paper and cuts.
	 *
	 * @param deviceName
	 *            the device name
	 * @param footer
	 *            the text to print as footer
	 */
	public void setPrintCut(String deviceName, String footer) {
		if (!initDone || !devices.containsKey(deviceName)) {
			return;
		}
		try {
			if (!footer.isEmpty()) {
				((POSPrinterControl114) devices.get(deviceName)).printNormal(POSPrinterConst.PTR_S_RECEIPT, footer);
			}
			// Feed the receipt to the cutter position automatically,
			// and cut.
			((POSPrinterControl114) devices.get(deviceName)).printNormal(POSPrinterConst.PTR_S_RECEIPT,
					"\u001b|" + (((POSPrinterControl114) devices.get(deviceName)).getRecLinesToPaperCut()) + "lF");
			if (((POSPrinterControl114) devices.get(deviceName)).getCapRecPapercut())
				((POSPrinterControl114) devices.get(deviceName)).cutPaper(100);
		} catch (JposException e) {
			LOGGER.error("jpos error printCut for device:" + deviceName + " {}", e);
		}
	}

	/**
	 * print a pre-loaded bitmap.
	 *
	 * @param deviceName
	 *            the device name
	 * @param printBitmap
	 *            the bitmap-id to print
	 */
	public void setPrintBitmap(String deviceName, Integer printBitmap) {
		if (!initDone || !devices.containsKey(deviceName)) {
			return;
		}
		String text = String.format("\u001b|%dB", printBitmap);
		try {
			if (((POSPrinterControl114) devices.get(deviceName)).getCapRecBitmap()) {
				int[] pram2 = new int[1];
				pram2[0] = EpsonPOSPrinterConst.PTR_DI_BITMAP_PRINTING_MULTI_TONE;
				((POSPrinterControl114) devices.get(deviceName))
						.directIO(EpsonPOSPrinterConst.PTR_DI_SET_BITMAP_PRINTING_TYPE, pram2, "");
				((POSPrinterControl114) devices.get(deviceName)).printNormal(POSPrinterConst.PTR_S_RECEIPT, text);
				pram2[0] = EpsonPOSPrinterConst.PTR_DI_BITMAP_PRINTING_NORMAL;
				((POSPrinterControl114) devices.get(deviceName))
						.directIO(EpsonPOSPrinterConst.PTR_DI_SET_BITMAP_PRINTING_TYPE, pram2, "");
			}
		} catch (JposException e) {
			LOGGER.error("jpos error setPrintBitmap for device:" + deviceName + " and:" + printBitmap + " {}", e);
		}
	}

	/**
	 * show a pre-loaded bitmap.
	 *
	 * @param deviceName
	 *            the device name
	 * @param displayBitmap
	 *            the display bitmap
	 */
	public void setShowBitmap(String deviceName, Integer displayBitmap) { // NOSONAR
		if (!initDone || !devices.containsKey(deviceName)) {
			return;
		}
	}

	/**
	 * prints a barcode.
	 *
	 * @param deviceName
	 *            the device name
	 * @param data
	 *            the barcode with pipe encoded barcode-type from
	 *            jpos.POSPrinterConst
	 */
	public void setPrintBarcode(String deviceName, String data) {
		if (!initDone || !devices.containsKey(deviceName)) {
			return;
		}
		String[] parts = data.split("\\|");
		try {
			if (((POSPrinterControl114) devices.get(deviceName)).getCapRecBarCode()) {
				// 5mm spaces
				((POSPrinterControl114) devices.get(deviceName)).printNormal(POSPrinterConst.PTR_S_RECEIPT,
						"\u001b|500uF");
				((POSPrinterControl114) devices.get(deviceName)).printBarCode(POSPrinterConst.PTR_S_RECEIPT, parts[0],
						new Integer(parts[1].trim()), 1000,
						((POSPrinterControl114) devices.get(deviceName)).getRecLineWidth(),
						POSPrinterConst.PTR_BC_CENTER, POSPrinterConst.PTR_BC_TEXT_BELOW);
				// 2mm spaces
				((POSPrinterControl114) devices.get(deviceName)).printNormal(POSPrinterConst.PTR_S_RECEIPT,
						"\u001b|200uF");
			}
		} catch (JposException e) {
			LOGGER.error("jpos error setPrintBitmap for device:" + deviceName + " and:" + data + " {}", e);
		}
	}

	/**
	 * Sets the slip notifications enabled.
	 *
	 * @param slipNotificationsEnabled
	 *            the new slip notifications enabled
	 */
	public void setSlipNotificationsEnabled(boolean slipNotificationsEnabled) {
		this.slipNotificationsEnabled = slipNotificationsEnabled;
	}

	/**
	 * Checks if is slip notifications enabled.
	 *
	 * @return true, if is slip notifications enabled
	 */
	public boolean isSlipNotificationsEnabled() {
		return slipNotificationsEnabled;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see jpos.events.StatusUpdateListener#statusUpdateOccurred(jpos.events.
	 * StatusUpdateEvent)
	 */
	@Override
	public void statusUpdateOccurred(StatusUpdateEvent e) { // NOSONAR
		Object source = e.getSource();
		if (source instanceof CashDrawer) {
			switch (e.getStatus()) {
			case CashDrawerConst.CASH_SUE_DRAWERCLOSED: // Drawer is closed.
				if (statemachine != null) {
					statemachine.processEvent(statemachine, new MessageEvent(EventType.MESSAGECLOSE, "drawerOpen"));
					statemachine.processEvent(statemachine, new MessageEvent(EventType.TRIGGER, "onDrawerClosed"));
				}
				break;
			case CashDrawerConst.CASH_SUE_DRAWEROPEN: // Drawer is opened.
				if (statemachine != null) {
					statemachine.processEvent(statemachine, new MessageEvent(EventType.MESSAGEOPEN, "drawerOpen"));
					statemachine.processEvent(statemachine, new MessageEvent(EventType.TRIGGER, "onDrawerOpened"));
				}
				break;
			default:
				break;
			}
		}
		if (source instanceof POSPrinter) {
			switch (e.getStatus()) {
			case POSPrinterConst.PTR_SUE_COVER_OPEN:
				if (statemachine != null) {
					statemachine.processEvent(statemachine, new MessageEvent(EventType.MESSAGEOPEN, "coverOpen"));
				}
				break;
			case POSPrinterConst.PTR_SUE_COVER_OK:
				if (statemachine != null) {
					statemachine.processEvent(statemachine, new MessageEvent(EventType.MESSAGECLOSE, "coverOpen"));
				}
				break;
			case POSPrinterConst.PTR_SUE_REC_EMPTY:
				if (statemachine != null) {
					statemachine.processEvent(statemachine, new MessageEvent(EventType.MESSAGEOPEN, "receiptEmpty"));
				}
				break;
			case POSPrinterConst.PTR_SUE_REC_PAPEROK:
				if (statemachine != null) {
					statemachine.processEvent(statemachine, new MessageEvent(EventType.MESSAGECLOSE, "receiptEmpty"));
					statemachine.processEvent(statemachine,
							new MessageEvent(EventType.STATUSCLOSE, "receiptNearEmpty"));
				}
				break;
			case POSPrinterConst.PTR_SUE_REC_NEAREMPTY:
				if (statemachine != null) {
					statemachine.processEvent(statemachine, new MessageEvent(EventType.STATUSOPEN, "receiptNearEmpty"));
				}
				break;
			case POSPrinterConst.PTR_SUE_SLP_EMPTY:
				if (statemachine != null && slipNotificationsEnabled) {
					statemachine.processEvent(statemachine, new MessageEvent(EventType.MESSAGEOPEN, "slipEmpty"));
				}
				break;
			case POSPrinterConst.PTR_SUE_SLP_PAPEROK:
				if (statemachine != null && slipNotificationsEnabled) {
					statemachine.processEvent(statemachine, new MessageEvent(EventType.MESSAGECLOSE, "slipEmpty"));
					statemachine.processEvent(statemachine, new MessageEvent(EventType.STATUSCLOSE, "slipNearEmpty"));
				}
				break;
			case POSPrinterConst.PTR_SUE_SLP_NEAREMPTY:
				if (statemachine != null && slipNotificationsEnabled) {
					statemachine.processEvent(statemachine, new MessageEvent(EventType.STATUSOPEN, "slipNearEmpty"));
				}
				break;
			case POSPrinterConst.PTR_SUE_JRN_EMPTY:
				if (statemachine != null) {
					statemachine.processEvent(statemachine, new MessageEvent(EventType.MESSAGEOPEN, "journalEmpty"));
				}
				break;
			case POSPrinterConst.PTR_SUE_JRN_PAPEROK:
				if (statemachine != null) {
					statemachine.processEvent(statemachine, new MessageEvent(EventType.MESSAGECLOSE, "journalEmpty"));
					statemachine.processEvent(statemachine,
							new MessageEvent(EventType.STATUSCLOSE, "journalNearEmpty"));
				}
				break;
			case POSPrinterConst.PTR_SUE_JRN_NEAREMPTY:
				if (statemachine != null) {
					statemachine.processEvent(statemachine, new MessageEvent(EventType.STATUSOPEN, "journalNearEmpty"));
				}
				break;
			case POSPrinterConst.PTR_SUE_REC_CARTRIDGE_EMPTY:
				if (statemachine != null) {
					statemachine.processEvent(statemachine,
							new MessageEvent(EventType.MESSAGEOPEN, "receiptCartridgeEmpty"));
				}
				break;
			case POSPrinterConst.PTR_SUE_REC_CARTRIDGE_NEAREMPTY:
				if (statemachine != null) {
					statemachine.processEvent(statemachine,
							new MessageEvent(EventType.STATUSOPEN, "receiptCartridgeNearEmpty"));
				}
				break;
			case POSPrinterConst.PTR_SUE_REC_HEAD_CLEANING:
				if (statemachine != null) {
					statemachine.processEvent(statemachine,
							new MessageEvent(EventType.STATUSOPEN, "receiptHeadCleaning"));
				}
				break;
			case POSPrinterConst.PTR_SUE_REC_CARTDRIGE_OK:
				if (statemachine != null) {
					statemachine.processEvent(statemachine,
							new MessageEvent(EventType.MESSAGECLOSE, "receiptCartridgeEmpty"));
					statemachine.processEvent(statemachine,
							new MessageEvent(EventType.STATUSCLOSE, "receiptHeadCleaning"));
					statemachine.processEvent(statemachine,
							new MessageEvent(EventType.STATUSCLOSE, "receiptCartridgeNearEmpty"));
				}
				break;
			case POSPrinterConst.PTR_SUE_SLP_CARTRIDGE_EMPTY:
				if (statemachine != null) {
					statemachine.processEvent(statemachine,
							new MessageEvent(EventType.MESSAGEOPEN, "slipCartridgeEmpty"));
				}
				break;
			case POSPrinterConst.PTR_SUE_SLP_CARTRIDGE_NEAREMPTY:
				if (statemachine != null) {
					statemachine.processEvent(statemachine,
							new MessageEvent(EventType.STATUSOPEN, "slipCartridgeNearEmpty"));
				}
				break;
			case POSPrinterConst.PTR_SUE_SLP_HEAD_CLEANING:
				if (statemachine != null) {
					statemachine.processEvent(statemachine, new MessageEvent(EventType.STATUSOPEN, "slipHeadCleaning"));
				}
				break;
			case POSPrinterConst.PTR_SUE_SLP_CARTDRIGE_OK:
				if (statemachine != null) {
					statemachine.processEvent(statemachine,
							new MessageEvent(EventType.MESSAGECLOSE, "slipCartridgeEmpty"));
					statemachine.processEvent(statemachine,
							new MessageEvent(EventType.STATUSCLOSE, "slipHeadCleaning"));
					statemachine.processEvent(statemachine,
							new MessageEvent(EventType.STATUSCLOSE, "slipCartridgeNearEmpty"));
				}
				break;
			case POSPrinterConst.PTR_SUE_JRN_CARTRIDGE_EMPTY:
				if (statemachine != null) {
					statemachine.processEvent(statemachine,
							new MessageEvent(EventType.MESSAGEOPEN, "journalCartridgeEmpty"));
				}
				break;
			case POSPrinterConst.PTR_SUE_JRN_CARTRIDGE_NEAREMPTY:
				if (statemachine != null) {
					statemachine.processEvent(statemachine,
							new MessageEvent(EventType.STATUSOPEN, "journalCartridgeNearEmpty"));
				}
				break;
			case POSPrinterConst.PTR_SUE_JRN_HEAD_CLEANING:
				if (statemachine != null) {
					statemachine.processEvent(statemachine,
							new MessageEvent(EventType.STATUSOPEN, "journalHeadCleaning"));
				}
				break;
			case POSPrinterConst.PTR_SUE_JRN_CARTDRIGE_OK:
				if (statemachine != null) {
					statemachine.processEvent(statemachine,
							new MessageEvent(EventType.MESSAGECLOSE, "journalCartridgeEmpty"));
					statemachine.processEvent(statemachine,
							new MessageEvent(EventType.STATUSCLOSE, "journalHeadCleaning"));
					statemachine.processEvent(statemachine,
							new MessageEvent(EventType.STATUSCLOSE, "journalCartridgeNearEmpty"));
				}
				break;
			default:
				break;
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see jpos.events.ErrorListener#errorOccurred(jpos.events.ErrorEvent)
	 */
	@Override
	public void errorOccurred(ErrorEvent e) { // NOSONAR
		switch (e.getErrorCodeExtended()) {
		case POSPrinterConst.JPOS_EPTR_COVER_OPEN:
			if (statemachine != null) {
				statemachine.processEvent(statemachine, new MessageEvent(EventType.ERROR, "errorCoverOpen"));
			}
			break;
		case POSPrinterConst.JPOS_EPTR_JRN_EMPTY:
			if (statemachine != null) {
				statemachine.processEvent(statemachine, new MessageEvent(EventType.ERROR, "errorJournalEmpty"));
			}
			break;
		case POSPrinterConst.JPOS_EPTR_REC_EMPTY:
			if (statemachine != null) {
				statemachine.processEvent(statemachine, new MessageEvent(EventType.ERROR, "errorReceiptEmpty"));
			}
			break;
		case POSPrinterConst.JPOS_EPTR_SLP_EMPTY:
			if (statemachine != null) {
				statemachine.processEvent(statemachine, new MessageEvent(EventType.ERROR, "errorSlipEmpty"));
			}
			break;
		case POSPrinterConst.JPOS_EPTR_BADFORMAT:
			if (statemachine != null) {
				statemachine.processEvent(statemachine, new MessageEvent(EventType.ERROR, "errorBadFormat"));
			}
			break;
		case POSPrinterConst.JPOS_EPTR_JRN_CARTRIDGE_EMPTY:
			if (statemachine != null) {
				statemachine.processEvent(statemachine,
						new MessageEvent(EventType.ERROR, "errorJournalCartdridgeEmpty"));
			}
			break;
		case POSPrinterConst.JPOS_EPTR_REC_CARTRIDGE_EMPTY:
			if (statemachine != null) {
				statemachine.processEvent(statemachine,
						new MessageEvent(EventType.ERROR, "errorReceiptCartdridgeEmpty"));
			}
			break;
		case POSPrinterConst.JPOS_EPTR_SLP_CARTRIDGE_EMPTY:
			if (statemachine != null) {
				statemachine.processEvent(statemachine, new MessageEvent(EventType.ERROR, "errorSlipCartdridgeEmpty"));
			}
			break;
		case POSPrinterConst.JPOS_EPTR_JRN_CARTRIDGE_REMOVED:
			if (statemachine != null) {
				statemachine.processEvent(statemachine,
						new MessageEvent(EventType.ERROR, "errorJournalCartdridgeRemoved"));
			}
			break;
		case POSPrinterConst.JPOS_EPTR_REC_CARTRIDGE_REMOVED:
			if (statemachine != null) {
				statemachine.processEvent(statemachine,
						new MessageEvent(EventType.ERROR, "errorReceiptCartdridgeRemoved"));
			}
			break;
		case POSPrinterConst.JPOS_EPTR_SLP_CARTRIDGE_REMOVED:
			if (statemachine != null) {
				statemachine.processEvent(statemachine,
						new MessageEvent(EventType.ERROR, "errorSlipCartdridgeRemoved"));
			}
			break;
		case POSPrinterConst.JPOS_EPTR_JRN_HEAD_CLEANING:
			if (statemachine != null) {
				statemachine.processEvent(statemachine, new MessageEvent(EventType.ERROR, "errorJournalHeadCleaning"));
			}
			break;
		case POSPrinterConst.JPOS_EPTR_REC_HEAD_CLEANING:
			if (statemachine != null) {
				statemachine.processEvent(statemachine, new MessageEvent(EventType.ERROR, "errorReceiptHeadCleaning"));
			}
			break;
		case POSPrinterConst.JPOS_EPTR_SLP_HEAD_CLEANING:
			if (statemachine != null) {
				statemachine.processEvent(statemachine, new MessageEvent(EventType.ERROR, "errorSlipHeadCleaning"));
			}
			break;
		default:
			break;
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * jpos.events.OutputCompleteListener#outputCompleteOccurred(jpos.events.
	 * OutputCompleteEvent)
	 */
	@Override
	public void outputCompleteOccurred(OutputCompleteEvent e) {
		// nothing to do
	}

	/**
	 * Gets the ptip.
	 *
	 * @return the ptip
	 */
	public String getPTIP() {
		return ptIP;
	}

	/**
	 * Sets the ptip.
	 *
	 * @param ptIP
	 *            the new ptip
	 */
	public void setPTIP(String ptIP) {
		this.ptIP = ptIP;
	}

	/**
	 * Gets the PT port.
	 *
	 * @return the PT port
	 */
	public Integer getPTPort() {
		return ptPort;
	}

	/**
	 * Sets the PT port.
	 *
	 * @param ptPort
	 *            the new PT port
	 */
	public void setPTPort(Integer ptPort) {
		this.ptPort = ptPort;
	}

	/**
	 * Sets the payment terminal open.
	 *
	 * @param connectionParameters
	 *            the new payment terminal open
	 */
	public void setPaymentTerminalOpen(String connectionParameters) {
		String[] parts = connectionParameters.split("\\|");
		setPTIP(parts[0]);
		setPTPort(Integer.parseInt(parts[1]));

		if (initDone && POSServiceBinder.getPosService() != null
				&& !POSServiceBinder.getPosService().openZVTChannel(getPTIP(), getPTPort())) {
			LOGGER.error("could not open ZVT socket");
		}
	}

	/**
	 * Sets the close payment terminal.
	 *
	 * @param close
	 *            the new close payment terminal
	 */
	public void setClosePaymentTerminal(String close) { // NOSONAR
		if (initDone && POSServiceBinder.getPosService() != null) {
			POSServiceBinder.getPosService().closeZVTChannel();
		}
	}

	/**
	 * Sets the payment terminal acknowledge.
	 *
	 * @param dummey
	 *            the new payment terminal acknowledge
	 */
	public void setPaymentTerminalAcknowledge(String dummey) { // NOSONAR
		if (initDone && POSServiceBinder.getPosService() != null) {
			POSServiceBinder.getPosService().zvtAcknowledge();
		}
	}

	/**
	 * Sets the payment terminal balance request.
	 *
	 * @param request
	 *            the new payment terminal balance request
	 */
	public void setPaymentTerminalBalanceRequest(String request) { // NOSONAR
		if (initDone && POSServiceBinder.getPosService() != null) {
			// zvt.balanceRequest();
		}
	}

	/**
	 * Sets the payment terminal prepaid top up.
	 *
	 * @param amount
	 *            the new payment terminal prepaid top up
	 */
	public void setPaymentTerminalPrepaidTopUp(Double amount) { // NOSONAR
		if (initDone && POSServiceBinder.getPosService() != null) {
			// zvt.prepaidTopUp(amount);
		}
	}

	/**
	 * Sets the payment terminal reversal.
	 *
	 * @param reversal
	 *            the new payment terminal reversal
	 */
	public void setPaymentTerminalReversal(String reversal) {
		String[] parts = reversal.split("\\|");
		if (initDone && POSServiceBinder.getPosService() != null) {
			POSServiceBinder.getPosService().zvtReversal(parts[0], parts[1]);
		}
	}

	/**
	 * Sets the payment terminal registration.
	 *
	 * @param registration
	 *            the new payment terminal registration
	 */
	public void setPaymentTerminalRegistration(String registration) {
		String[] parts = registration.split("\\|");
		if (initDone && POSServiceBinder.getPosService() != null) {
			POSServiceBinder.getPosService().zvtRegistration(parts[0], parts[1]);
		}
	}

	/**
	 * Sets the payment terminal authorization.
	 *
	 * @param amount
	 *            the new payment terminal authorization
	 */
	public void setPaymentTerminalAuthorization(Double amount) {
		if (initDone && POSServiceBinder.getPosService() != null) {
			POSServiceBinder.getPosService().zvtAuthorization(amount);
		}
	}

	/**
	 * Gets the payment terminal response.
	 *
	 * @return the payment terminal response
	 */
	public String getPaymentTerminalResponse() {
		if (initDone && POSServiceBinder.getPosService() != null) {
			return POSServiceBinder.getPosService().getZvtResponse();
		}
		return null;
	}

	/**
	 * Gets the payment terminal transaction.
	 *
	 * @return the payment terminal transaction
	 */
	public IZVTTransactionData getPaymentTerminalTransaction() {
		if (initDone && POSServiceBinder.getPosService() != null) {
			return POSServiceBinder.getPosService().getZvtTransactionData();
		}
		return null;
	}

	/**
	 * Sets the prints the report.
	 *
	 * @param reportParameters
	 *            the new prints the report
	 */
	public void setPrintReport(String reportParameters) {
		if (statemachine.getReportProvider() != null) {
			String[] parts = reportParameters.split("\\|");
			String reportName = parts[0];
			Map<String, String> filterMap = new HashMap<>();
			// the filter is optional
			if (parts.length > 1) {
				String storageKey = parts[1];
				String filterName = null;
				String filterValue = null;
				for (String attribute : statemachine.getStorageAttributes(parts[1])) {
					if ("filterName".equals(attribute)) {
						filterName = (String) statemachine.getStorage(storageKey, attribute);
					}
					if ("filterValue".equals(attribute)) {
						filterValue = (String) statemachine.getStorage(storageKey, attribute);
					}
					if (filterName != null && filterValue != null) {
						// TODO: as soon as report supports cube datamarts, the
						// slicerSingleSelectDecorator must be added
						filterMap.put(filterName, filterValue);
						filterName = null;
						filterValue = null;
					}
				}
			}
			statemachine.getReportProvider().printReportAsPdf(reportName, statemachine.getUser(),
					statemachine.getDslMetadataService(), statemachine.getBlobService(), filterMap);
		}
	}
	
	public void setSignatureOpen(String dummy) {
		if(POSServiceBinder.getSignatureService() != null) {
			if(POSServiceBinder.getSignatureService().openTablet(statemachine.getBlobService())) {
				statemachine.schedule(statemachine, 500L, new MessageEvent(EventType.TRIGGER, "onSignaturePadOpen"));
			}
		}
	}

	public void setSignatureCapture(String dummy) {
		if(POSServiceBinder.getSignatureService() != null) {
			POSServiceBinder.getSignatureService().captureTablet();
			POSServiceBinder.getSignatureService().addListener(this);
		}
	}
	
	public void setSignatureIdle(String dummy) {
		if(POSServiceBinder.getSignatureService() != null) {
			POSServiceBinder.getSignatureService().removeListener(this);
			POSServiceBinder.getSignatureService().idleTablet();
		}
	}
	
	public void setSignatureCaptureImage(String imageId) {
		if(POSServiceBinder.getSignatureService() != null) {
			POSServiceBinder.getSignatureService().setCaptureImage(imageId); 
		}
	}
	
	public void setSignatureAddSlide(String slideId) {
		if(POSServiceBinder.getSignatureService() != null) {
			POSServiceBinder.getSignatureService().addSlideTablet(slideId); 
		}
	}
	
	public void setSignatureSlideDelay(int delay) {
		if(POSServiceBinder.getSignatureService() != null) {
			POSServiceBinder.getSignatureService().setSlideDelay(delay); 
		}
	}
	
	public void setSignatureClose(String dummy) {
		if(POSServiceBinder.getSignatureService() != null) {
			POSServiceBinder.getSignatureService().removeListener(this);
			POSServiceBinder.getSignatureService().closeTablet();
		}
	}

	public void setSignatureLabel(String labels) {
		if(POSServiceBinder.getSignatureService() != null) {
			POSServiceBinder.getSignatureService().setTabletLabel(labels);
		}
	}
	
	@Override
	public void notifyFinished(ISignatureEvent event) {
		if(event.getButtonId() == 1) {
			penData.clear();
			penData.addAll(event.getPenData());
			POSServiceBinder.getSignatureService().removeListener(this);
			statemachine.processEvent(statemachine, new MessageEvent(EventType.TRIGGER, "onSignatureOk"));
			POSServiceBinder.getSignatureService().idleTablet();
		}
		if(event.getButtonId() == 2) {
			if(POSServiceBinder.getSignatureService() != null) {
				POSServiceBinder.getSignatureService().clearTablet();
			}
		}
		if(event.getButtonId() == 3) {
			penData.clear();
			POSServiceBinder.getSignatureService().removeListener(this);
			statemachine.processEvent(statemachine, new MessageEvent(EventType.TRIGGER, "onSignatureCancel"));
			POSServiceBinder.getSignatureService().idleTablet();
		}
		
	}
	
	public List<PenData> getPenData() {
		return penData;
	}

	public String getSignatureBlob() {
		return POSServiceBinder.getSignatureService().getSignatureBlob(statemachine.getSceenWidth(), statemachine.getScreenHeight());
	}
}
