/*
Trieda umožňujúca komunikáciu so zariadením, komunikujúcim
skrz sériovú linku. Pre svoju činnosť využíva externú
knižnicu "jSerialComm" ....
 */

package CommunicationAndSaving;

import com.fazecast.jSerialComm.SerialPort;

import javax.swing.*;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;

public class serialCommunication {

    public final String START_COMMAND = "start";
    public final String STOP_COMMAND = "stop";
    public final String END_COMMAND = "end";
    public final String ARDUINO_READY = "ansok";
    public final String SPLIT_CHAR_SEPARATOR = ",";
    public final String NEW_PLANE = "C";
    public final double REGULAR_STEP = 360/25560;
    public final double M_FACTOR_FOR_CPLANE = 71;
    public final double M_FACTOR_FOR_GAMMA = 71;
    public final int TIME_DELAY = 5000;
    public final int GAMMA_RANGE = 360;
    public final int CPLANE_RANGE = 180;


    private static SerialPort serialPort;
    private static ArrayList<SerialPort> serialPorts = new ArrayList<SerialPort>();

    /*
    Konštruktor triedy "načítajúci" zoznam USB portov prítomných v zariadení ...
     */
    public serialCommunication() throws IOException {
        serialPorts = new ArrayList<SerialPort>(Arrays.asList(SerialPort.getCommPorts()));
    }

    public void openSerialPort(){
        try {
            SelectPort(serialPort.getDescriptivePortName());
            if (serialPort.openPort()){
                System.out.println("Serial is OPEN!");
            }else {
                System.out.println("Serial is NOT OPEN!");
            }
        }catch (Exception exception){
            JOptionPane.showMessageDialog(null, "Can not open the Serial Port!");
        }
    }

    public void closeSerialPort(){
        serialPort.closePort();
    }

    public void serialSend(String send) throws InterruptedException, IOException {
        byte[] bytesSend = send.getBytes();
        try {
            serialPort.setComPortTimeouts(SerialPort.TIMEOUT_WRITE_SEMI_BLOCKING, TIME_DELAY,TIME_DELAY);
            OutputStream out = serialPort.getOutputStream();
            Thread.sleep(1500);
            out.write(bytesSend);
            out.close();
        } catch (Exception e) {
            System.out.println("Can not send DATA serialSend() function!");
        }
        System.out.println("serialSend() ended!");
    }

    public String serialRead() throws IOException {
        StringBuilder stringBuilder = new StringBuilder("");
        try {
            serialPort.setComPortTimeouts(SerialPort.TIMEOUT_WRITE_SEMI_BLOCKING, TIME_DELAY,TIME_DELAY);
            InputStream inputStream = serialPort.getInputStream();
            while(inputStream.available() != 0){
                stringBuilder.append((char)inputStream.read());
            }
            inputStream.close();
        }catch (Exception e){
            System.out.println("Can not send DATA serialRead() function!");
        }

        return stringBuilder.toString();
    }

    public ArrayList<String> usbCommPortDescriptions() {
        ArrayList<String> usbPortDescriptions = new ArrayList<String>(); // descriptivePortNames
        for (SerialPort port : serialPorts) {
            usbPortDescriptions.add(port.getDescriptivePortName());
        }
        return usbPortDescriptions;
    }

    public boolean SelectPort(String selectedItem) {
        boolean flag = false;
        if (!selectedItem.isEmpty()) {
            for (SerialPort port : serialPorts) {
                if (selectedItem.equals(port.getDescriptivePortName())) {
                    serialPort = port;
                    flag = true;
                }
            }
        }
        return flag;
    }

    /*
    Znovu načíta zoznam aktívnych USB portov ...
     */
    public ArrayList<SerialPort> getPorts(){
        serialPorts.clear();
        serialPorts = new ArrayList<>(Arrays.asList(SerialPort.getCommPorts()));
        return serialPorts;
    }
}
