/*                                                                      *\
**                    SICU Stress Measurement System                    **
**                      Project P04  |  C380 Team A                     **
**          EBME 380: Biomedical Engineering Design Experience          **
**                    Case Western Reserve University                   **
**                          2016 Fall Semester                          **
\*                                                                      */

package edu.cwru.sicu_sms.util;

import jssc.SerialPort;
import jssc.SerialPortEventListener;
import jssc.SerialPortException;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;

/**
 * This class is an abstraction of a serial port comprising all the necessary parameters and core functionality needed for the client application.
 *
 * @since December 12, 2016
 * @author Ted Frohlich <ttf10@case.edu>
 * @author Abby Walker <amw138@case.edu>
 */
abstract class AbstractSerialPort implements SerialPortEventListener {
    
    SerialPort serialPort;
    Properties properties;
    
    /**
     * Constructs the underlying serial port with properties from the specified file.
     *
     * @param filename the relative path to the <code>.properties</code> file
     */
    AbstractSerialPort(String filename) {
        properties = new Properties();
        try {
            FileInputStream inStream = new FileInputStream(filename);
            properties.load(inStream);
            inStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    ///////////////////////////  GETTERS  ///////////////////////////////
    
    private String getProperty(String key) {
        return properties.getProperty(key);
    }
    
    private int getPropertyAsInt(String key) {
        return Integer.parseInt(getProperty(key));
    }
    
    public String getPortName() {
        return getProperty("portName");
    }
    
    public String getNickname() {
        return getProperty("nickname");
    }
    
    public int getBaudRate() {
        return getPropertyAsInt("baudRate");
    }
    
    public int getDataBits() {
        return getPropertyAsInt("dataBits");
    }
    
    public int getStopBits() {
        return getPropertyAsInt("stopBits");
    }
    
    public int getParity() {
        return getPropertyAsInt("parity");
    }
    
    public int getMask() {
        return getPropertyAsInt("mask");
    }
    
    ///////////////////////////  SETTERS  ///////////////////////////////
    
    private void setProperty(String key, String value) {
        properties.setProperty(key, value);
    }
    
    private void setPropertyAsInt(String key, int value) {
        setProperty(key, String.valueOf(value));
    }
    
    public void setPortName(String value) {
        setProperty("portName", value);
    }
    
    public void setNickname(String value) {
        setProperty("nickname", value);
    }
    
    public void setBaudRate(int value) {
        setPropertyAsInt("baudRate", value);
    }
    
    public void setDataBits(int value) {
        setPropertyAsInt("dataBits", value);
    }
    
    public void setStopBits(int value) {
        setPropertyAsInt("stopBits", value);
    }
    
    public void setParity(int value) {
        setPropertyAsInt("parity", value);
    }
    
    public void setMask(int value) {
        setPropertyAsInt("mask", value);
    }
    
    // TODO: Setters should write updated properties back to .properties file!
    
    ////////////////////////  OTHER METHODS  ////////////////////////////
    
    /**
     * Opens the underlying serial port.
     *
     * @return <code>true</code> if the serial port was successfully opened; <code>false</code> otherwise
     */
    public boolean openPort() {
        boolean success = false;
        final SerialPort newPort = new SerialPort(getPortName());
        try {
            newPort.openPort();
            newPort.setParams(getBaudRate(), getDataBits(), getStopBits(), getParity());
            newPort.setEventsMask(getMask());
            newPort.addEventListener(this);
            
            serialPort = newPort;
            success = true;
        }
        catch (SerialPortException e) {
            e.printStackTrace();
        }
        return success;
    }
    
    /**
     * Reads ____ data in the input buffer of the underlying serial port.
     * TODO: Should know how many bytes to read at a time!
     *
     * @return a byte array of data
     */
    public byte[] readData() {
        byte[] data = null;
        try {
            data = serialPort.readBytes();
        }
        catch(SerialPortException e) {
            e.printStackTrace();
        }
        return data;
    }
    
    /**
     * Closes the underlying serial port.
     *
     * @return <code>true</code> if the serial port was successfully closed; <code>false</code> otherwise
     */
    public boolean closePort() {
        boolean success = false;
        try {
            serialPort.removeEventListener();
            if (serialPort.isOpened())
                serialPort.closePort();
            
            serialPort = null;
            success = true;
        }
        catch (SerialPortException e) {
            e.printStackTrace();
        }
        return success;
    }
    
}

@@ -1393,20 +1393,16 @@
 es =
- new
  Propert
 ies(
@@ -1401,244 +1401,43 @@
 pert
-ies();%0A        try %7B%0A            FileInputStream inStream = new FileInputStream(filename);%0A            properties.load(inStream);%0A            inStream.close();%0A        %7D catch (IOException e) %7B%0A            e.printStackTrace();%0A        %7D
+yOperator.loadProperties(filename);
 %0A   

Update constructor, delegating implementation to the new 'PropertyOperator' class