import os
import sys
from PyQt6 import QtWidgets
from PyQt6 import QtCore
from LowLevelWidgetsPackage import defaultConfigForWidgets 
from LowLevelWidgetsPackage.SingleIOPackage.SingleIOGUI import Ui_SINGLEIO


class signalClass(QtCore.QObject):
    pin_changed_from_widget = QtCore.pyqtSignal(str,int,bool,bool,str) #ToSet,PinNumber,output(1->HIGH,0->LOW),impendance (1->HIGH,0->LOW),sender_name
    pin_voltage_request_from_widget = QtCore.pyqtSignal(int,str) #PinNumber,sender_name
    pin_input_request_from_widget = QtCore.pyqtSignal(int,str) #PinNumber,sender_name
    impedance_to_widget = QtCore.pyqtSignal(bool,str) #HIGH_Z = True, LOW_Z = False
    output_to_widget = QtCore.pyqtSignal(bool,str) #HIGH = True, LOW = False
    voltage_to_widget= QtCore.pyqtSignal(float,str) #voltage in V
    input_to_widget = QtCore.pyqtSignal(bool,str) #voltage in V

class SingleIOClass(QtWidgets.QWidget):
    def __init__(self,log:defaultConfigForWidgets.LOGGER = defaultConfigForWidgets.LOGGER("ALL") ,*args, **kwargs):#args = multiple input variables, **kvargs multiple keyword variables (dictionaries, touples etc.)
    ################ INIT Function ##################
        super().__init__(*args, **kwargs)#super inherits all methods and properties from its parent  (QWIDGET classes)
        #Load UI forms creaated in QTdDesigner
        self.log = log
        self.log.log("STARTING SingleIO CLASS","UNNECESSARY")
        self.ui = Ui_SINGLEIO() #UI form generated by UI designe
        self.ui.setupUi(self)
        self.signals = signalClass()
        self._name = "SingleIO"
        self._number = 0
        self._hide_labels_flag = False
        self.setHideLabels(False)
        self.ui.pb_voltage.setText("0.0000V")
        self._voltage_treshold_min = 0.5
        self._voltage_treshold_max = 3.2

        self.ui.che_impedance.clicked.connect(self._impedanceCallback)
        self.ui.che_output.clicked.connect(self._outputCallback)
        self.signals.impedance_to_widget.connect(self._setImpedance)
        self.signals.output_to_widget.connect(self._setOutput)
        self.signals.voltage_to_widget.connect(self._setVoltage)
        self.signals.input_to_widget.connect(self._setInput)
        self.ui.pb_input.clicked.connect(self._inputCallback)
        self.ui.pb_voltage.clicked.connect(self._voltageCallback)

    def _inputCallback(self):
        self.signals.pin_input_request_from_widget.emit(self._number,self._name)

    def _voltageCallback(self):
        self.signals.pin_voltage_request_from_widget.emit(self._number,self._name)

    def setHideLabels(self,flag:bool):
        self._hide_labels_flag = flag
        self._styleOutput()
        self._styleImpedance()

    def setVoltageTreshold(self,min:float, max:float):
        self._voltage_treshold_min = min
        self._voltage_treshold_max = max
        self._styleVoltage()

    def setName(self,name:str):
        #to distinguish between different widgets change self.name -> this name will be emit in signals
        self._name = name

    def setPinNumber(self,number:int):
        self._number = number

    def _styleVoltage(self):
        voltage = float(self.ui.pb_voltage.text().replace('V',''))
        if ((voltage < self._voltage_treshold_max) and (voltage > self._voltage_treshold_min)):
            self.ui.pb_voltage.setStyleSheet("background-color: green")
        
        else:
            self.ui.pb_voltage.setStyleSheet("background-color: red")

    
    def _styleImpedance(self):
        if self.ui.che_impedance.isChecked():
            self.ui.che_impedance.setText("LOW Z")
            self.ui.che_impedance.setStyleSheet("background-color: orange")
        else:
            self.ui.che_impedance.setText("HIGH Z")
            self.ui.che_impedance.setStyleSheet("background-color: yellow")

        if self._hide_labels_flag:
            self.ui.che_impedance.setText("")

    def _styleOutput(self):
        if self.ui.che_output.isChecked():
            self.ui.che_output.setText("ON")
            self.ui.che_output.setStyleSheet("background-color: lightblue")
        else:
            self.ui.che_output.setText("OFF")
            self.ui.che_output.setStyleSheet("background-color: grey")

        if self._hide_labels_flag:
            self.ui.che_output.setText("")

    def _styleInput(self):
        if self.ui.pb_input.text() == "LOW":
            self.ui.pb_input.setStyleSheet("background-color: pink")
        else:
            self.ui.pb_input.setStyleSheet("background-color: lightgreen")

    @QtCore.pyqtSlot(bool,str)
    def _setInput(self,input,sender_name):
        self.log.log(f"SingleIOClass: set Input: {input} from {sender_name}","SIGNAL")
        if input == True:
            self.ui.pb_input.setText("HIGH")

        elif input == False:
            self.ui.pb_input.setText("LOW")

        self._styleInput()

    @QtCore.pyqtSlot(float,str)
    def _setVoltage(self,voltage:float,sender_name:str):
        self.log.log(f"SingleIOClass: set Voltage: {voltage} from {sender_name}","SIGNAL")
        self.ui.pb_voltage.setText(f"{voltage:.4f}V")
        self._styleVoltage()

    @QtCore.pyqtSlot(bool,str)
    def _setImpedance(self,impedance:bool,sender_name:str):
        self.log.log(f"SingleIOClass: set Impedance: {impedance} from {sender_name}","SIGNAL")
        self.ui.che_impedance.setChecked(impedance)
        self._styleImpedance()

    @QtCore.pyqtSlot(bool,str)
    def _setOutput(self,output:bool,sender_name:str):
        self.log.log(f"SingleIOClass: set Output: {output} from {sender_name}","SIGNAL")
        self.ui.che_output.setChecked(not output)#invert output
        self._styleOutput()

    def _impedanceCallback(self):
        self._styleImpedance()
        self.signals.pin_changed_from_widget.emit("IMPEDANCE",self._number, self.ui.che_output.isChecked(),not self.ui.che_impedance.isChecked(),self._name)#PinNumber,output(1->HIGH,0->LOW),impendance (0->HIGH,1->LOW),sender_name

    def _outputCallback(self):
        self._styleOutput()
        self.signals.pin_changed_from_widget.emit("OUTPUT",self._number,self.ui.che_output.isChecked(),not self.ui.che_impedance.isChecked(),self._name)#PinNumber,output(1->HIGH,0->LOW),impendance (0->HIGH,1->LOW),sender_name
        
if __name__ == "__main__":
    app1 = QtWidgets.QApplication([])
    window1 = SingleIOClass(QtWidgets.QWidget)
    window1.show()
    app1.exec()