/*
 *                                                                            
 *  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.lang.reflect.InvocationTargetException;
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.LinkedHashMap;
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.Scale;
import jpos.config.JposEntryRegistry;
import jpos.config.simple.SimpleEntry;
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;

	/** */
	private boolean paymentTerminalIsOpen = false;
	private boolean signaturePadIsOpen = false;
	private boolean printerBitmapIsSet[] = { false, false, false, false, false };

	/** 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);
		}
	}

	private boolean isJavaPosRemote() {
		if( !"null".equals(remoteHost) && remotePort > 0 ) {
			String cmd = String.format("http://%s:%d/devices/posParameters", remoteHost, remotePort);
			HttpGet get = new HttpGet(cmd);
			get.addHeader("Accept", "application/json");
			
			try(CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
				CloseableHttpResponse response = httpClient.execute(get);
				LOGGER.info(EntityUtils.toString(response.getEntity()));
				if(response.getEntity().getContentLength()==0) {
					return false;
				}
				return true;
			} catch (ParseException | IOException e) {
				// it's ok - we have no remote javapos
			} finally {
				get.releaseConnection();
			}
		}
		return false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see foodmartdialogdslplugin.AbstractStateMachineParticipant#init()
	 */
	@Override
	public void init(String pRemoteHost, int pRemotePort) {
		
		if( pRemoteHost == null )
			remoteHost = "null";
		else
			remoteHost = pRemoteHost;
		
		remotePort = pRemotePort;
		
		isRemote = 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.info("POS setupfile is not registered in product preferences");
				return;
			}
			LOGGER.info("POS setupfile to be used: {}", configFile);
			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);
	}

	private String doHttpGet(String path, Map<String, String> params) {
		String responseString = null;
		URIBuilder builder = new URIBuilder();
		builder.setScheme(HTTP).setHost(remoteHost).setPort(remotePort);
		builder.setPath(path);
		builder.clearParameters();
		if (params != null) {
			for (String paramKey : params.keySet()) {
				builder.addParameter(paramKey, params.get(paramKey));
			}
		}
		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("doHttpGet exception: {}", 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("doHttpPut exception: {}", 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("doHttpPost exception {}", e);
		}
	}
	
	public void initDevice(String deviceName ) {
		if (isRemote) {
			
			HttpPut put = new HttpPut(String.format("http://%s:%d/devices/claim?deviceName=%s", remoteHost, remotePort, deviceName));
	    	put.addHeader("Accept", "application/json");
	    	try(CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
	    		CloseableHttpResponse response = httpClient.execute(put);
	    		LOGGER.info(EntityUtils.toString(response.getEntity()));
	    	} catch (IOException e) {
	    		LOGGER.error("Unable to init device {}\n{}", deviceName, e);
	    	} finally {
	    		put.releaseConnection();
	    	}
			
		} else {
		    BaseControl device = null;
		    SimpleEntry entry = null;
	    	entry = (SimpleEntry) props.getJposEntry(deviceName);
	    	if(entry == null) {
	    		LOGGER.error("{} is not configured", deviceName);
	    	} else {
	    		try {
	    			device = (BaseControl) Class.forName("jpos." + entry.getProp("deviceCategory").getValueAsString()).getConstructor().newInstance();
	    			device.open(deviceName);
	    			device.claim(1000);
	    			device.setDeviceEnabled(true);
	    			if ( "POSPrinter".equals(entry.getProp("deviceCategory").getValueAsString() ) ) { 
		    			((POSPrinter) device).addStatusUpdateListener(this);
		    			((POSPrinter) device).addErrorListener(this);
		    			((POSPrinter) device).addOutputCompleteListener(this);
		    			// Even if using any printer, 0.01mm unit makes it possible to print neatly.
		    			((POSPrinter) device).setMapMode(POSPrinterConst.PTR_MM_METRIC);
		    			// Output by the high quality mode
		    			((POSPrinter) device).setRecLetterQuality(true);
	    			}
	    			devices.put(deviceName, device);
	    			LOGGER.info("device init success: {}", deviceName);
	    		} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
	    				| NoSuchMethodException | SecurityException | ClassNotFoundException | JposException ex) {
	    			LOGGER.error("device init error: {}", ex);
	    			if(ex instanceof JposException && ((JposException)ex).getOrigException()!=null) {
	    				LOGGER.error(((JposException)ex).getOrigException().getMessage());
	    			}
	    			LOGGER.error("check path for dll access:"+ System.getProperty("java.library.path"));
	    		}
	    	}
			
		}
	}
	
	
	@Override
	public void releaseDevices() {
		if (statusPoll != null && statusPoll.isRunning()) {
			statusPoll.stop();
		}
		if (signatureStatusPoll != null && signatureStatusPoll.isRunning()) {
			signatureStatusPoll.stop();
		}
		if (isRemote) {
	        HttpPut put;
	    	put = new HttpPut(String.format("http://%s:%d/devices/release", remoteHost, remotePort));
	    	put.addHeader("Accept", "application/json");
	    	try(CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
	    		CloseableHttpResponse response = httpClient.execute(put);
	    		LOGGER.info(EntityUtils.toString(response.getEntity()));
	    	} catch (IOException e) {
	    		LOGGER.error("{}", e);
	    	} finally {
	    		put.releaseConnection();
	    	}
		} else {
			// release all devices that have been initialized
			for( String d:devices.keySet() ) {
	    		try {
	    			devices.get(d).setDeviceEnabled(false);
	    			SimpleEntry entry = null;
	    	    	entry = (SimpleEntry) props.getJposEntry(d);
	    	    	if("POSPrinter".equals(entry.getProp("deviceCategory").getValueAsString() )) {
	    				((POSPrinter) devices.get(d)).removeStatusUpdateListener(this);
	    			}
	    			devices.get(d).release();
	    			devices.get(d).close();
	    		} catch (JposException e) {
	    			LOGGER.error("Error releasing {}", d); 
	    		}
			}
		}

	}

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

	public int[] getAllWeights(String deviceName) {
		int[] weightData = new int[3];
		if (isRemote) {
			Map<String, String> params = new LinkedHashMap<>();
			params.put(DEVICE_NAME, deviceName);
			String result = doHttpGet("/devices/readAllWeights", params);
			if( result != null ) {
				String[] results = result.split(" ");
				for( int i=0 ; i<(results.length<weightData.length?results.length:weightData.length) ; i++ ) {
					weightData[i] = Integer.parseInt(results[i]);
				}
				LOGGER.debug("readAllWeights: {}, {}, {}", weightData[0], weightData[1], weightData[2]);
			}
			return weightData;

		} else if (!initDone || !devices.containsKey(deviceName)) {
			return weightData;
		}
		try {
			((Scale) devices.get(deviceName)).readWeight(weightData, 2000);
		} catch (JposException e) {
			LOGGER.error("general error readAllWeights for device:{} ex:{}", deviceName, e);
		} catch (Exception ex) {
			LOGGER.error("general error readAllWeights for device:{} ex:{}", deviceName, ex);
		}
		// net weight in element 0
		// gross weight in element 1
		// tare weight in element 2
		LOGGER.debug("readAllWeights: {}, {}, {}", weightData[0], weightData[1], weightData[2]);
		return weightData;
	}

	public Double getReadWeight(String deviceName) {
		if (isRemote) {
			Map<String, String> params = new LinkedHashMap<>();
			params.put(DEVICE_NAME, deviceName);
			String result = doHttpGet("/devices/readNetWeight", params);
			if( result != null ) {
				if( result.contains("status") ) {
					LOGGER.error("general error readNetWeight for device:{} ex:{}", deviceName, result);
				} else { 
					Double result2 = Double.parseDouble(result.replace(",", "."));
					LOGGER.debug("readNetWeight: {}", result2);
					return result2;
				}
			} 
			return 0.0;

		} else if (!initDone || !devices.containsKey(deviceName)) {
			return 0.0;
		}
		int[] weightData = new int[3];
		try {
			((Scale) devices.get(deviceName)).readWeight(weightData, 2000);
		} catch (JposException e) {
			LOGGER.error("general error readNetWeight for device:{} ex:{}", deviceName, e);
		} catch (Exception ex) {
			LOGGER.error("general error readNetWeight for device:{} ex:{}", deviceName, ex);
		}
		// net weight in element 0
		// gross weight in element 1
		// tare weight in element 2
		Double result = (1.0*weightData[0]) / 1000.0;
		LOGGER.debug("readNetWeight: {}", result);
		return result;
	}

	public Double getReadTareWeight(String deviceName) {
		if (isRemote) {
			Map<String, String> params = new LinkedHashMap<>();
			params.put(DEVICE_NAME, deviceName);
			String result = doHttpGet("/devices/readTareWeight", params);
			if( result != null ) {
				if( result.contains("status") ) {
					LOGGER.error("general error getReadTareWeight for device:{} ex:{}", deviceName, result);
				} else {
					Double result2 = Double.parseDouble(result.replace(",", "."));
					LOGGER.debug("readTareWeight: {}", result2);
					return result2;
				}
			}
			return 0.0;
		} else if (!initDone || !devices.containsKey(deviceName)) {
			return 0.0;
		}
		int tareWeight = 0;
		try {
			if (((Scale) devices.get(deviceName)).getCapTareWeight()) {
				tareWeight = ((Scale) devices.get(deviceName)).getTareWeight();
			}
		} catch (JposException e) {
			LOGGER.error("general error readWeight for device:{} ex:{}", deviceName, e);
		} catch (Exception ex) {
			LOGGER.error("general error readWeight for device:{} ex:{}", deviceName, ex);
		}
		Double result = (1.0*tareWeight) / 1000.0;
		LOGGER.debug("readTareWeight: {}", result);
		return result;
	}

	public String getWeightUnit(String deviceName) {
		if (isRemote) {
			Map<String, String> params = new LinkedHashMap<>();
			params.put(DEVICE_NAME, deviceName);
			String result = doHttpGet("/devices/weightUnit", params);
			if( result != null )
				if( result.contains("status") ) {
					LOGGER.error("general error getReadTareWeight for device:{} ex:{}", deviceName, result);
				} else { 
					LOGGER.debug("getWeightUnit: {}", result);
					return result;
				}
			return null;

		} else if (!initDone || !devices.containsKey(deviceName)) {
			return null;
		}
		try {
			String result="";
			int unitType = ((Scale) devices.get(deviceName)).getWeightUnit();
			switch (unitType) {
			case 0:
				result = "pound 1/8";
				break;
			case 1:
				result = "pound 1/10";
				break;
			case 2:
				result = "pound 1/500";
				break;
			case 3:
				result = "kg";
				break;
			case 4:
				result = "pound";
				break;
			case 5:
				result = "oz";
				break;
			}
			LOGGER.debug("getWeightUnit: {}", result);
			return result;
		} catch (JposException e) {
			LOGGER.error("general error readWeight for device:{} ex:{}", deviceName, e);
		} catch (Exception ex) {
			LOGGER.error("general error readWeight for device:{} ex:{}", deviceName, ex);
		}
		return null;
	}

	public void setScaleDisplayText(String deviceName, String displayText) {
		if (isRemote) {
			doHttpPut("/devices/scaleDisplayText", DEVICE_NAME, deviceName, "displayText", displayText);
			return;

		} else if (!initDone || !devices.containsKey(deviceName)) {
			return;
		}
		try {
			if (((Scale) devices.get(deviceName)).getCapDisplayText()) {
				((Scale) devices.get(deviceName)).displayText(displayText);
			}
		} catch (JposException e) {
			LOGGER.error("general error scaleDisplayText for device:{} text:{} ex:{}", deviceName, displayText, e);
		} catch (Exception ex) {
			LOGGER.error("general error scaleDisplayText for device:{} text:{} ex:{}", deviceName, displayText, ex);
		}
	}

	public void setTareWeight(String deviceName, String tareWeightInGramms) {
		if(null == tareWeightInGramms)
			tareWeightInGramms = "0";
		if (isRemote) {
			doHttpPut("/devices/tareWeight", DEVICE_NAME, deviceName, "tareWeight", tareWeightInGramms);
			return;
		} else if (!initDone || !devices.containsKey(deviceName)) {
			return;
		}
		try {
			if (((Scale) devices.get(deviceName)).getCapTareWeight()) {
				((Scale) devices.get(deviceName)).setTareWeight(Integer.parseInt(tareWeightInGramms));
			}
		} catch (JposException e) {
			LOGGER.error("general error tareWeight for device:{} text:{} ex:{}", deviceName, tareWeightInGramms, e);
		} catch (Exception ex) {
			LOGGER.error("general error tareWeight for device:{} text:{} ex:{}", deviceName, tareWeightInGramms, ex);
		}
	}

	public void setZeroScale(String deviceName, String dummy) {
		if (isRemote) {
			doHttpPost("/devices/zeroScale", DEVICE_NAME, deviceName);
			return;

		} else if (!initDone || !devices.containsKey(deviceName)) {
			return;
		}
		try {
			if (((Scale) devices.get(deviceName)).getCapZeroScale()) {
				((Scale) devices.get(deviceName)).zeroScale();
			}
		} catch (JposException e) {
			LOGGER.error("general error zeroScale for device:{} ex:{}", deviceName, e);
		} catch (Exception ex) {
			LOGGER.error("general error zeroScale for device:{} ex:{}", deviceName, ex);
		}
	}

	// 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( null == displayLine ) {
			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);
					}
					printerBitmapIsSet[bitmapIndex] = true;
				}
			} 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);
		}
	}

	/**
	 * start transactional printing
	 * 
	 * @param deviceName
	 *            the device name
	 */
	public void setStartTransactionPrint(String deviceName) {

		if (isRemote) {
			return;
		} else if (!initDone || !devices.containsKey(deviceName)) {
			return;
		}

		try {
			POSPrinterControl114 device = (POSPrinterControl114) devices.get(deviceName);
			if (device.getCapTransaction())
				device.transactionPrint(POSPrinterConst.PTR_S_RECEIPT, POSPrinterConst.PTR_TP_TRANSACTION);
		} catch (Exception e) {
			LOGGER.error("jpos error printCut for device:" + deviceName + " {}", e);
		}
	}

	/**
	 * end transactional printing
	 * 
	 * @param deviceName
	 *            the device name
	 */
	public void setEndTransactionPrint(String deviceName) {

		if (isRemote) {
			return;
		} else if (!initDone || !devices.containsKey(deviceName)) {
			return;
		}

		try {
			POSPrinterControl114 device = (POSPrinterControl114) devices.get(deviceName);
			if (device.getCapTransaction())
				device.transactionPrint(POSPrinterConst.PTR_S_RECEIPT, POSPrinterConst.PTR_TP_NORMAL);
		} catch (Exception e) {
			LOGGER.error("jpos error printCut 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;
		}
		POSPrinterControl114 device = (POSPrinterControl114) devices.get(deviceName);

		try {
			if (!footer.isEmpty()) {
				device.printNormal(POSPrinterConst.PTR_S_RECEIPT, footer);
			}
			if (device.getCapRecPapercut()) {
				linefeedToPapercut(device);
			}
			device.cutPaper(99);
		} catch (JposException eAll) {
			LOGGER.error("jpos error printCut for device:" + deviceName + " {}", eAll);
			try {
				device.printNormal(POSPrinterConst.PTR_S_RECEIPT, esc + "i");
			} catch (JposException e) {
				LOGGER.error("retry jpos error printCut for device:" + deviceName + " {}", e);
			}
		}
	}

	private void linefeedToPapercut(POSPrinterControl114 device) throws JposException {
		int linesToPaperCut = device.getRecLinesToPaperCut() + 1;
		try {
			device.printNormal(POSPrinterConst.PTR_S_RECEIPT, esc + "|" + linesToPaperCut + "lF");	// linefeed variant 1
		} catch (JposException e) {
			LOGGER.debug("jpos error linefeedToPapercut - retry variant 2");
			device.printNormal(POSPrinterConst.PTR_S_RECEIPT, esc + "d" + ((char) (linesToPaperCut))); // linefeed variant 2
		}
	}

	/**
	 * 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);
			printerBitmapIsSet[printBitmap] = false;
		}
	}

	/**
	 * 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());
			}
			POSPrinterControl114 device = (POSPrinterControl114) devices.get(deviceName);
			if (device.getCapRecBarCode()) {
				device.printBarCode(POSPrinterConst.PTR_S_RECEIPT, value, code, height, device.getRecLineWidth()-1,
						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) {
		if ("null".equals(ptIP))
			this.ptIP = "";
		else
			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 && !getPTIP().isEmpty() && getPTPort() > 0
				&& POSServiceBinder.getPosService().openZVTChannel(getPTIP(), getPTPort())) {
			paymentTerminalIsOpen = true;
			return;

		}
		paymentTerminalIsOpen = false;
		LOGGER.error("could not open ZVT socket at '{}:{}'", getPTIP(), getPTPort());
	}

	/**
	 * Sets the close payment terminal.
	 *
	 * @param close
	 *            the new close payment terminal
	 */
	public void setClosePaymentTerminal(String close) { // NOSONAR
		if (POSServiceBinder.getPosService() != null && paymentTerminalIsOpen) {
			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 && paymentTerminalIsOpen) {
			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 && paymentTerminalIsOpen) {
			// 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 && paymentTerminalIsOpen) {
			/**
			 * zvt.prepaidTopUp(amount);
			 */
		}
	}

	/**
	 * Sets the payment terminal reversal.
	 *
	 * @param reversal
	 *            the new payment terminal reversal
	 */
	public void setPaymentTerminalReversal(String reversal) {
		if (POSServiceBinder.getPosService() != null && paymentTerminalIsOpen) {
			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) {
		if (POSServiceBinder.getPosService() != null && paymentTerminalIsOpen) {
			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 && paymentTerminalIsOpen) {
			POSServiceBinder.getPosService().zvtAuthorization(amount);
		}
	}

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

	/**
	 * Gets the payment terminal transaction.
	 *
	 * @return the payment terminal transaction
	 */
	public IZVTTransactionData getPaymentTerminalTransaction() {
		if (POSServiceBinder.getPosService() != null && paymentTerminalIsOpen) {
			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) {
			try {
				if (POSServiceBinder.getSignatureService().openTablet(statemachine.getBlobService())) {
					statemachine.schedule(statemachine, 500, new MessageEvent(EventType.TRIGGER, "onSignaturePadOpen"));
					signaturePadIsOpen = true;
					return;
				}
			} catch (Exception e) {
				LOGGER.error("Initialization of signature pad failed - continue without signature pad");
			}
			signaturePadIsOpen = false;
		}
	}

	public void setSignatureCapture(String dummy) { // NOSONAR
		if (isRemote) {
			doHttpPost("/signature/captureTablet");
		} else if (POSServiceBinder.getSignatureService() != null && signaturePadIsOpen) {
			POSServiceBinder.getSignatureService().captureTablet();
			POSServiceBinder.getSignatureService().addListener(this);
		}
	}

	public void setSignatureIdle(String dummy) { // NOSONAR
		if (isRemote) {
			doHttpPost("/signature/idleTablet");
		} else if (POSServiceBinder.getSignatureService() != null && signaturePadIsOpen) {
			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 && signaturePadIsOpen) {
			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 && signaturePadIsOpen) {
			POSServiceBinder.getSignatureService().addSlideTablet(slideId);
		}
	}

	public void setSignatureSlideDelay(Integer delay) {
		if (isRemote) {
			doHttpPut("/signature/slideDelay", "delay", delay.toString());
		} else if (POSServiceBinder.getSignatureService() != null && signaturePadIsOpen) {
			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 && signaturePadIsOpen) {
			POSServiceBinder.getSignatureService().removeListener(this);
			POSServiceBinder.getSignatureService().closeTablet();
		}
	}

	public void setSignatureLabel(String labels) {
		if (isRemote) {
			doHttpPut("/signature/addLabels", "labels", labels);
		} else if (POSServiceBinder.getSignatureService() != null && signaturePadIsOpen) {
			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) {
			Map<String, String> params = new LinkedHashMap<>();
			params.put("width", Integer.toString(statemachine.getSceenWidth()));
			params.put("height", Integer.toString(statemachine.getScreenHeight()));
			String base64String = doHttpGet("/signature/signature", params);
			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));
				}
			}
		}
	}
}
