import sys
from PySide6.QtWidgets import *


class MainWindow(QMainWindow):

    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setWindowTitle("Cliffhanger")

        # Add widgets, the first one being the file list widget given for the exercise
        self.file_selection = QPushButton("Ouvrir...")
        self.file_selected = QLabel("")

        layout_line1 = QHBoxLayout()
        layout_line1.addWidget(self.file_selection)
        layout_line1.addWidget(self.file_selected)

        self.label_height = QLabel("Hauteur à laquelle l'impression s'est arrêtée (en mm)")
        self.print_height = QLineEdit("", self)

        layout_line2 = QHBoxLayout()
        layout_line2.addWidget(self.label_height)
        layout_line2.addWidget(self.print_height)

        self.button_start = QPushButton("Récupérer mon impression !")

        layout = QVBoxLayout()
        layout.addLayout(layout_line1)
        layout.addLayout(layout_line2)
        layout.addWidget(self.button_start)

        central_widget = QWidget()
        central_widget.setLayout(layout)
        self.setCentralWidget(central_widget)

        # Launch function when button is clicked
        self.file_selection.clicked.connect(self.select_file)
        self.button_start.clicked.connect(self.save_my_print)

    def select_file(self):
        file_dialog = QFileDialog(self)
        file_dialog.setFileMode(QFileDialog.FileMode.ExistingFile)

        # getOpenFileNames returns 2 elements, the file name and the filter, we only want the name
        file_name = file_dialog.getOpenFileName(self, "Sélectionner le fichier GCode...", "", "*.gcode")[0]

        self.file_selected.setText(file_name)

    def save_my_print(self):
        src_file_path = self.file_selected.text()
        src_file = open(src_file_path, "r")

        # Create the output file
        output_file_name = src_file_path.split(".gcode")[0] + "-recup.gcode"
        output_file = open(output_file_name, "w")

        stage1 = False
        stage2 = False
        write_line = True
        print_height = float(self.print_height.text())
        current_height = 0.0
        layer_height = 0.0
        previous_extrusion = 0.0
        current_extrusion = 0.0
        next_extrusion = 0.0
        firstloop = True

        # Go through each line of each file
        for line in src_file:
            newline = ""

            if stage2 & line.startswith("G1"):
                instructions = line.split(" ")

                for instruction in instructions:
                    if instruction.startswith("E"):
                        current_extrusion = float(instruction.split("E")[1])

                        if firstloop:
                            previous_extrusion = current_extrusion
                            firstloop = False

                        next_extrusion = next_extrusion + current_extrusion - previous_extrusion
                        next_extrusion = round(next_extrusion, 4)
                        previous_extrusion = current_extrusion

                        newline += "E" + str(next_extrusion) + "\n"
                    else:
                        newline += instruction + " "
            else:
                newline = line

            if write_line:
                output_file.write(newline)

            if line.startswith("M1001"):
                stage1 = True
                write_line = False

            if stage1 & line.startswith(";Z:"):
                current_height = float(line.split(":")[1])

            if (not stage2) & (print_height <= (current_height - layer_height)):
                stage2 = True
                write_line = True

            if stage1 & line.startswith(";HEIGHT:"):
                layer_height = float(line.split(":")[1])

        src_file.close()
        output_file.write("\n")
        output_file.close()

        # Notify the user and clear the list
        QMessageBox.information(self, "Information", "Nouveau fichier créé avec succès !")


def main():
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec())


if __name__ == '__main__':
    main()