from PySide6 import QtCore, QtWidgets, QtGui
import plots
import PIL
import pandas as pd
import fitting


# Значения параметра part при построении графиков установлены на тестовый режим
class TitleScreen(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.q = QtGui.QScreen.availableGeometry(QtWidgets.QApplication.primaryScreen())
        self.part1 = Part1()
        self.part2 = Part2()

        self.button = QtWidgets.QPushButton(self)
        self.button.setGeometry(QtCore.QRect(20, 20, 40, 40))
        self.button.setText("Esc")
        self.text = QtWidgets.QLabel(self)
        self.text.setText(
            "<html><head/><body><p align=\"center\"><span style=\" font-size:20pt; font-weight:600;\">Лабораторная "
            "работа 3.5.1</span></p><p align=\"center\"><span style=\" font-size:16pt;\">Исследование плазмы газового "
            "разряда</span></p></body></html>")
        self.text.setGeometry(QtCore.QRect(self.q.width() // 3 - 250, self.q.height() // 2 - 50, 500, 100))
        self.vline = QtWidgets.QFrame(self)
        self.vline.setFrameShape(QtWidgets.QFrame.VLine)
        self.vline.setGeometry(QtCore.QRect(2 * self.q.width() // 3, 0, 10, self.q.height() + 40))
        self.hline = QtWidgets.QFrame(self)
        self.hline.setFrameShape(QtWidgets.QFrame.HLine)
        self.hline.setGeometry(QtCore.QRect(2 * self.q.width() // 3 + 5, self.q.height() // 2, self.q.width() // 3, 40))
        self.label1 = QtWidgets.QLabel(self)
        self.label1.setText(
            "<html><head/><body><p align=\"center\"><span style=\" font-size:10pt; font-weight:600;\">ЧАСТЬ "
            "I</span></p><p align=\"center\"><span style=\" font-size:10pt;\">Вольт-амперная характеристика газового "
            "разряда</span></p></body></html>")
        self.label1.setGeometry(QtCore.QRect(5 * self.q.width() // 6 - 150, self.q.height() // 4 - 40, 300, 80))
        self.label2 = QtWidgets.QLabel(self)
        self.label2.setText(
            "<html><head/><body><p align=\"center\"><span style=\" font-size:10pt; font-weight:600;\"> ЧАСТЬ "
            "II</span></p><p align=\"center\"><span style=\" font-size:10pt;\">Зондовые характеристики "
            "плазмы</span></p></body></html>")
        self.label2.setGeometry(QtCore.QRect(5 * self.q.width() // 6 - 150, 3 * self.q.height() // 4 - 40, 300, 80))
        self.button1 = QtWidgets.QPushButton(self)
        self.button1.setGeometry(QtCore.QRect(5 * self.q.width() // 6 - 40, self.q.height() // 4 + 80, 80, 40))
        self.button1.setText("Начать")
        self.button2 = QtWidgets.QPushButton(self)
        self.button2.setGeometry(QtCore.QRect(5 * self.q.width() // 6 - 40, 3 * self.q.height() // 4 + 80, 80, 40))
        self.button2.setText("Начать")

        self.button.clicked.connect(self.esc)
        self.button1.clicked.connect(self.open_part1)
        self.button2.clicked.connect(self.open_part2)

    @QtCore.Slot()
    def esc(self):
        self.close()

    def open_part1(self):
        self.part1.showFullScreen()
        self.close()

    def open_part2(self):
        self.part2.showFullScreen()
        self.close()


class Part1(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.n = 0
        self.hint_open = False
        self.started = False
        self.q = QtGui.QScreen.availableGeometry(QtWidgets.QApplication.primaryScreen())
        h = self.q.height() * 0.2
        plots.empty_plot(3)

        self.points = QtWidgets.QLabel(self)
        self.points.setGeometry(QtCore.QRect(7.5 * h - 60, 3 * h - 80, 140, 20))
        self.points.setText('Измеренных точек: ' + str(self.n))

        self.disclaimer = QtWidgets.QLabel(self)
        self.disclaimer.setText('<html><p align=\"left\"><span style=\" font-size:10pt; font-weight:600;\">Не '
                                'забудьте прочитать методику<\p><p align=\"left\"><span style=\" font-size:10pt; '
                                'font-weight:600;\">и подсказку выше перед началом работы!<\p><\html>')
        self.disclaimer.setGeometry(7.5 * h - 150, h, 400, 100)

        self.button = QtWidgets.QPushButton(self)
        self.button.setGeometry(QtCore.QRect(20, 20, 40, 40))
        self.button.setText("Esc")

        self.start_btn = QtWidgets.QPushButton(self)
        self.start_btn.setText("Начать измерения")
        self.start_btn.setGeometry(QtCore.QRect(7.5 * h - 150, 3 * h - 50, 120, 30))

        self.reset_btn = QtWidgets.QPushButton(self)
        self.reset_btn.setText("Сбросить")
        self.reset_btn.setGeometry(QtCore.QRect(7.5 * h + 30, 3 * h - 50, 120, 30))

        self.save_plot_btn = QtWidgets.QPushButton(self)
        self.save_plot_btn.setText("Сохранить \n график")
        self.save_plot_btn.setGeometry(QtCore.QRect(7.5 * h - 150, 3 * h, 120, 70))
        self.save_plot_btn.hide()

        self.save_values_btn = QtWidgets.QPushButton(self)
        self.save_values_btn.setText("Сохранить \n данные")
        self.save_values_btn.setGeometry(QtCore.QRect(7.5 * h + 30, 3 * h, 120, 70))
        self.save_values_btn.hide()

        self.title = QtWidgets.QLabel(self)
        self.title.setText(
            "<html><head/><body><p align=\"center\"><span style=\" font-size:16pt; font-weight:600;\">ЧАСТЬ "
            "I</span></p><p align=\"center\"><span style=\" font-size:12pt;\">Вольт-амперная характеристика газового "
            "разряда</span></p></body></html>")
        self.title.setGeometry(QtCore.QRect(self.q.width() // 2 - 200, 20, 400, 80))

        self.back_button = QtWidgets.QPushButton(self)
        self.back_button.setGeometry(QtCore.QRect(20, self.q.height() - 20, 80, 40))
        self.back_button.setText("Назад")

        self.pixmap0 = QtGui.QPixmap('tmpplots/tmpplot1.jpg')
        self.pixmap = self.pixmap0.scaledToHeight(3 * h)
        self.plot1 = QtWidgets.QLabel(self)
        self.plot1.setPixmap(self.pixmap)
        self.plot1.setGeometry(QtCore.QRect(h, h + 20, 4 * h, 3 * h))

        self.text = QtWidgets.QLabel(self)
        self.text.setText("<html><p align=\"left\"><span style=\" font-size:10pt;\">Перед проведением измерений ВАХ "
                          "газового разряда</p><p align=\"left\"><span style=\" font-size:10pt;\">проверьте "
                          "подключение вольтметра V<sub>1</sub> и амперметра A<sub>1</sub>,"
                          "</p><p align=\"left\"><span style=\" font-size:10pt;\">а также убедитесь, "
                          "что переключатель П<sub>1</sub> находится в положении I.</p><p align=\"left\"><span "
                          "style=\" font-size:10pt;\">При проведении измерений медленно увеличивайте выходное"
                          "</p><p align=\"left\"><span style=\" font-size:10pt;\">напряжение ВИП до достижения "
                          "максимального значения тока"
                          "</p><p align=\"left\"><span style=\" font-size:10pt;\">через амперметр "
                          "А<sub>1&nbsp;</sub>(не более 5 мА), затем проведите измерения "
                          "</p><p align=\"left\"><span style=\" font-size:10pt;\">в обратную сторону.</p><p "
                          "align=\"left\"><span style=\" font-size:10pt;\">График "
                          "I<sub>р</sub>(U<sub>р</sub>) будет строиться автоматически,</p><p align=\"left\"><span "
                          "style=\" font-size:10pt;\">после завершения измерений можно сохранить полученные</p><p "
                          "align=\"left\"><span style=\" font-size:10pt;\">значения "
                          "и график.</p></html>")
        self.text.setGeometry(QtCore.QRect(6 * h, h + 20, 3 * h, 2 * h + 20))
        self.text.setStyleSheet("border: 1px solid black; background-color: white;")
        self.text.hide()

        self.hint_btn = QtWidgets.QPushButton(self)
        self.hint_btn.setText('?')
        self.hint_btn.setGeometry(QtCore.QRect(self.q.width() - 60, 20, 40, 40))

        self.button.clicked.connect(self.esc)
        self.back_button.clicked.connect(self.back)
        self.start_btn.clicked.connect(self.start_stop)
        self.reset_btn.clicked.connect(self.reset)
        self.hint_btn.clicked.connect(self.hint)
        self.save_plot_btn.clicked.connect(self.save_plot)
        self.save_values_btn.clicked.connect(self.save_values)

        timer = QtCore.QTimer(self)
        timer.timeout.connect(self.upd_plot)
        timer.start(500)

    @QtCore.Slot()
    def save_plot(self):
        # при замене устройства директорию надо изменить
        file, check = QtWidgets.QFileDialog.getSaveFileName(None, "Сохранить график 1",
                                                            r"C:\Users\Vadim\Desktop\plot1.jpg", "Images (*.png *.jpg)")
        if check:
            plot1 = PIL.Image.open('tmpplots/tmpplot3.jpg')
            plot1.save(file)

    def save_values(self):
        # при замене устройства директорию надо изменить
        file, check = QtWidgets.QFileDialog.getSaveFileName(None, "Сохранить значения",
                                                            r"C:\Users\Vadim\Desktop\experiment1.xlsx", "Table (.xlsx)")
        if check:
            data = {'U_р, В': plots.vol[2][0], 'I_р, мА': plots.cur[2][0]}
            df = pd.DataFrame(data)
            df.to_excel(file, index=False)

    def hint(self):
        if not self.hint_open:
            self.text.show()
            self.hint_open = True
        else:
            self.text.hide()
            self.hint_open = False

    def esc(self):
        self.close()

    def back(self):
        self.w = TitleScreen()
        self.w.showFullScreen()
        self.close()

    def show_plot(self):
        self.points.setText('Измеренных точек: ' + str(self.n))
        self.pixmap0 = QtGui.QPixmap('tmpplots/tmpplot3.jpg')
        self.pixmap = self.pixmap0.scaledToHeight(0.6 * self.q.height())
        self.plot1.setPixmap(self.pixmap)

    def upd_plot(self):
        if self.started:
            plots.update_plot(3, 0)
            plots.saveplot(3)
            self.n += 10
            self.show_plot()

    def start_stop(self):
        if not self.started:
            self.start_btn.setText("Стоп")
            self.started = True
            self.save_plot_btn.hide()
            self.save_values_btn.hide()
            self.hint_btn.hide()

        else:
            self.start_btn.setText("Продолжить")
            self.started = False
            self.save_plot_btn.show()
            self.save_values_btn.show()
            self.hint_btn.show()

    def reset(self):
        self.started = False
        self.start_btn.setText("Начать измерения")
        self.save_plot_btn.hide()
        self.save_values_btn.hide()
        self.hint_btn.show()
        self.n = 0
        plots.empty_plot(3)
        self.show_plot()


class Part2(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.n = 0
        self.num = 0
        self.i = 0
        self.hint_open = False
        self.started = False
        self.q = QtGui.QScreen.availableGeometry(QtWidgets.QApplication.primaryScreen())
        h = self.q.height() * 0.2
        plots.empty_plot(4)

        self.button = QtWidgets.QPushButton(self)
        self.button.setGeometry(QtCore.QRect(20, 20, 40, 40))
        self.button.setText("Esc")

        self.points = QtWidgets.QLabel(self)
        self.points.setGeometry(QtCore.QRect(7.5 * h - 150, 3 * h - 80, 300, 20))
        self.points.setText('Измеренных точек в текущей серии: ' + str(self.n))

        self.current = QtWidgets.QLabel(self)
        self.current.setGeometry(QtCore.QRect(7.5 * h - 150, 3 * h - 120, 300, 20))
        self.current.setText('Текущий ток разряда: ' + str(self.i))
        self.current.setStyleSheet('color: green;')

        self.disclaimer = QtWidgets.QLabel(self)
        self.disclaimer.setText('<html><p align=\"left\"><span style=\" font-size:10pt; font-weight:600;\">Не '
                                'забудьте прочитать методику<\p><p align=\"left\"><span style=\" font-size:10pt; '
                                'font-weight:600;\">и подсказку выше перед началом работы!<\p><\html>')
        self.disclaimer.setGeometry(7.5 * h - 150, h, 400, 100)

        self.title = QtWidgets.QLabel(self)
        self.title.setText(
            "<html><head/><body><p align=\"center\"><span style=\" font-size:16pt; font-weight:600;\"> ЧАСТЬ "
            "II</span></p><p align=\"center\"><span style=\" font-size:12pt;\">Зондовые характеристики "
            "плазмы</span></p></body></html>")
        self.title.setGeometry(QtCore.QRect(self.q.width() // 2 - 200, 20, 400, 80))

        self.back_button = QtWidgets.QPushButton(self)
        self.back_button.setGeometry(QtCore.QRect(20, self.q.height() - 20, 80, 40))
        self.back_button.setText("Назад")

        self.start_btn = QtWidgets.QPushButton(self)
        self.start_btn.setText("Добавить серию")
        self.start_btn.setGeometry(QtCore.QRect(7.5 * h - 150, 3 * h - 50, 120, 30))

        self.delete_btn = QtWidgets.QPushButton(self)
        self.delete_btn.setText("Удалить серию")
        self.delete_btn.setGeometry(QtCore.QRect(7.5 * h + 30, 3 * h - 50, 120, 30))
        self.delete_btn.hide()

        self.save_plot_btn = QtWidgets.QPushButton(self)
        self.save_plot_btn.setText("Сохранить \n график")
        self.save_plot_btn.setGeometry(QtCore.QRect(7.5 * h - 150, 3 * h, 120, 70))
        self.save_plot_btn.hide()

        self.save_values_btn = QtWidgets.QPushButton(self)
        self.save_values_btn.setText("Сохранить \n данные")
        self.save_values_btn.setGeometry(QtCore.QRect(7.5 * h + 30, 3 * h, 120, 70))
        self.save_values_btn.hide()

        self.hint_btn = QtWidgets.QPushButton(self)
        self.hint_btn.setText('?')
        self.hint_btn.setGeometry(QtCore.QRect(self.q.width() - 60, 20, 40, 40))

        self.pixmap0 = QtGui.QPixmap('tmpplots/tmpplot4.jpg')
        self.pixmap = self.pixmap0.scaledToHeight(3 * h)
        self.plot1 = QtWidgets.QLabel(self)
        self.plot1.setPixmap(self.pixmap)
        self.plot1.setGeometry(QtCore.QRect(h, h + 20, 4 * h, 3 * h))

        self.text = QtWidgets.QLabel(self)
        self.text.setText("<html><p align=\"left\"><span style=\" font-size:10pt;\">Перед проведением измерений "
                          "зондовых характеристик</p><p align=\"left\"><span style=\" font-size:10pt;\">плазмы "
                          "проверьте подключение вольтметра V<sub>2</sub></p><p align=\"left\"><span style=\" "
                          "font-size:10pt;\">и амперметров A<sub>1&nbsp;</sub>и А<sub>2</sub>, а также убедитесь,"
                          "</p><p align=\"left\"><span style=\" font-size:10pt\";>что переключатель П<sub>1</sub> "
                          "находится в положении II.</p><p align=\"left\"><span style=\" font-size:10pt;\">Установите "
                          "требуемый согласно методике разрядный ток,</p><p align=\"left\"><span style=\" "
                          "font-size:10pt\";>не изменяйте его в момент проведения серии измерений.</p><p "
                          "align=\"left\"><span style=\" font-size:10pt;\">При помощи потенциометра измерьте "
                          "ВАХ</p><p align=\"left\"><span style=\" font-size:10pt;\">в максимальном диапазоне, "
                          "учтите,</p><p align=\"left\"><span style=\" font-size:10pt;\">что полярность можно менять "
                          "с помощью</p><p align=\"left\"><span style=\" font-size:10pt;\">переключателя "
                          "П<sub>2</sub> только при токе I<sub>з</sub>= 0.</p><p align=\"left\"><span style=\" "
                          "font-size:10pt;\">График I<sub>з</sub>(U<sub>з</sub>) будет строиться автоматически,"
                          "</p><p align=\"left\"><span style=\" font-size:10pt;\">после завершения всех серий "
                          "измерений</p><p align=\"left\"><span style=\" font-size:10pt;\">можно сохранить полученные "
                          "значения и график.</p></html>")
        self.text.setGeometry(QtCore.QRect(6 * h, h + 20, 3 * h, 2 * h + 20))
        self.text.setStyleSheet("border: 1px solid black; background-color: white;")
        self.text.hide()

        self.button.clicked.connect(self.esc)
        self.back_button.clicked.connect(self.back)
        self.start_btn.clicked.connect(self.start_stop)
        self.delete_btn.clicked.connect(self.delete)
        self.hint_btn.clicked.connect(self.hint)
        self.save_plot_btn.clicked.connect(self.save_plot)
        self.save_values_btn.clicked.connect(self.save_values)

        timer = QtCore.QTimer(self)
        timer.timeout.connect(self.upd_plot)
        timer.start(500)

        timer2 = QtCore.QTimer(self)
        timer2.timeout.connect(self.cur_check)
        timer2.start(1000)

    @QtCore.Slot()
    def cur_check(self):
        if plots.experiment % 3 == 0:
            self.i = 5
        elif plots.experiment % 3 == 1:
            self.i = 3
        else:
            self.i = 1.5
        self.current.setText('Текущий ток разряда: ' + str(self.i) + 'мА')

    def save_plot(self):
        # при замене устройства директорию надо изменить
        file, check = QtWidgets.QFileDialog.getSaveFileName(None, "Сохранить график 2",
                                                            r"C:\Users\Vadim\Desktop\plot2.jpg", "Images (*.png *.jpg)")
        if check:
            plot1 = PIL.Image.open('tmpplots/tmpplot4.jpg')
            plot1.save(file)

    def save_values(self):
        # при замене устройства директорию надо изменить
        file, check = QtWidgets.QFileDialog.getSaveFileName(None, "Сохранить значения",
                                                            r"C:\Users\Vadim\Desktop\experiment2.xlsx", "Table (.xlsx)")
        if check:
            data = {'U_1, В': plots.vol[3][0], 'I_1, мкА': plots.cur[3][0]}
            I_0, k_0, A = [], [], []
            params = fitting.fit(plots.vol[3][0], plots.cur[3][0])
            I_0.append(params[0])
            k_0.append(params[1])
            A.append(params[2])
            for i in range(len(plots.vol[3]) - 1):
                mes = {'U_' + str(i+2) + ', В': plots.vol[3][i + 1], 'I_' + str(i + 2) + ', мкА': plots.cur[3][i + 1]}
                data.update(mes)
                params = fitting.fit(plots.vol[3][i + 1], plots.cur[3][i + 1])
                I_0.append(params[0])
                k_0.append(params[1])
                A.append(params[2])

            data.update({'I_0, мкА': I_0, 'k_0, мкА/В': k_0, 'A, мкА/В': A})

            df = pd.DataFrame(dict([(k, pd.Series(v)) for k, v in data.items()]))
            df.to_excel(file, index=False)

    def hint(self):
        if not self.hint_open:
            self.text.show()
            self.hint_open = True
        else:
            self.text.hide()
            self.hint_open = False

    def esc(self):
        self.close()

    def back(self):
        self.w = TitleScreen()
        self.w.showFullScreen()
        self.close()

    def show_plot(self):
        self.points.setText('Измеренных точек в текущей серии: ' + str(self.n))
        self.pixmap0 = QtGui.QPixmap('tmpplots/tmpplot4.jpg')
        self.pixmap = self.pixmap0.scaledToHeight(0.6 * self.q.height())
        self.plot1.setPixmap(self.pixmap)

    def upd_plot(self):
        if self.started:
            plots.update_plot(4, self.num - 1)
            plots.saveplot(4)
            self.n += 10
            self.show_plot()

    def start_stop(self):
        if not self.started:
            self.start_btn.setText("Стоп")
            self.started = True
            self.save_plot_btn.hide()
            self.save_values_btn.hide()
            self.hint_btn.hide()
            if self.num != 0:
                plots.plus_plot(4)
            self.num += 1
            self.n = 0

        else:
            self.start_btn.setText("Добавить серию")
            self.started = False
            self.save_plot_btn.show()
            self.save_values_btn.show()
            self.hint_btn.show()
            self.delete_btn.show()

    def delete(self):
        self.started = False
        self.start_btn.setText("Добавить серию")
        self.save_plot_btn.hide()
        self.save_values_btn.hide()
        self.hint_btn.show()
        self.n = 0
        plots.minus_plot(4)
        plots.saveplot(4)
        self.show_plot()
        self.num -= 1
        if self.num == 0:
            self.save_plot_btn.hide()
            self.save_values_btn.hide()
            self.delete_btn.hide()
