import sys
import serial

from PyQt5.QtCore import QSize, Qt, QTimer
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QLabel, QLineEdit, QVBoxLayout, QHBoxLayout, QSpinBox, QWidget


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.show()

        #self.led_is_on = False
        self.connected = False
        self.serial = serial.Serial()
        self.com_port_num = 4

        # Window
        self.setWindowTitle("LED controller")
        self.setFixedSize(QSize(400, 300))

        # Top bar
        com_label = QLabel("COM")
        com_label.setMinimumWidth(30)

        com_port = self.com_port_input = QSpinBox()
        com_port.setValue(self.com_port_num)
        com_port.valueChanged.connect(self._on_com_port_value_changed)

        connect_button = self.connect_button = QPushButton("Connect")
        connect_button.setCheckable(True) # Toggle button
        connect_button.clicked.connect(self._on_connect_button_pressed)

        baud_label = QLabel("9600 BAUD") # This is not changed
        baud_label.setMinimumWidth(80)

        top_bar = QHBoxLayout()
        top_bar.addWidget(com_label)
        top_bar.addWidget(com_port)
        top_bar.addWidget(connect_button)
        top_bar.addWidget(baud_label)
        top_bar.setAlignment(Qt.AlignLeft | Qt.AlignTop)

        # Status Label
        status_label = self.status_label = QLabel()
        status_label.setAlignment(Qt.AlignLeft | Qt.AlignTop)

        # LED Button
        led_button = self.led_button = QPushButton("LED")
        led_button.setCheckable(True) # Toggle button
        led_button.setEnabled(False) # Cannot press the button when not connected
        led_button.clicked.connect(self._on_led_button_pressed)

        # Layout
        layout = QVBoxLayout()
        layout.addLayout(top_bar)
        #layout.addWidget(text_input)
        layout.addWidget(status_label)
        layout.addWidget(led_button)

        # Container
        container = QWidget()
        container.setLayout(layout)

        # Set the central widget of the Window.
        self.setCentralWidget(container)

        # Timer for reading the serial port
        self.serial_timer = QTimer()
        self.serial_timer.setInterval(500)
        self.serial_timer.timeout.connect(self._on_serial_timer_timeout)


    def _on_led_button_pressed(self, checked):
        if not self.serial.is_open:
            return
        if checked:
            #print("Turning led on")
            #self.led_is_on = True
            self.serial.write(b'1')
        else:
            #print("Turning led off")
            #self.led_is_on = False
            self.serial.write(b'0')


    def _on_connect_button_pressed(self, checked):
        if checked and not self.serial.is_open:
            # Try to connect to serial
            self.serial.baudrate = 9600
            self.serial.port = "COM" + str(self.com_port_num)
            #print("COM" + str(self.com_port_num))
            try:
                self.serial.open()
            except serial.SerialException:
                #print("Failed to connect")
                self.connect_button.setChecked(False)
                self.status_label.setText("Failed to connect")
                return
            self.status_label.setText("")
            #print("Connected")
            self.connect_button.setText("Connected")
            self.com_port_input.setEnabled(False)
            self.led_button.setEnabled(True)
            self.serial.write(b'\n')
            self.serial_timer.start()
        elif self.serial.is_open:
            # Disconnect serial
            self.serial_timer.stop()
            self.serial.close()
            #print("Disconnected")
            self.connect_button.setText("Connect")
            self.com_port_input.setEnabled(True)
            self.led_button.setEnabled(False)
            self.led_button.setText("LED")


    def _on_com_port_value_changed(self, value):
        self.com_port_num = value

    def _on_serial_timer_timeout(self):
        if not self.serial.is_open or not self.serial.in_waiting:
            # Nothing to read
            return
        message = ""
        while self.serial.in_waiting:
            # Read byte and add to string
            message += self.serial.read().decode('utf-8')
        # Remove possible newline characters and split to arguments
        data = message.strip('\r\n').split(',')

        if data[0] == "LED" and data[1] == '0':
            # Information is about LED index 0
            if data[2] == '1':
                # The LED has been turned on
                self.led_button.setChecked(True)
                self.led_button.setText("LED is on")
            elif data[2] == '0':
                # The LED has been turned off
                self.led_button.setChecked(False)
                self.led_button.setText("LED is off")


app = QApplication(sys.argv)

window = MainWindow()

app.exec()
