/*
 *                                                                            
 *  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.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.imageio.ImageIO;
import javax.swing.Timer;

import org.apache.commons.codec.binary.Base64;
import org.apache.http.ParseException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
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.IBeeper;
import org.eclipse.osbp.ui.api.statemachine.IPeripheral;
import org.eclipse.osbp.ui.api.statemachine.IStateMachine;
import org.eclipse.osbp.ui.api.themes.IThemeResourceService.ThemeResourceType;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.CollectionType;
import com.fasterxml.jackson.databind.type.SimpleType;
import com.vaadin.ui.Audio;
import com.vaadin.ui.Video;

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.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.services.POSPrinterService14;
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, ActionListener {
	private static final String HTTP = "http";

	private static final String APPLICATION_JSON = "application/json";

	private static final String ACCEPT = "Accept";

	private static final String DEVICE_NAME = "deviceName";

	private static final String CASH_DRAWER_CONST = "CashDrawerConst";

	private static final String POS_PRINTER_CONST = "POSPrinterConst";

	/** 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;
	/** The pen data supplied by signature pad. */
	
	private List<PenData> penData = new ArrayList<>();
	
	/** The beeper. */
	protected IBeeper beeper;
	
	/** The audio. */
	protected Audio audio;
	
	/** The video. */
	protected Video video;

	/** if javapos is installed remotely. */
	protected boolean isRemote = false;

	/** The remote host. */
	protected String remoteHost;
	
	/** The remote port. */
	protected int remotePort = 9090;
	
	/** The devices status poll. */
	private Timer statusPoll;

	/** The signature status poll. */
	private Timer signatureStatusPoll;
	
	/** The fields of CashDrawerConst. */
	Field[] cashDrawerFields = CashDrawerConst.class.getDeclaredFields();
	
	/** The pos printer fields. */
	Field[] posPrinterFields = POSPrinterConst.class.getDeclaredFields();
	
	private Map<Integer, String> printerBitmaps = new HashMap<>();

    private String esc = ((char)0x1b)+"";
	
	@Override
	public boolean equals(Object obj) {
		return super.equals(obj);
	}

	@Override
	public int hashCode() {
		return super.hashCode();
	}

	/*
	 * (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() {
		isRemote = statemachine.isJavaPosRemote();
		if(!isRemote) {
			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();
		} else {
			LOGGER.debug("Remote POS server active");
			initDone = true;
			remoteHost = statemachine.getHostName();
			remotePort = statemachine.getRemotePort();
			URIBuilder builder = new URIBuilder();
			builder.setScheme(HTTP).setHost(remoteHost).setPort(remotePort);
			if(statusPoll == null) {
				statusPoll = new Timer(1000, this);
				statusPoll.start();
			} else if(!statusPoll.isRunning()){
				statusPoll.restart();
			}
		}
	}

	private String doHttpGet(String path) {
		return doHttpGet(path, null, null, null, null);
	}
	
	private String doHttpGet(String path, String paraName1, String para1, String paraName2, String para2) {
		String responseString = null;
		URIBuilder builder = new URIBuilder();
		builder.setScheme(HTTP).setHost(remoteHost).setPort(remotePort);
		builder.setPath(path);
		builder.clearParameters();
		if(paraName1 != null && para1 != null) {
			builder.addParameter(paraName1, para1);
		}
		if(paraName2 != null && para2 != null) {
			builder.addParameter(paraName2, para2);
		}
		try {
			HttpGet get = new HttpGet(builder.build());
			get.addHeader(ACCEPT, APPLICATION_JSON);
			CloseableHttpClient httpClient = HttpClientBuilder.create().build();
			CloseableHttpResponse response = httpClient.execute(get);
			responseString = EntityUtils.toString(response.getEntity());
			get.releaseConnection();
		} catch (URISyntaxException | ParseException | IOException e) {
			LOGGER.error("{}", e);
		}
		return responseString;
	}

	private void doHttpPut(String path, String paraName1, String para1) {
		doHttpPut(path, paraName1, para1, null, null);
	}
	
	private void doHttpPut(String path, String paraName1, String para1, String paraName2, String para2) {
		URIBuilder builder = new URIBuilder(); 
		builder.setScheme(HTTP).setHost(remoteHost).setPort(remotePort);
		builder.setPath(path);
		builder.clearParameters();
		if(paraName1 != null && para1 != null) {
			builder.addParameter(paraName1, para1);
		}
		if(paraName2 != null && para2 != null) {
			builder.addParameter(paraName2, para2);
		}
		try {
			HttpPut put = new HttpPut(builder.build());
			put.addHeader(ACCEPT, APPLICATION_JSON);
			CloseableHttpClient httpClient = HttpClientBuilder.create().build();
			httpClient.execute(put);
			put.releaseConnection();
		} catch (URISyntaxException | ParseException | IOException e) {
			LOGGER.error("{}", e);
		}
	}

	private void doHttpPost(String path) {
		doHttpPost(path, null, null);
	}
	
	private void doHttpPost(String path, String paraName, String para) {
		doHttpPost(path, paraName, para, null);
	}
	
	private void doHttpPost(String path, String paraName, String para, byte[] image) {
		URIBuilder builder = new URIBuilder();
		builder.setScheme(HTTP).setHost(remoteHost).setPort(remotePort);
		builder.setPath(path);
		try {
			HttpPost post = new HttpPost(builder.build());
			post.addHeader(ACCEPT, APPLICATION_JSON);
			if(paraName != null && para != null || image != null) {
				MultipartEntityBuilder mpeBuilder = MultipartEntityBuilder.create();
				mpeBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
				if(paraName != null && para != null) {
					mpeBuilder.addTextBody(paraName, para);
				}
				if(image != null) {
					mpeBuilder.addBinaryBody("image", image, ContentType.MULTIPART_FORM_DATA, "");
				}
				post.setEntity(mpeBuilder.build());
			}
			CloseableHttpClient httpClient = HttpClientBuilder.create().build();
			httpClient.execute(post);
			post.releaseConnection();
		} catch (URISyntaxException | ParseException | IOException e) {
			LOGGER.error("{}", e);
		}
	}
	
	public void releaseDevices() {
		if(statusPoll != null && statusPoll.isRunning()) {
			statusPoll.stop();
		}
		if(signatureStatusPoll != null && signatureStatusPoll.isRunning()) {
			signatureStatusPoll.stop();
		}
	}
	/*
	 * (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(isRemote) {
			doHttpPut("/devices/displayLine", DEVICE_NAME, deviceName, "displayLine", displayLine);
			return;
			
		} else 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 to all printers.
	 *
	 * @param registerBitmap
	 *            encodes a pipe separated tuple bitmapNumber, bitmapFilename
	 */
	public void setPrinterBitmap(String registerId, String registerBitmapId) {
		int imgWidth = 200;
		int imgHeight = 80;
		if(isRemote) {
			doHttpPut("/devices/uploadedBitmaps", "uploadedBitmaps", Boolean.toString(ProductConfiguration.hasJavaPosUploadedBitmaps()));
			byte[] img = statemachine.getBlobService().getByteArrayImage(registerBitmapId, 0);
			doHttpPost("/devices/printerBitmap", "registerId", registerId, img);
			return;
		} else if (!initDone) {
			return;
		}
    	// load the image
		BufferedImage img = statemachine.getBlobService().getBufferedImage(registerBitmapId, 0);
		// convert it to black/white
        BufferedImage blackWhite = new BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_BYTE_BINARY);
        Graphics2D g2d = blackWhite.createGraphics();
        g2d.drawImage(img, 0, 0, imgWidth, imgHeight, 0, 0, img.getWidth(), img.getHeight(), null);
        g2d.dispose();
		
        // write file in temp dir
		File tempFile = null;
		try {
			tempFile = File.createTempFile("printerBitmap", ".bmp");
			ImageIO.write(blackWhite, "BMP", tempFile);
		} catch (IOException ioex) {
			LOGGER.error("{}", ioex);
			return;
		}
		
		for(BaseControl device:devices.values()) {
			String deviceName = ""; 
			try {
				int bitmapIndex = Integer.parseInt(registerId);
				String path = tempFile.getPath();
				deviceName = device.getPhysicalDeviceName();
				if(device instanceof POSPrinter && ((POSPrinterControl114) device).getCapRecBitmap()) {
					if(ProductConfiguration.hasJavaPosUploadedBitmaps()) {
						((POSPrinterControl114) device).setBitmap(bitmapIndex,POSPrinterConst.PTR_S_RECEIPT, path, (((POSPrinterControl114) device).getRecLineWidth()/2), POSPrinterConst.PTR_BM_CENTER);
					} else {
						printerBitmaps.put(bitmapIndex, path);
					}
				}
			} catch (JposException jex) {
				LOGGER.error("jpos error setRegisterBitmap for device:{} and:{} ex:{}", deviceName, registerBitmapId, jex);
			} catch (Exception ex) {
				LOGGER.error("general error registerBitmap for device:{} text:{} ex:{}", deviceName, registerBitmapId,ex);
			}
		}
	}

	/**
	 * Sets the device brightness.
	 *
	 * @param deviceName
	 *            the device name
	 * @param deviceBrightness
	 *            the new device brightness
	 */
	public void setDeviceBrightness(String deviceName, Integer deviceBrightness) {
		if(isRemote) {
			doHttpPut("/devices/deviceBrightness", DEVICE_NAME, deviceName, "deviceBrightness", deviceBrightness.toString());
			return;
			
		} else 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(isRemote) {
			doHttpPut("/devices/blinkRate", DEVICE_NAME, deviceName, "blinkRate", blinkRate.toString());
			return;
			
		} else 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(isRemote) {
			doHttpPut("/devices/cursorType", DEVICE_NAME, deviceName, "cursorType", cursorType.toString());
			return;
			
		} else 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(isRemote) {
			doHttpPut("/devices/marqueeFormat", DEVICE_NAME, deviceName, "marqueeFormat", marqueeFormat.toString());
			return;
			
		} else 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(isRemote) {
			doHttpPut("/devices/marqueeRepeatWait", DEVICE_NAME, deviceName, "marqueeRepeatWait", marqueeRepeatWait.toString());
			return;
			
		} else 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(isRemote) {
			doHttpPut("/devices/marqueeType", DEVICE_NAME, deviceName, "marqueeType", marqueeType.toString());
			return;
			
		} else 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(isRemote) {
			doHttpPut("/devices/marqueeUnitWait", DEVICE_NAME, deviceName, "marqueeUnitWait", marqueeUnitWait.toString());
			return;
			
		} else 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(isRemote) {
			doHttpPut("/devices/createWindow", DEVICE_NAME, deviceName, "createWindow", createWindow);
			return;
			
		} else 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(isRemote) {
			doHttpPut("/devices/destroyWindow", DEVICE_NAME, deviceName, "destroyWindow", destroyWindow);
			return;
			
		} else 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(isRemote) {
			doHttpPut("/devices/scroll", DEVICE_NAME, deviceName, "scroll", scroll);
			return;
			
		} else 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(isRemote) {
			doHttpPut("/devices/interCharacterWait", DEVICE_NAME, deviceName, "interCharacterWait", interCharacterWait.toString());
			return;
			
		} else 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(isRemote) {
			doHttpPut("/devices/displayTextAt", DEVICE_NAME, deviceName, "displayTextAt", displayTextAt);
			return;
			
		} else 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(isRemote) {
			doHttpPut("/devices/clearDisplay", DEVICE_NAME, deviceName, "clearDisplay", clearDisplay);
			return;
			
		} else 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(isRemote) {
			doHttpPut("/devices/openDrawer", DEVICE_NAME, deviceName, "openDrawer", openDrawer.toString());
			return;
			
		} else 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(isRemote) {
			doHttpPut("/devices/printNormal", DEVICE_NAME, deviceName, "printNormal", printNormal);
			return;
			
		} else 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(isRemote) {
			doHttpPut("/devices/printCut", DEVICE_NAME, deviceName, "printCut", footer);
			return;
			
		} else if (!initDone || !devices.containsKey(deviceName)) {
			return;
		}
		try {
			if (!footer.isEmpty()) {
				((POSPrinterControl114) devices.get(deviceName)).printNormal(POSPrinterConst.PTR_S_RECEIPT, footer);
			}
			if (((POSPrinterControl114) devices.get(deviceName)).getCapRecPapercut()) {
				int linesToPaperCut = ((POSPrinterControl114) devices.get(deviceName)).getRecLinesToPaperCut();
				((POSPrinterControl114) devices.get(deviceName)).printNormal(POSPrinterConst.PTR_S_RECEIPT, esc + "d" + ((char)(linesToPaperCut+1)));
				((POSPrinterControl114) devices.get(deviceName)).printNormal(POSPrinterConst.PTR_S_RECEIPT, esc + "i");
			}
		} 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(isRemote) {
			doHttpPut("/devices/printBitmap", DEVICE_NAME, deviceName, "printBitmap", printBitmap.toString());
			return;
			
		} else if (!initDone || !devices.containsKey(deviceName)) {
			return;
		}
		try {
			if (((POSPrinterControl114) devices.get(deviceName)).getCapRecBitmap() && printerBitmaps.containsKey(printBitmap)) {
				if(ProductConfiguration.hasJavaPosUploadedBitmaps()) {
					((POSPrinterControl114) devices.get(deviceName)).printNormal(POSPrinterConst.PTR_S_RECEIPT, esc+"|"+printBitmap.toString()+"B");
				} else {
					((POSPrinterControl114) devices.get(deviceName)).printBitmap(POSPrinterConst.PTR_S_RECEIPT, printerBitmaps.get(printBitmap), POSPrinterConst.PTR_BM_ASIS, POSPrinterConst.PTR_BM_CENTER);
				}
			}
		} catch (JposException e) {
			LOGGER.error("jpos error setPrintBitmap for device:" + deviceName + " and:" + printBitmap + " {}", e);
		}
	}

	/**
	 * 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(isRemote) {
			doHttpPut("/devices/printBarcode", DEVICE_NAME, deviceName, "printBarcode", data);
			return;
			
		} else if (!initDone || !devices.containsKey(deviceName)) {
			return;
		}
		String[] parts = data.split("\\|");
		try {
			String value = parts[0];
			int code = Integer.parseInt(parts[1].trim());
			int height = 0;
			if(parts.length > 2) {
				height = Integer.parseInt(parts[2].trim());
			}
			if (((POSPrinterControl114) devices.get(deviceName)).getCapRecBarCode()) {
				((POSPrinterControl114) devices.get(deviceName)).printBarCode(POSPrinterConst.PTR_S_RECEIPT, value,
						code, height, ((POSPrinterControl114) devices.get(deviceName)).getRecLineWidth(), POSPrinterConst.PTR_BC_CENTER, POSPrinterConst.PTR_BC_TEXT_BELOW);
			}
		} catch (JposException e) {
			LOGGER.error("jpos error setPrintBarcode for device:" + deviceName + " and:" + data + " {}", e);
		}
	}

	/**
	 * Sets the slip notifications enabled.
	 *
	 * @param slipNotificationsEnabled
	 *            the new slip notifications enabled
	 */
	public void setSlipNotificationsEnabled(boolean slipNotificationsEnabled) {
		if(isRemote) {
			doHttpPut("/devices/slipNotificationsEnabled", "slipNotificationsEnabled", Boolean.toString(slipNotificationsEnabled));
		} else {
			this.slipNotificationsEnabled = slipNotificationsEnabled;
		}
	}

	/**
	 * Checks if is slip notifications enabled.
	 *
	 * @return true, if is slip notifications enabled
	 */
	public boolean isSlipNotificationsEnabled() {
		if(isRemote) {
			return Boolean.getBoolean(doHttpGet("/devices/isSlipNotificationsEnabled"));
		} else {
			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 POSPrinterService14) {
			try {
				String serviceDescription = ((POSPrinterService14)source).getPhysicalDeviceDescription();
				if(serviceDescription.contains("Cash Drawer")) {
					decodeCashDrawerStatus(e.getStatus());
				} else {
					decodePOSPrinterStatus(e.getStatus());
				}
			} catch (JposException e1) {
				// NOSONAR
			}
		}
		if (source instanceof CashDrawer) {
			decodeCashDrawerStatus(e.getStatus());
		}
		if (source instanceof POSPrinter) {
			decodePOSPrinterStatus(e.getStatus());
		}
	}

	private void decodePOSPrinterStatus(int status) {
		if (statemachine != null) {
			switch (status) {
			case POSPrinterConst.PTR_SUE_COVER_OPEN:
				statemachine.processEvent(statemachine, new MessageEvent(EventType.MESSAGEOPEN, "coverOpen"));
				break;
			case POSPrinterConst.PTR_SUE_COVER_OK:
				statemachine.processEvent(statemachine, new MessageEvent(EventType.MESSAGECLOSE, "coverOpen"));
				break;
			case POSPrinterConst.PTR_SUE_REC_EMPTY:
				statemachine.processEvent(statemachine, new MessageEvent(EventType.MESSAGEOPEN, "receiptEmpty"));
				break;
			case POSPrinterConst.PTR_SUE_REC_PAPEROK:
				statemachine.processEvent(statemachine, new MessageEvent(EventType.MESSAGECLOSE, "receiptEmpty"));
				statemachine.processEvent(statemachine,
						new MessageEvent(EventType.STATUSCLOSE, "receiptNearEmpty"));
				break;
			case POSPrinterConst.PTR_SUE_REC_NEAREMPTY:
				statemachine.processEvent(statemachine, new MessageEvent(EventType.STATUSOPEN, "receiptNearEmpty"));
				break;
			case POSPrinterConst.PTR_SUE_SLP_EMPTY:
				if (slipNotificationsEnabled) {
					statemachine.processEvent(statemachine, new MessageEvent(EventType.MESSAGEOPEN, "slipEmpty"));
				}
				break;
			case POSPrinterConst.PTR_SUE_SLP_PAPEROK:
				if (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 (slipNotificationsEnabled) {
					statemachine.processEvent(statemachine, new MessageEvent(EventType.STATUSOPEN, "slipNearEmpty"));
				}
				break;
			case POSPrinterConst.PTR_SUE_JRN_EMPTY:
				statemachine.processEvent(statemachine, new MessageEvent(EventType.MESSAGEOPEN, "journalEmpty"));
				break;
			case POSPrinterConst.PTR_SUE_JRN_PAPEROK:
				statemachine.processEvent(statemachine, new MessageEvent(EventType.MESSAGECLOSE, "journalEmpty"));
				statemachine.processEvent(statemachine,
						new MessageEvent(EventType.STATUSCLOSE, "journalNearEmpty"));
				break;
			case POSPrinterConst.PTR_SUE_JRN_NEAREMPTY:
				statemachine.processEvent(statemachine, new MessageEvent(EventType.STATUSOPEN, "journalNearEmpty"));
				break;
			case POSPrinterConst.PTR_SUE_REC_CARTRIDGE_EMPTY:
				statemachine.processEvent(statemachine,
						new MessageEvent(EventType.MESSAGEOPEN, "receiptCartridgeEmpty"));
				break;
			case POSPrinterConst.PTR_SUE_REC_CARTRIDGE_NEAREMPTY:
				statemachine.processEvent(statemachine,
						new MessageEvent(EventType.STATUSOPEN, "receiptCartridgeNearEmpty"));
				break;
			case POSPrinterConst.PTR_SUE_REC_HEAD_CLEANING:
				statemachine.processEvent(statemachine,
						new MessageEvent(EventType.STATUSOPEN, "receiptHeadCleaning"));
				break;
			case POSPrinterConst.PTR_SUE_REC_CARTDRIGE_OK:
				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:
				statemachine.processEvent(statemachine,
						new MessageEvent(EventType.MESSAGEOPEN, "slipCartridgeEmpty"));
				break;
			case POSPrinterConst.PTR_SUE_SLP_CARTRIDGE_NEAREMPTY:
				statemachine.processEvent(statemachine,
						new MessageEvent(EventType.STATUSOPEN, "slipCartridgeNearEmpty"));
				break;
			case POSPrinterConst.PTR_SUE_SLP_HEAD_CLEANING:
				statemachine.processEvent(statemachine, new MessageEvent(EventType.STATUSOPEN, "slipHeadCleaning"));
				break;
			case POSPrinterConst.PTR_SUE_SLP_CARTDRIGE_OK:
				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:
				statemachine.processEvent(statemachine,
						new MessageEvent(EventType.MESSAGEOPEN, "journalCartridgeEmpty"));
				break;
			case POSPrinterConst.PTR_SUE_JRN_CARTRIDGE_NEAREMPTY:
				statemachine.processEvent(statemachine,
						new MessageEvent(EventType.STATUSOPEN, "journalCartridgeNearEmpty"));
				break;
			case POSPrinterConst.PTR_SUE_JRN_HEAD_CLEANING:
				statemachine.processEvent(statemachine,
						new MessageEvent(EventType.STATUSOPEN, "journalHeadCleaning"));
				break;
			case POSPrinterConst.PTR_SUE_JRN_CARTDRIGE_OK:
				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;
			}
		}
	}

	private void decodeCashDrawerStatus(int status) {
		switch (status) {
		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;
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see jpos.events.ErrorListener#errorOccurred(jpos.events.ErrorEvent)
	 */
	@Override
	public void errorOccurred(jpos.events.ErrorEvent e) { // NOSONAR
		decodePOSPrinterErrorField(e.getErrorCodeExtended());
	}

	private void decodePOSPrinterErrorField(int error) {
		if (statemachine != null) {
			switch (error) {
			case POSPrinterConst.JPOS_EPTR_COVER_OPEN:
				statemachine.processEvent(statemachine, new MessageEvent(EventType.ERROR, "errorCoverOpen"));
				break;
			case POSPrinterConst.JPOS_EPTR_JRN_EMPTY:
				statemachine.processEvent(statemachine, new MessageEvent(EventType.ERROR, "errorJournalEmpty"));
				break;
			case POSPrinterConst.JPOS_EPTR_REC_EMPTY:
				statemachine.processEvent(statemachine, new MessageEvent(EventType.ERROR, "errorReceiptEmpty"));
				break;
			case POSPrinterConst.JPOS_EPTR_SLP_EMPTY:
				statemachine.processEvent(statemachine, new MessageEvent(EventType.ERROR, "errorSlipEmpty"));
				break;
			case POSPrinterConst.JPOS_EPTR_BADFORMAT:
				statemachine.processEvent(statemachine, new MessageEvent(EventType.ERROR, "errorBadFormat"));
				break;
			case POSPrinterConst.JPOS_EPTR_JRN_CARTRIDGE_EMPTY:
				statemachine.processEvent(statemachine,
						new MessageEvent(EventType.ERROR, "errorJournalCartdridgeEmpty"));
				break;
			case POSPrinterConst.JPOS_EPTR_REC_CARTRIDGE_EMPTY:
				statemachine.processEvent(statemachine,
						new MessageEvent(EventType.ERROR, "errorReceiptCartdridgeEmpty"));
				break;
			case POSPrinterConst.JPOS_EPTR_SLP_CARTRIDGE_EMPTY:
				statemachine.processEvent(statemachine, new MessageEvent(EventType.ERROR, "errorSlipCartdridgeEmpty"));
				break;
			case POSPrinterConst.JPOS_EPTR_JRN_CARTRIDGE_REMOVED:
				statemachine.processEvent(statemachine,
						new MessageEvent(EventType.ERROR, "errorJournalCartdridgeRemoved"));
				break;
			case POSPrinterConst.JPOS_EPTR_REC_CARTRIDGE_REMOVED:
				statemachine.processEvent(statemachine,
						new MessageEvent(EventType.ERROR, "errorReceiptCartdridgeRemoved"));
				break;
			case POSPrinterConst.JPOS_EPTR_SLP_CARTRIDGE_REMOVED:
				statemachine.processEvent(statemachine,
						new MessageEvent(EventType.ERROR, "errorSlipCartdridgeRemoved"));
				break;
			case POSPrinterConst.JPOS_EPTR_JRN_HEAD_CLEANING:
				statemachine.processEvent(statemachine, new MessageEvent(EventType.ERROR, "errorJournalHeadCleaning"));
				break;
			case POSPrinterConst.JPOS_EPTR_REC_HEAD_CLEANING:
				statemachine.processEvent(statemachine, new MessageEvent(EventType.ERROR, "errorReceiptHeadCleaning"));
				break;
			case POSPrinterConst.JPOS_EPTR_SLP_HEAD_CLEANING:
				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 (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 (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 (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 (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 (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 (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 (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 (POSServiceBinder.getPosService() != null) {
			POSServiceBinder.getPosService().zvtAuthorization(amount);
		}
	}

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

	/**
	 * Gets the payment terminal transaction.
	 *
	 * @return the payment terminal transaction
	 */
	public IZVTTransactionData getPaymentTerminalTransaction() {
		if (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, String printService) {
		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);
				} else if ("filterValue".equals(attribute)) {
					filterValue = (String) statemachine.getStorage(storageKey, attribute);
				}
				if (filterName != null && filterValue != null) {
					filterMap.put(filterName, filterValue);
					filterName = null;
					filterValue = null;
				}
			}
		}
		if (statemachine.getReportProvider() != null) {
			statemachine.getReportProvider().printReportAsPdf(reportName, statemachine.getEclipseContext(), filterMap, printService);
		}
	}
	
	public void setSignatureOpen(String dummy) {	// NOSONAR
		if(isRemote) {
			doHttpPost("/signature/openTablet");
			if(signatureStatusPoll == null) {
				signatureStatusPoll = new Timer(1000, this);
				signatureStatusPoll.start();
			} else if(!statusPoll.isRunning()){
				signatureStatusPoll.restart();
			}
		} else if(POSServiceBinder.getSignatureService() != null && POSServiceBinder.getSignatureService().openTablet(statemachine.getBlobService())) {
			statemachine.schedule(statemachine, 500, new MessageEvent(EventType.TRIGGER, "onSignaturePadOpen"));
		}
	}

	public void setSignatureCapture(String dummy) {	// NOSONAR
		if(isRemote) {
			doHttpPost("/signature/captureTablet");
		} else if(POSServiceBinder.getSignatureService() != null) {
			POSServiceBinder.getSignatureService().captureTablet();
			POSServiceBinder.getSignatureService().addListener(this);
		}
	}
	
	public void setSignatureIdle(String dummy) {	// NOSONAR
		if(isRemote) {
			doHttpPost("/signature/idleTablet");
		} else if(POSServiceBinder.getSignatureService() != null) {			
			POSServiceBinder.getSignatureService().removeListener(this);
			POSServiceBinder.getSignatureService().idleTablet();
		}
	}
	
	public void setSignatureCaptureImage(String imageId) {
		if(isRemote) {
			byte[] img = statemachine.getBlobService().getByteArrayImage(imageId, 0);
			doHttpPost("/signature/captureImage", null, null, img);
		} else if(POSServiceBinder.getSignatureService() != null) {			
			POSServiceBinder.getSignatureService().setCaptureImage(imageId); 
		}
	}
	
	public void setSignatureAddSlide(String slideId) {
		if(isRemote) {
			byte[] img = statemachine.getBlobService().getByteArrayImage(slideId, 0);
			doHttpPost("/signature/addSlide", null, null, img);
		} else if(POSServiceBinder.getSignatureService() != null) {			
			POSServiceBinder.getSignatureService().addSlideTablet(slideId); 
		}
	}
	
	public void setSignatureSlideDelay(Integer delay) {
		if(isRemote) {
			doHttpPut("/signature/slideDelay", "delay", delay.toString());
		} else if(POSServiceBinder.getSignatureService() != null) {			
			POSServiceBinder.getSignatureService().setSlideDelay(delay); 
		}
	}
	
	public void setSignatureClose(String dummy) {	// NOSONAR
		if(isRemote) {
			doHttpPost("closeTablet");
			if(signatureStatusPoll != null && signatureStatusPoll.isRunning()) {
				signatureStatusPoll.stop();
			}
		} else if(POSServiceBinder.getSignatureService() != null) {
			POSServiceBinder.getSignatureService().removeListener(this);
			POSServiceBinder.getSignatureService().closeTablet();
		}
	}

	public void setSignatureLabel(String labels) {
		if(isRemote) {
			doHttpPut("/signature/addLabels", "labels", labels);
		} else 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 && 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() {
		if(isRemote) {
			String jsonString =  doHttpGet("/signature/penData");
			ObjectMapper mapper = new ObjectMapper();
			try {
				penData = mapper.readValue(jsonString, CollectionType.construct(List.class, SimpleType.construct(PenData.class)));
			} catch (IOException e) {
				LOGGER.error("{}", e);
			}
		}
		return penData;
	}

	public String getSignatureBlob() {
		if(isRemote) {
			String base64String =  doHttpGet("/signature/signature", "width", Integer.toString(statemachine.getSceenWidth()), "height", Integer.toString(statemachine.getScreenHeight()));
			if(base64String != null) {
				byte[] bytes = Base64.decodeBase64(base64String.getBytes());
				return statemachine.getBlobService().createBlobMapping(new ByteArrayInputStream(bytes), "", "image/jpeg");
			}
		} else if(POSServiceBinder.getSignatureService() != null) {
			return POSServiceBinder.getSignatureService().getSignatureBlob(statemachine.getSceenWidth(), statemachine.getScreenHeight());
		}
		return null;
	}

    public void setBeeper(String parameters) {
    	Integer duration;
    	Integer frequency;
		String[] parts = parameters.split("\\|");
		duration = Integer.parseInt(parts[0]);
		frequency = Integer.parseInt(parts[1]);
		beeper.beep(duration, frequency);
    }

    public void setPlayer(String name) {
    	video.setSources(statemachine.getThemeResourceService().getThemeResource(name, ThemeResourceType.VIDEO));
		video.play();
    }

    public void setSound(String name) { 
    	audio.setSources(statemachine.getThemeResourceService().getThemeResource(name, ThemeResourceType.SOUND));
    	audio.play();
    }

	@Override
	public void actionPerformed(ActionEvent e) {
		if(e.getSource().equals(statusPoll)) {
			decodeRemoteState(doHttpGet("/devices/states"));
			decodeRemoteError(doHttpGet("/devices/errors"));
		}
		if(e.getSource().equals(signatureStatusPoll)) {
			decodeRemoteSignatureState(doHttpGet("/signature/states"));
		}
	}

	private void decodeRemoteError(String responseString) {
		if(responseString != null) {
			List<String> errors = Arrays.asList(responseString.replace("[","").replace("]", "").replace("\"", "").split(","));
			for(String error:errors) {
				if(error.startsWith(POS_PRINTER_CONST)) {
					decodeRemoteErrorState(error);
				}
			}
		}
	}

	private void decodeRemoteErrorState(String error) {
		for ( Field field : posPrinterFields ) {
			if(field.getName().equals(error.substring(POS_PRINTER_CONST.length()+1))) {
				field.setAccessible(true);
				try {
					decodePOSPrinterErrorField((int)field.get(error));
				} catch (IllegalArgumentException | IllegalAccessException e1) {
					LOGGER.error("{}", e1);
				}
				break;
			}
		}
	}

	private void decodeRemoteState(String responseString) {
		if(responseString != null) {
			List<String> states = Arrays
					.asList(responseString.replace("[", "").replace("]", "").replace("\"", "").split(","));
			for (String state : states) {
				if (state.startsWith(CASH_DRAWER_CONST)) {
					decodeCashDrawerStatusField(state);
				} else if (state.startsWith(POS_PRINTER_CONST)) {
					decodePOSPrinterStatusField(state);
				}
			}
		}
	}

	private void decodePOSPrinterStatusField(String state) {
		for (Field field : posPrinterFields) {
			if (field.getName().equals(state.substring(POS_PRINTER_CONST.length() + 1))) {
				field.setAccessible(true);
				try {
					decodePOSPrinterStatus((int) field.get(state));
				} catch (IllegalArgumentException | IllegalAccessException e1) {
					LOGGER.error("{}", e1);
				}
				break;
			}
		}
	}

	private void decodeCashDrawerStatusField(String state) {
		for (Field field : cashDrawerFields) {
			field.setAccessible(true);
			if (field.getName().equals(state.substring(CASH_DRAWER_CONST.length() + 1))) {
				field.setAccessible(true);
				try {
					decodeCashDrawerStatus((int) field.get(state));
				} catch (IllegalArgumentException | IllegalAccessException e1) {
					LOGGER.error("{}", e1);
				}
				break;
			}
		}
	}

	private void decodeRemoteSignatureState(String responseString) {
		if(responseString != null) {
			List<String> states = Arrays.asList(responseString.replace("[","").replace("]", "").replace("\"", "").split(","));
			for(String state:states) {
				if(!state.isEmpty()) {
					statemachine.schedule(statemachine, 500, new MessageEvent(EventType.TRIGGER, state));
				}
			}
		}
	}
}
