#!/usr/bin/python3
import os
import subprocess
import sys

from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QApplication, QWidget, QGridLayout, QMainWindow, QPushButton, QCheckBox, QMessageBox


class MyWindow(QMainWindow):

    def alert(self, message):
        dlg = QMessageBox()
        dlg.setWindowTitle('Внимание!')
        dlg.setText(message)
        dlg.exec()

    def remove_driver(self):
        run_command = subprocess.run('pkexec dnf remove -y x11-driver-input-libinput',
                                     shell=True, capture_output=True)
        if run_command.returncode == 0:
            dlg = QMessageBox()
            dlg.setWindowTitle('Внимание!')
            dlg.setText('Драйвер удалён успешно. Для продолжения калибровки необходимо перезапустить компьютер. '
                        'Выполнить перезагрузку сейчас?')
            dlg.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)
            if dlg.exec() == QMessageBox.Ok:
                subprocess.run('reboot', shell=True)
        else:
            self.alert(f'Возникла ошибка: {run_command.stdout.decode()}')

    def run_calibrator(self):
        misclick_addition = '' if not self.misclick_disable_required else ' --misclick 0'
        run_command = subprocess.run(f'xinput_calibrator --output-type xorg.conf.d{misclick_addition} 2>&1',
                                     shell=True, capture_output=True)
        if run_command.returncode != 0:
            self.alert(run_command.stdout.decode())
        else:
            res = run_command.stdout.decode()
            if 'Section "InputClass"' in res:
                self.calibration_output = res
                self.save_res_button.setEnabled(True)
                self.save_res_button.setToolTip('')
                dlg = QMessageBox()
                dlg.setWindowTitle('Внимание!')
                dlg.setText('Калибровка завершилась успешно. '
                            'Сохранить результат в /etc/X11/xorg.conf.d/99-calibration.conf?')
                dlg.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)
                if dlg.exec() == QMessageBox.Ok:
                    self.save_result()
            else:
                self.alert(f'Калибровка завершилась неудачно.\nСообщение калибратора: {res}')

    def checkbox_changed(self):
        self.misclick_disable_required = self.misclick_checkbox.isChecked()

    def save_result(self):
        self.calibration_output = self.calibration_output.split('\n')
        start, end = -1, -1
        for i in range(len(self.calibration_output)):
            if 'Section "InputClass"' in self.calibration_output[i]:
                start = i
            if 'EndSection' in self.calibration_output[i]:
                end = i
        if start != -1 and end != -1:
            self.calibration_output = ''.join(self.calibration_output[start:end + 1])
            temp_file = subprocess.run('mktemp', shell=True, capture_output=True).stdout.decode().strip()
            print(*self.calibration_output, file=open(temp_file, 'w'))
            run_command = subprocess.run(f'pkexec bash -c "cat {temp_file}>>/etc/X11/xorg.conf.d/99-calibration.conf"',
                                         shell=True, capture_output=True)
            if run_command.returncode == 0:
                self.alert('Настройки успешно сохранены.')
            else:
                self.alert(f'Не удалось сохранить настройки.\nСообщение об ошибке: {run_command.stdout.decode()}')
            os.remove(temp_file)

    def __init__(self):
        QMainWindow.__init__(self)
        self.misclick_disable_required = False
        self.calibration_output = ''
        self.initUI()

    def initUI(self):
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        grid = QGridLayout()
        central_widget.setLayout(grid)

        remove_driver_button = QPushButton('Удалить x11-driver-input-libinput')
        remove_driver_button.clicked.connect(self.remove_driver)
        if subprocess.run('rpm -q x11-driver-input-libinput', shell=True).returncode != 0:
            remove_driver_button.setDisabled(True)
            remove_driver_button.setToolTip('x11-driver-input-libinput уже удалён')
        grid.addWidget(remove_driver_button, 0, 0)

        calibrate_button = QPushButton('Запустить калибровку')
        calibrate_button.clicked.connect(self.run_calibrator)
        grid.addWidget(calibrate_button, 1, 0)

        self.misclick_checkbox = QCheckBox('Отключить misclick')
        self.misclick_checkbox.stateChanged.connect(self.checkbox_changed)
        grid.addWidget(self.misclick_checkbox, 2, 0)

        self.save_res_button = QPushButton('Записать результат в /etc/X11/xorg.conf.d/99-calibration.conf')
        self.save_res_button.clicked.connect(self.save_result)
        self.save_res_button.setEnabled(False)
        self.save_res_button.setToolTip('Сначала необходимо выполнить калибровку')
        grid.addWidget(self.save_res_button, 3, 0)

        self.setGeometry(50, 50, 300, 100)
        self.setWindowTitle("Калибровка сенсорного экрана")
        self.setWindowIcon(QIcon(QIcon.fromTheme('xinput-calibrator-gui')))
        self.show()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MyWindow()
    sys.exit(app.exec_())
