from nmreval.nmr.coupling import *
from nmreval.utils.text import convert

from ..Qt import QtWidgets, QtCore
from .._py.coupling_calculator import Ui_coupling_calc_dialog
from ..lib.forms import SelectionWidget, FormWidget


class QCoupCalcDialog(QtWidgets.QDialog, Ui_coupling_calc_dialog):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setupUi(self)

        self.cp = [Quadrupolar, Czjzek, HeteroDipolar, HomoDipolar]
        for cp in self.cp:
            self.comboBox.addItem(cp.name)

        self._coupling_parameter = []

        self.change_coupling(0)

    @QtCore.pyqtSlot(int, name='on_comboBox_currentIndexChanged')
    def change_coupling(self, idx):
        self.label_2.setText(convert(self.cp[idx].equation))
        coup = self.cp[idx]
        self._coupling_parameter = []

        while self.verticalLayout_2.count():
            item = self.verticalLayout_2.takeAt(0)
            try:
                item.widget().deleteLater()
            except AttributeError:
                pass

        max_size = 0
        if coup.parameter is not None:
            for p, u in zip(coup.parameter, coup.unit):
                if u:
                    _temp = FormWidget(parent=self, name=convert(p+' / '+u))
                else:
                    _temp = FormWidget(parent=self, name=convert(p))
                _temp.valueChanged.connect(lambda v: self.calc_coupling())
                size = _temp.label.sizeHint()
                max_size = max(max_size, size.width())
                self.verticalLayout_2.addWidget(_temp)
                self._coupling_parameter.append(_temp)

            for item in self._coupling_parameter:
                item.label.setFixedWidth(max_size)

        if coup.choice is not None:
            for c in self.cp[idx].choice:
                _temp = SelectionWidget(*c, parent=self)
                _temp.selectionChanged.connect(lambda name, value: self.calc_coupling())
                self.verticalLayout_2.addWidget(_temp)
                self._coupling_parameter.append(_temp)

        self.calc_coupling()

    def calc_coupling(self):
        p = []
        kw = {}
        for pp in self._coupling_parameter:
            if isinstance(pp, FormWidget):
                p.append(pp.value)
            else:
                kw.update(pp.value)

        self.label.setText('Coupling constant: %.8g' % self.cp[self.comboBox.currentIndex()].relax(*p))
