from ..Qt import QtCore, QtWidgets, QtGui
from .._py.eval_expr_dialog import Ui_CalcDialog


class QEvalDialog(QtWidgets.QDialog, Ui_CalcDialog):
    do_eval = QtCore.pyqtSignal(list, list, bool)
    do_calc = QtCore.pyqtSignal(list, dict)

    def __init__(self, mode='c', parent=None):
        super().__init__(parent=parent)
        self.setupUi(self)
        self.namespace = None
        self.success = True

        self.set_mode(mode)

        self.value_lineEdit.setValidator(QtGui.QDoubleValidator())

    def set_mode(self, mode: str):
        if mode not in ['c', 'e']:
            raise ValueError(f'Mode should be "c" or "e", {mode} given')

        if mode == 'c':
            self.stackedWidget.setCurrentIndex(1)
        else:
            self.stackedWidget.setCurrentIndex(0)
        self.mode = mode

    def set_namespace(self, namespace):
        self.namespace = namespace
        self.namespace_widget.set_namespace(self.namespace)

    def add_data(self, data):
        self.listWidget.clear()
        for set_id, name in data:
            item = QtWidgets.QListWidgetItem(name)
            item.setData(QtCore.Qt.UserRole, set_id)
            item.setFlags(item.flags() ^ QtCore.Qt.ItemIsEditable)
            item.setCheckState(QtCore.Qt.Checked)
            self.listWidget.addItem(item)

    def set_graphs(self, graphs: list):
        self.graph_comboBox.clear()
        self.graph_comboBox.addItem('New graph', userData='')
        for g_id, g_name in graphs:
            self.graph_comboBox.addItem(g_name, userData=g_id)

    @QtCore.pyqtSlot(str, name='on_namespace_widget_selected')
    def add_to_equation(self, string: str):
        self.calc_edit.insertPlainText(string + ' ')

    def on_buttonBox_clicked(self, bttn):
        bttn_role = self.buttonBox.buttonRole(bttn)
        if bttn_role == QtWidgets.QDialogButtonBox.ApplyRole:
            self.collect_args()

        elif bttn_role == QtWidgets.QDialogButtonBox.AcceptRole:
            self.collect_args()
            if self.success:
                self.accept()

        else:
            self.reject()

    def collect_args(self):
        cmds = self.calc_edit.toPlainText().strip().split('\n')
        if cmds[-1] == '':
            # remove last empty line to check
            cmds.pop()

        if cmds:
            if self.mode == 'e':
                set_id = []
                for i in range(self.listWidget.count()):
                    item = self.listWidget.item(i)
                    if item.checkState() == QtCore.Qt.Checked:
                        set_id.append(item.data(QtCore.Qt.UserRole))

                self.do_eval.emit(cmds, set_id, self.overwrite_checkbox.isChecked())

            elif self.mode == 'c':
                opts = {
                    'symbol': self.symbol_comboBox.value,
                    'symbolcolor': self.symcolor_comboBox.value,
                    'symbolsize': self.symbol_spinBox.value(),

                    'linestyle': self.linestyle_comboBox.value,
                    'linecolor': self.linecolor_comboBox.value,
                    'linewidth': self.line_doubleSpinBox.value(),

                    'graph': self.graph_comboBox.currentData(),
                    'dtype': self.dtype_comboBox.currentIndex(),
                    'name': self.label_lineEdit.text(),
                    'val': self.value_lineEdit.text()
                }

                self.do_calc.emit(cmds, opts)

            else:
                # keine Ahnung, warum man hier landen sollte ...
                self.success = False
