import sys
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5.QtCore import pyqtSlot
from PyQt5.QtCore import QThread, pyqtSlot
from PyQt5.QtCore import pyqtSignal as Signal
from PyQt5 import uic
from serial import Serial, SerialException
from threading import Thread


# Load the UI file using loadUiType
UiClass, BaseClass = uic.loadUiType("C:\\Users\\zktmt\\Desktop\\digital_circuit\\src\\week9\\mortor.ui")

class WindowClass(QMainWindow, UiClass):
    def __init__(self):
        super().__init__()
        self.setupUi(self)  # setupUi method comes from UiClass
       
        self.dev = None
        self.receiver = Receiver(self)

        # Connect signals to slots
        self.pushButton_Open.clicked.connect(self.openFunction)
        self.pushButton_Clear.clicked.connect(self.clearFunction)
        self.push_Close.clicked.connect(self.closeFunction)
        self.pushButton_Set.clicked.connect(self.setFunction)
        self.pushButton_Reset.clicked.connect(self.resetFunction)
        self.receiver.rx_data.connect(self.rx_data_append)

    @pyqtSlot()        
    def clearFunction(self):
        self.textEdit.clear()

    @pyqtSlot()
    def openFunction(self):
        current_port = self.comboPort.currentText()
        current_baudrate = int(self.comboBox_Baudrate.currentText())

        if self.dev is None or not self.dev.isOpen():
            try:
                self.dev = Serial(current_port, current_baudrate)
                self.textEdit.append("Device opened")
            except SerialException as e:
                self.textEdit.append(f"Failed to open the device: {e}")
        else:
            self.textEdit.append("Device already opened")

    @pyqtSlot()
    def closeFunction(self):
        if self.dev:
            if self.dev.is_open:
                self.dev.close()
                self.dev = None
                self.textEdit.append("Device closed")
            else:
                self.textEdit.append("Already closed")
        else:
            self.textEdit.append("Already closed")
    
    @pyqtSlot()
    def setFunction(self):
        current_velocity = int(self.comboBox_Velocity.currentText())
        current_direction = (self.comboBox_Direction.currentText())
        a=current_direction = (self.comboBox_Direction.currentText())
        time_setting=(self.comboBox_Time.currentText())
        b=(self.comboBox_Time.currentText())

        if current_direction =="정방향":
            current_direction = int(8)
        elif current_direction == "역방향":
            current_direction = int(9)


        if time_setting =='세팅x':
            time_setting =int(10)
        elif time_setting =='5초':
            time_setting =int(11)
        elif time_setting =='10초':
            time_setting =int(12)
        elif time_setting =='15초':
            time_setting =int(13)


        if self.dev:
            try:
                sender = Sender(self.dev, current_velocity,current_direction,time_setting)
                sender.start()
                self.textEdit.append("SET")
                self.textEdit.append(f"Velocity:{current_velocity}  Direction:{a}  Time setting:{b} ")
            except Exception as e:
                self.textEdit.append(f"Failed to set: {e}")
    @pyqtSlot()
    def resetFunction(self):
        current_velocity = int(0)
        current_direction = int(0)
        time_setting=int(0)
        if self.dev:
            try:
                sender = Sender(self.dev, current_velocity,current_direction,time_setting)
                sender.start()
                self.textEdit.append("STOP")
            except Exception as e:
                self.textEdit.append(f"Failed to set: {e}")
    @pyqtSlot(bytes)
    def rx_data_append(self, r_data):
        value = int.from_bytes(r_data, byteorder='big', signed=False)  # big-endian 처리
        if value == 254:
            self.textEdit.append("작동 중지")  # 254를 받으면 "작동 중지" 출력
        else:
            self.textEdit.append(f"Received: {value}")


class Sender(Thread):
    
    def __init__(self, dev, velocity=None,direction=None, time=None):
        super().__init__()
        self.dev = dev
        self.velocity = velocity
        self.direction = direction
        self.time=time

    def run(self):
        if self.dev is not None:
            try:
                data = bytes([self.velocity]) if self.velocity is not None else b''
                data2 = bytes([self.direction]) if self.direction is not None else b''
                data3 = bytes([self.time]) if self.time is not None else b''
                
                self.dev.write(data)
                self.dev.write(data2)
                self.dev.write(data3)
                print(data,data2,data3)
                
            except SerialException as e:
                print(f"Error writing to serial port: {e}")
                return
        else:
            print("Device not initialized")





class Receiver(QThread):
    rx_data = Signal(bytes)

    def __init__(self, parent=None):
        super(Receiver, self).__init__(parent)
        self.serial_monitor = parent
        self.is_running = True

    def run(self):
        while self.is_running:
            try:
                data = self.serial_monitor.dev.read(1)
                if data:
                    self.rx_data.emit(bytes(data))
            except SerialException as e:
                print(f"Error reading from serial: {e}")
                break

if __name__ == "__main__":
    app = QApplication(sys.argv)
    mainWindow = WindowClass()
    mainWindow.show()
    sys.exit(app.exec_()) 이 코드에서 시리얼통신을 통해 정수254를 받으면 "작동중지"라는 텍스트가 나오게 수정해줘