from nmreval.io.asciireader import AsciiReader

from ..Qt import QtGui, QtCore, QtWidgets
from .._py.asciidialog import Ui_ascii_reader


class QAsciiReader(QtWidgets.QDialog, Ui_ascii_reader):
    data_read = QtCore.pyqtSignal(list)
    file_ext = ['.dat', '.txt']
    skip = False

    def __init__(self, fname=None, parent=None):
        super().__init__(parent=parent)
        self.setupUi(self)

        self.reader = AsciiReader(fname)

        pal = QtWidgets.QApplication.instance().palette()
        rgb = pal.color(pal.Base).getRgb()[:3]
        rgb2 = pal.color(pal.Text).getRgb()[:3]
        self.comment_textfield.setStyleSheet(f'Qdelay_textfield {{ background-color: rgb{rgb} ; color: rgb{rgb2}; }}')

        self.ascii_table.horizontalHeader().setStretchLastSection(True)
        self.buttonbox.button(QtWidgets.QDialogButtonBox.Apply).clicked.connect(self.apply)
        self.buttonbox.button(QtWidgets.QDialogButtonBox.Ok).clicked.connect(self.accept)

        self.changestaggeredrange(0)

        self.ascii_table.contextMenuEvent = self.ctx_table
        self.ascii_table.horizontalHeader().setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.ascii_table.horizontalHeader().customContextMenuRequested.connect(self.ctx_table)

    def __call__(self, fname, *args, **kwargs):
        for i in [self.stag_lineEdit, self.start_lineedit, self.end_lineedit,
                  self.comment_textfield, self.ascii_table, self.delay_lineedit]:
            i.clear()
        self.staggered_checkBox.setChecked(False)
        self.log_checkBox.setChecked(False)
        self.comment_textfield.show()

        self.reader = AsciiReader(fname)
        self.set_gui()

        if QAsciiReader.skip:
            self.accept()
        else:
            self.skippy_checkbox.blockSignals(True)
            self.skippy_checkbox.setCheckState(QtCore.Qt.Unchecked)
            self.skippy_checkbox.blockSignals(False)

            return self

    def set_gui(self):
        for text in self.reader.header:
            self.comment_textfield.appendPlainText(text)

        self.ascii_table.setRowCount(self.reader.shape[0])
        self.ascii_table.setColumnCount(self.reader.shape[1])
        try:
            last_header_line = self.reader.header[-1].split()
            if len(last_header_line) == self.reader.shape[1]:
                self.ascii_table.setHorizontalHeaderLabels(last_header_line)
        except IndexError:
            self.comment_textfield.hide()

        for i, line in enumerate(self.reader.data):
            for j, field in enumerate(line):
                it = QtWidgets.QTableWidgetItem(field)
                self.ascii_table.setItem(i, j, it)

        self.ascii_table.resizeColumnsToContents()

        if self.reader.delays is not None:
            set_string = ''.join(str(d) + '\n' for d in self.reader.delays)
            self.delay_textfield.setPlainText(set_string)
            self.delay_lineedit.setText(str(len(self.reader.delays)))

    def ctx_table(self, _):
        menu = QtWidgets.QMenu(self)
        x_action = QtWidgets.QAction('Set as x', self)
        x_action.triggered.connect(lambda: self.set_columns('x'))
        y_action = QtWidgets.QAction('Set as y', self)
        y_action.triggered.connect(lambda: self.set_columns('y'))
        menu.addActions([x_action, y_action])
        if self.label_5.isVisible():
            yerr_action = QtWidgets.QAction('Set as \u0394y', self)
            yerr_action.triggered.connect(lambda: self.set_columns('yerr'))
            menu.addAction(yerr_action)
        menu.popup(QtGui.QCursor.pos())

    def set_columns(self, mode):
        cols = ' '.join([str(s.column()+1) for s in self.ascii_table.selectionModel().selectedColumns()])
        try:
            lineedit = {'x': self.x_lineedit, 'y': self.y_lineedit, 'yerr': self.deltay_lineEdit}[mode]
            lineedit.setText(cols)
        except KeyError:
            pass

    @QtCore.pyqtSlot(int, name='on_checkBox_2_stateChanged')
    def changestaggeredrange(self, evt):
        if evt == 2:
            self.stag_lineEdit.show()
            self.stag_lineEdit.setEnabled(True)
        else:
            self.stag_lineEdit.hide()
            self.stag_lineEdit.setDisabled(True)

    @QtCore.pyqtSlot(name='on_pushButton_clicked')
    def calc_delays(self):
        self.reader.calc_delays(float(self.start_lineedit.text()), float(self.end_lineedit.text()),
                                int(self.delay_lineedit.text()), log=self.log_checkBox.isChecked(),
                                stagg=self.staggered_checkBox.isChecked(), stag_size=int(self.stag_lineEdit.text()))

        set_string = ''.join(str(d) + '\n' for d in self.reader.delays)
        self.delay_textfield.setPlainText(set_string)

    def update_header(self, text, comment='#'):
        text = text.replace(comment, '').lstrip().rstrip()
        self.comment_textfield.appendPlainText(text)

    @QtCore.pyqtSlot()
    def on_delay_textfield_textChanged(self):
        new_delays = str(self.delay_textfield.toPlainText()).rstrip('\n').split('\n')
        self.delay_lineedit.setText(str(len(new_delays)))
        if new_delays[0] == '':
            new_delays = None
        else:
            for k, v in enumerate(new_delays):
                try:
                    new_delays[k] = float(v)
                except ValueError:
                    new_delays[k] = -1
        self.reader.delays = new_delays

    @QtCore.pyqtSlot()
    def accept(self):
        if self.apply():
            self.close()

    def apply(self):
        # default row for x is the first row, it will be superseded if an integer number is given.

        try:
            x = [int(self.x_lineedit.text())-1]
        except ValueError:
            x = None
        try:
            y = [int(t)-1 for t in str(self.y_lineedit.text()).split(' ')]
        except ValueError:
            y = None
        try:
            y_err = [int(t)-1 for t in str(self.deltay_lineEdit.text()).split(' ')]
        except ValueError:
            y_err = None

        ret_dic = self.reader.export(xidx=x, yidx=y, yerridx=y_err,
                                     mode=self.buttonGroup.checkedButton().text())

        self.data_read.emit(ret_dic)

        return True

    @staticmethod
    def _update_dic(key, value, old_dic):
        old_dic_keys = list(old_dic.keys())
        if key in old_dic_keys:
            counter = 0
            replace_key = key + str(counter)
            while replace_key in old_dic_keys:
                counter += 1
                replace_key = key + str(counter)
        else:
            replace_key = key
        old_dic[replace_key] = value

    @QtCore.pyqtSlot(int, name='on_buttonGroup_buttonClicked')
    def show_error(self, val):
        if val == -2:
            self.widget.show()
        else:
            self.deltay_lineEdit.setText('')
            self.widget.hide()

    @QtCore.pyqtSlot(int, name='on_skippy_checkbox_stateChanged')
    def skip_next_dial(self, _):
        QAsciiReader.skip = self.skippy_checkbox.isChecked()
