import sys

from PyQt5 import QtGui, QtCore
from PyQt5.QtCore import Qt, pyqtSlot
from PyQt5.QtWidgets import QTableWidgetItem, QPushButton, QHeaderView, QLabel, QLineEdit
from ui.widget import Widget


class Diagnostics(Widget):
    def __init__(self, parent):
        super().__init__()
        self.parent = parent
        self.simulate = "--sim-io" in sys.argv
        self.inputs = self.parent.config["digital_inputs"]
        self.outputs = self.parent.config["digital_outputs"]
        self.color_red = "#f00"
        self.color_green = "#0f0"
        headers_out = ["OUTPUT", "SET"]
        headers_in = ["INPUT", "STATUS"]
        r = 0
        self.latch = [False for o in range (len(self.outputs))]
        self.latch_in = [False for i in range(len(self.inputs))]


        # POPULATE OUTPUT TABLE
        self.output_tb.setColumnCount(len(headers_out))
        self.output_tb.setHorizontalHeaderLabels(headers_out)
        self.output_tb.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.output_tb.verticalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.output_tb.setRowCount(len(self.outputs))
        self.output_tb.setVerticalHeaderLabels(list(self.outputs))
        self.ICON_OK = QtGui.QPixmap("src/ui/icons/ok.png").scaled(30, 30, QtCore.Qt.KeepAspectRatio)
        self.ICON_KO = QtGui.QPixmap("src/ui/icons/ko.png").scaled(30, 30, QtCore.Qt.KeepAspectRatio)
        self.ICON_OFF = QtGui.QPixmap("src/ui/icons/off.png").scaled(30, 30, QtCore.Qt.KeepAspectRatio)
        self.out_buttons=[QPushButton() for o in range(len(self.outputs))]
        for output_name,output_idx in self.outputs.items():
            for c, header in enumerate(headers_out):
                if header == "ACTIVATE":
                    self.out_buttons[r].setCheckable(True)
                    self.out_buttons[r].setText("OFF")
                    self.output_tb.setCellWidget(r, c, self.out_buttons[r])
                    indexb = QtCore.QPersistentModelIndex(self.output_tb.model().index(r, c))
                    self.out_buttons[r].clicked.connect(lambda *args, index=indexb: self.plc_bit_toggle(index))
                elif header == "OUTPUT":
                    i = QTableWidgetItem()
                    i.setText(str(output_idx))
                    self.output_tb.setItem(r, c, i)
            r += 1

        # POPULATE INPUT TABLE
        self.input_tb.setColumnCount(len(headers_in))
        self.input_tb.setHorizontalHeaderLabels(headers_in)
        self.input_tb.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.input_tb.verticalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.input_tb.setRowCount(len(self.inputs))
        self.input_tb.setVerticalHeaderLabels(list(self.inputs))
        r = 0
        if self.simulate:
            self.in_buttons = [QPushButton() for i in range(len(self.outputs))]
        for input_name, input_idx in self.inputs.items():
            for c, header in enumerate(headers_in):
                if header == "STATUS":
                    if self.simulate:
                        self.in_buttons[r].setCheckable(True)
                        self.in_buttons[r].setText("OFF")
                        self.input_tb.setCellWidget(r, c, self.in_buttons[r])
                        indexb = QtCore.QPersistentModelIndex(self.input_tb.model().index(r, c))
                        self.in_buttons[r].clicked.connect(lambda *args, index=indexb: self.in_bit_toggle(index))
                    else:
                        w = QLabel()
                        w.setPixmap(self.ICON_KO)
                        self.input_tb.setCellWidget(r, c, w)
                elif header == "INPUT":
                    i = QTableWidgetItem()
                    i.setText(str(input_idx))
                    self.input_tb.setItem(r, c, i)
            r += 1
        if not self.simulate:
            self.parent.components["digital_io"].update.connect(self.update)

    def plc_bit_toggle(self,bit_num):

        bit_num=bit_num.row()
        byte_idx = int(bit_num / 8)
        bit_idx = bit_num % 8
        if self.latch[bit_num] is True:
            self.latch[bit_num]=False
            self.out_buttons[bit_num].setText("OFF")
        else:
            self.latch[bit_num]=True
            self.out_buttons[bit_num].setText("ON")
        self.parent.components["digital_io"].set_bit(byte_idx, bit_idx, self.latch[bit_num])

    def digital_int_update(self, bit_num, output_name):
        row_num = bit_num.row()
        item = self.output_tb.cellWidget(row_num, 1)
        try:
            value = int(item.text(), 10)
            self.parent.components["digital_io"].set_int(output_name, value)
        except ValueError:
            item.setText("")

    def in_bit_toggle(self, bit_num):
        bit_num = bit_num.row()
        byte_idx = int(bit_num / 8)
        bit_idx = bit_num % 8
        if self.latch_in[bit_num] is True:
            self.latch_in[bit_num] = False
            self.in_buttons[bit_num].setText("OFF")
        else:
            self.latch_in[bit_num] = True
            self.in_buttons[bit_num].setText("ON")
        self.parent.components["digital_io"].set_in_bit(byte_idx, bit_idx, self.latch_in[bit_num])

    # UPDATE DIGITAL INPUTS DISPLAY
    @pyqtSlot(dict)
    def update(self, data):
        r = 0
        for input_name, input_idx in self.inputs.items():
            item = self.input_tb.cellWidget(r, 1)
            input_idx = int(input_idx)
            byte_idx = int(input_idx / 8)
            bit_idx = input_idx % 8
            if data[1][byte_idx][bit_idx]:
                item.setPixmap(self.ICON_OK)
            else:
                item.setPixmap(self.ICON_KO)
            r += 1
        pass

    def closeEvent(self, event):
        self.components["digital_io"].set_bit("")
