import os
from PyQt5 import QtWidgets
from PyQt5.QtCore import QThread, pyqtSignal, QObject
from PyQt5.QtWidgets import QFileDialog
from utils.files.input import ScannedObject
from utils.gui.pyqt.main_window.UI_MainWindow import Ui_MainWindow
from utils.gui.pyqt.main_window.Workers.AnalyseWorker import AnalyseWorker
from utils.gui.pyqt.main_window.Canvas.Mesh3DCanvas import Mesh3DCanvas
from utils.gui.pyqt.main_window.Canvas.CrossSection2DCanvas import CrossSection2DCanvas
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    """
    Main window of the application
    """

    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        # Retrieve the UI
        self.setupUi(self)
        # Setup buttons listeners
        self.start_analyse_button.clicked.connect(self.start_analyse)
        self.input_file_choose_btn.clicked.connect(self.select_file)
        self.output_folder_choose_btn.clicked.connect(self.select_folder)
        #CanvasWrapper(ScannedObject.from_obj_file("/Users/djalim/Documents/DevStuff/AnalyseMorphologique/datasets/Barette/1 - BARETTE.obj")).canvas.native
        self.completed = 0

    def select_file(self):
        """
        Open a file dialog to select the input file
        """
        file = QFileDialog.getOpenFileName()[0]
        self.input_file_path.setPlainText(file)
        self.output_file_prefix.setText(os.path.splitext(os.path.basename(file))[0])

    def select_folder(self):
        """
        Open a file dialog to select the output folder
        """
        self.output_folder_path.setPlainText(
            QFileDialog.getExistingDirectory())

    def start_analyse(self):
        """
        Start the analyse
        """
        if not self.check_input_file():
            self.input_file_path.setPlainText("Invalid file path")
            return
        if not self.check_output_folder():
            self.output_folder_path.setPlainText("Invalid folder path")
            return

        # Create the thread to run the analyse
        self.thread = QThread()
        self.worker = AnalyseWorker(self.input_file_path.toPlainText(),
                             self.output_folder_path.toPlainText(),
                             self.output_file_prefix.text(),
                             self.discretisation_value_selector.value())
        self.worker.moveToThread(self.thread)

        # Connect the signals
        # Start
        self.thread.started.connect(self.worker.run)
        # Progress
        self.worker.status.connect(self.set_status)
        self.worker.progress.connect(self.update_progress_bar)
        self.worker.render.connect(self.show_graph)
        # Finished
        self.worker.finished.connect(self.finish_analyse)
        self.worker.finished.connect(self.thread.quit)
        self.worker.finished.connect(self.worker.deleteLater)
        self.thread.finished.connect(self.thread.deleteLater)

        # Start the thread
        self.thread.start()
        self.start_analyse_button.setEnabled(False)

    def set_status(self, status:str):
        """
        Set the status of the analyse
        """
        self.status_text.setText(status)

    def show_graph(self, obj:ScannedObject):
        """
        Show the graph
        """
        if not self.show_graph_checkbox.checked:
            return
        self.slot0.addWidget(Mesh3DCanvas(obj).canvas.native)
        self.slot1.addWidget(CrossSection2DCanvas(obj.get_x(),obj.get_z(),"Coupe X").canvas.native)
        self.slot2.addWidget(CrossSection2DCanvas(obj.get_y(),obj.get_z(),"Coupe Y").canvas.native)

    def finish_analyse(self):
        """
        Finish the analyse
        """
        self.start_analyse_button.setEnabled(True)


    def check_input_file(self):
        """
        Check if the input file is valid
        """
        if os.path.isfile(self.input_file_path.toPlainText()):
            return True

    def check_output_folder(self):
        """
        Check if the output folder is valid
        """
        if os.path.isdir(self.output_folder_path.toPlainText()):
            return True

    def update_progress_bar(self, value):
        """
        Update the progress bar
        """
        self.analyse_progress_bar.setValue(value)