from nmreval.lib.lines import LineStyle
from nmreval.lib.symbols import SymbolStyle
from nmreval.data.points import Points
from nmreval.io.graceeditor import GraceEditor

from ..Qt import QtCore, QtWidgets, QtGui
from .._py.gracereader import Ui_Dialog


class QGraceReader(QtWidgets.QDialog, Ui_Dialog):
    data_read = QtCore.pyqtSignal(list)
    file_ext = ['.agr']

    def __init__(self, parent=None):
        super().__init__(parent=parent)
        self.setupUi(self)
        self._reader = GraceEditor()
        self.treeWidget.itemClicked.connect(self.show_property)

        self.treeWidget.installEventFilter(self)

    def __call__(self, fname, *args, **kwargs):
        self.treeWidget.clear()
        self.show_property(self.treeWidget.invisibleRootItem(), 0)
        self.read(fname)

        return self

    def eventFilter(self, src: QtCore.QObject, evt: QtCore.QEvent):
        if evt.type() == QtCore.QEvent.KeyPress:
            if evt.key() == QtCore.Qt.Key_Space:
                iterator = QtWidgets.QTreeWidgetItemIterator(self.treeWidget)
                while iterator.value():
                    item = iterator.value()
                    if item.parent() is not None and item.isSelected():
                        item.setCheckState(0,
                                           QtCore.Qt.Checked if item.checkState(0) == QtCore.Qt.Unchecked else
                                           QtCore.Qt.Unchecked)

                    iterator += 1

                return True

        return super().eventFilter(src, evt)

    def read(self, fname):
        self._reader.parse(fname)

        for graphs in self._reader.graphs:
            item = QtWidgets.QTreeWidgetItem([f'Graph {graphs.idx} (Title "{graphs.get_property("title")}")'])
            for gset in graphs.set:
                ds = self._reader.dataset(graphs.idx, gset.idx)
                if ds is None:
                    continue

                item_2 = QtWidgets.QTreeWidgetItem([f'Set {gset.idx} (Label:  {gset.get_property("legend")}, '
                                                    f'shape: {ds.shape})'])
                item_2.setCheckState(0, QtCore.Qt.Checked)
                item_2.setData(0, QtCore.Qt.UserRole, (graphs.idx, gset.idx))
                item.addChild(item_2)

            self.treeWidget.addTopLevelItem(item)
        self.treeWidget.expandAll()

    @QtCore.pyqtSlot(QtWidgets.QTreeWidgetItem, int)
    def show_property(self, item: QtWidgets.QTreeWidgetItem, col: int):
        keys = item.data(col, QtCore.Qt.UserRole)
        if keys is not None:
            cols = self._reader.colors

            self.tableWidget.item(0, 1).setText(SymbolStyle(self._reader.get_property(*keys, 'symbol')).name)
            sym_col = cols[self._reader.get_property(*keys, 'symbol fill color')][1]
            self.tableWidget.item(1, 1).setBackground(QtGui.QBrush(QtGui.QColor(*sym_col)))

            self.tableWidget.item(2, 1).setText(LineStyle(self._reader.get_property(*keys, 'line linestyle')).name)

            line_col = cols[self._reader.get_property(*keys, 'line color')][1]
            self.tableWidget.item(3, 1).setBackground(QtGui.QBrush(QtGui.QColor(*line_col)))

    def accept(self):
        data = []
        iterator = QtWidgets.QTreeWidgetItemIterator(self.treeWidget,
                                                     QtWidgets.QTreeWidgetItemIterator.NoChildren |
                                                     QtWidgets.QTreeWidgetItemIterator.Checked)

        while iterator.value():
            item = iterator.value()
            key = (item.data(0, QtCore.Qt.UserRole))
            s = self._reader.dataset(*key)
            label = self._reader.get_property(*key, 'legend').replace('"', '')
            # label = self._reader.graphs[key[0]].sets[key[1]]['legend'].replace('"', '')
            sd = s.data
            if s.type == 'xydy':
                data.append(Points(x=sd[:, 0], y=sd[:, 1], y_err=sd[:, 2], name=label))
            else:
                data.append(Points(x=sd[:, 0], y=sd[:, 1], name=label))

            iterator += 1

        self.data_read.emit(data)

        self.close()

    def close(self):
        self._reader.clear()
        super().close()
