package com.asreader.asr033w.asr033w;

import java.io.IOException;
import java.io.InputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;


/**
 * Device is a abstract class for connections with Reader devices.
 *
 */
public abstract class ASR033WDevice {

	/**
	 * Size of the receive buffer
	 */
	public static final int MAX_BUFFER_SIZE = 1024 * 12;
	
	/**
	 * Size of the PipedInputStream
	 */
	public static final int MAX_STREAM_SIZE = 1024 * 16;

	protected static String TAG = ASR033WDevice.class.getSimpleName();
	protected PipedOutputStream mWriter;
	protected PipedInputStream mReader;
	protected boolean mIsConnectComplete;
	protected boolean DEBUG = false;
	
	/**
	 * Create an instance of the Device class
	 */
	public ASR033WDevice() {
		this.mWriter = null;
		this.mReader = null;
		
		mIsConnectComplete = false;
	}
	
	/**
	 * Destroy an instance and release resources.
	 */
	public abstract void destroy();

	/**
	 * Returns name of device.
	 * @return String that indicates name of device
	 */
	public abstract String getName();

	/**
	 * Returns address of device
	 * @return String that indicates address of device
	 */
	public abstract String getAddress();

	/**
	 * Sets address of device
	 * @param address String that indicates address of device
	 */
	public abstract void setAddress(String address);

	/**
	 * Attempts to connect to the appliance using an instance of the Device class.
	 * @param address
	 */
	public abstract void connect(String address);

	public abstract void waitConnection();
	
	/**
	 * An instance of the Device class waits for the device to connect. Not used.
	 */
	public abstract void listen();

	/**
	 * An instance of the Device class closes the connection to the device to which the device is connected.
	 */
	public abstract void disconnect();
	public abstract void disconnect(boolean wait_connect);

	/**
	 * Write data to the device.
	 * @param data Array of byte that specifies the data to write to the Device.
	 * @throws Exception Exception is thrown if a failure occurs while writing data on device.
	 */
	public abstract void write(byte[] data) throws Exception;

	/**
	 * Returns instance of the PipedInputStream. Used internally in the API.
	 * @return Instance of the PipedInputStream
	 */
	public InputStream getReader() {
		return this.mReader;
	}

	protected boolean createStream() {
		try {
			this.mWriter = new PipedOutputStream();
			this.mReader = new PipedInputStream(this.mWriter, MAX_STREAM_SIZE);
		} catch (IOException e) {
			return false;
		}
		return true;
	}

	protected void destroyStream() {
		if (this.mWriter != null) {
			try {
				this.mWriter.close();
			} catch (IOException e) {
			}
			this.mWriter = null;
		}
		if (this.mReader != null) {
			try {
				this.mReader.close();
			} catch (IOException e) {
			}
			this.mReader = null;
		}
	}
}
