"""
Hauptfenster der Anwendung, enthält alle weiteren unter Module und erlaubt Zugriff auf diese. 
Übernimmt die Initialisierung der Anwendungsoberfläche und zeigt bei Bedarf die Nutzerauswahl
"""

from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *

from LayoutElements.gcodeEditor import gcodeEditor
from LayoutElements.menubar import menubar
from LayoutElements.settingsManager import settingsManager
from LayoutElements.plotErstellung import plotWindow
from LayoutElements.setupTabmenu import setupTabmenu
from LayoutElements.rotatedButton import rotatedButton
from LayoutElements.userDisplay import userDisplay

from utils.globalSettings import (
    # Import GUI Settings to access global settings
    GUI_SETTINGS,
    # with Language Settings language pack can be accessed
    LANGUAGE_SETTINGS, 
    loadUserRole,
    writeSettings
)

class mainWindowGUI(QMainWindow):
    """
    Hauptfenster der Anwendung, enthält alle weiteren unter Module und erlaubt Zugriff auf diese. 
    Übernimmt die Initialisierung der Anwendungsoberfläche und zeigt bei Bedarf die Nutzerauswahl

    Das Mainlayout self.mainlayout enthält die 3 Hauptlayouts self.full_gcodelayout, self.full_plotlayout und self.full_tablayout.
    Diese wiederrum enthalten jeweils einen Frame für das jeweilige Fenster und einen Button, der die Ein- bzw. Ausklappfunktion auslöst.
    Die jeweiligen Fenster bestehen teilweise aus mehreren Layouts (siehe Kommentare).
    Die Einbindung in Frames ist notwendig, da man dann von der Funktion frame.hide() Gebrauch machen kann, um die Versteckfunktion zu implementieren.
    """

    def __init__(self,App):
        """Create the mainWindow and start the init Routine for the GUI"""
        super().__init__()

        self.title = LANGUAGE_SETTINGS.languagePack["mainWindowGUI"]["windowTitle"]
        self.top = 100
        self.left = 100
        self.width = 1400
        self.height = 600
        self.setObjectName("MainWindow")
        self.App=App

        # # start User select if no Role is set
        # if GUI_SETTINGS["GUI"]["userRole"] == "":
        #     self.showUserSelect()
        # else:
        self.InitWindow()

    def InitWindow(self) -> None:
        """
        Initialize the mainWindow of the GUI and all of its submodules
        """

        # set title again for language change
        self.title = LANGUAGE_SETTINGS.languagePack["mainWindowGUI"]["windowTitle"]

        # no external window yet
        self.settingsPlotWindow = None

        self.thisStatusBar = QStatusBar()  # Statusbar
        self.setStatusBar(self.thisStatusBar)

        self.gcodeStatusIndicator = QLabel(LANGUAGE_SETTINGS.languagePack["plotErstellung"]["GCodeStatusNichtAktuell"])
        self.gcodeStatusIndicator.setAlignment(Qt.AlignCenter)
        self.gcodeStatusIndicator.setStyleSheet("background-color: #e85154; color: black; padding: 5px;")

        # self.setWindowIcon(QIcon('Images/'))
        self.setWindowTitle(self.title)
        self.setGeometry(self.top, self.left, self.width, self.height)

        self.thisSettingsManager = settingsManager(self)
        self.thisGcodeEditor = gcodeEditor(self)
        self.thisPlotWindow = plotWindow(self)
        self.thisSettings = setupTabmenu(self.thisGcodeEditor, self.thisPlotWindow, self)  # Tabwidget
        self.thisMenuBar = menubar(self)

        # Mainbuttons
        self.mainbuttonGcode = rotatedButton(LANGUAGE_SETTINGS.languagePack["mainbutton"]["texteditor"], self)
        self.mainbuttonGcode.setFixedWidth(30)
        self.mainbuttonGcode.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.mainbuttonGcode.clicked.connect(self.__doGcodeAnimation)
        self.mainbuttonGcode.setIcon(QIcon('Images/arrow2.png'))
        self.mainbuttonGcode.setIconSize(QSize(24, 24))
        self.mainbuttonGcode.setToolTip("NC-Code-Editor öffnen bzw. schließen.")
        self.mainbuttonGcode.setStyleSheet(
            "QPushButton {background-color: #F0F0F0; text-align: left}"
            "QPushButton:hover {background-color: #CCE8FF}"
            "QToolTip { background-color: white; color: black; }"
        )

        self.mainbuttonPlots = rotatedButton(LANGUAGE_SETTINGS.languagePack["mainbutton"]["plots"], self)
        self.mainbuttonPlots.setFixedWidth(30)
        self.mainbuttonPlots.setIcon(QIcon('Images/arrow2.png'))
        self.mainbuttonPlots.setIconSize(QSize(24, 24))
        self.mainbuttonPlots.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.mainbuttonPlots.clicked.connect(self.__doPlotAnimation)
        self.mainbuttonPlots.setToolTip("Plots öffnen bzw. schließen.")
        self.mainbuttonPlots.setStyleSheet(
            "QPushButton { background-color: #F0F0F0; text-align: left}"
            "QPushButton:hover {background-color: #CCE8FF}"
            "QToolTip { background-color: white; color: black; }"
        )

        self.mainbuttonTab = rotatedButton(LANGUAGE_SETTINGS.languagePack["mainbutton"]["settings"], self)
        self.mainbuttonTab.setFixedWidth(30)
        self.mainbuttonTab.setIcon(QIcon('Images/arrow2.png'))
        self.mainbuttonTab.setIconSize(QSize(24, 24))
        self.mainbuttonTab.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.mainbuttonTab.clicked.connect(self.__doTabAnimation)
        self.mainbuttonTab.setToolTip("Settings-Tab öffnen bzw. schließen.")
        self.mainbuttonTab.setStyleSheet(
            "QPushButton { background-color: #F0F0F0; text-align: left}"
            "QPushButton:hover {background-color: #CCE8FF}"
            "QToolTip { background-color: white; color: black; }"
        )

        # Teillayouts, die in den jeweiligen Frames eingefügt werden
        self.layoutGcodeeditor = QVBoxLayout()  # Texteditor
        self.layoutGcodeeditor.addWidget(self.thisGcodeEditor)

        # Create a horizontal layout for the save button and status indicator
        self.layoutStatusAndSave = QHBoxLayout()

        # Save button
        self.saveButton = QPushButton(LANGUAGE_SETTINGS.languagePack["menubarSubmenu"]["fileSubmenu"]["gcodeActions"]["saveGcode"])
        self.saveButton.setIcon(QIcon('Images/save.png'))
        self.saveButton.setIconSize(QSize(16, 16))
        self.saveButton.clicked.connect(self.thisGcodeEditor.gcodeSave)  # Replace with the actual save method
        self.layoutStatusAndSave.addWidget(self.saveButton)

        # Status indicator for G-Code editor
        self.layoutStatusAndSave.addWidget(self.gcodeStatusIndicator)

        self.layoutGcodeeditor.addLayout(self.layoutStatusAndSave)

        self.layoutTab = QVBoxLayout()  # gesamtes Tabfenster
        self.layoutTab.addLayout(self.thisSettings)

        # Layout for plot window
        self.plotWindowLayout = QVBoxLayout()
        self.plotWindowLayout.addLayout(self.thisPlotWindow)

        # Frames
        self.frameGcodeeditor = QFrame(self)
        self.frameGcodeeditor.setFrameStyle(QFrame.Panel | QFrame.Raised)
        self.frameGcodeeditor.setLayout(self.layoutGcodeeditor)
        self.frameGcodeeditor.setMinimumWidth(300)

        self.framePlots = QFrame(self)
        self.framePlots.setFrameStyle(QFrame.Panel | QFrame.Raised)
        self.framePlots.setLayout(self.plotWindowLayout)
        self.framePlots.setMinimumWidth(350)

        self.frameTab = QFrame(self)
        self.frameTab.setFrameStyle(QFrame.Panel | QFrame.Raised)
        self.frameTab.setLayout(self.layoutTab)
        self.frameTab.setMinimumWidth(300)

        #initialWidgetSizes = [30, 400, 30, 450, 30, 450]
        initialWidgetSizes = [400, 30, 450, 30, 450, 30]
        ghostButton = QWidget()

        splitter = QSplitter()
        splitter.addWidget(self.frameTab)
        splitter.addWidget(self.mainbuttonTab)
        splitter.addWidget(self.framePlots)
        splitter.addWidget(self.mainbuttonPlots)
        splitter.addWidget(self.frameGcodeeditor)
        splitter.addWidget(self.mainbuttonGcode)
        splitter.addWidget(ghostButton)
        splitter.setOrientation(Qt.Horizontal)
        splitter.setSizes(initialWidgetSizes)

        self.mainlayout = QHBoxLayout()
        self.mainlayout.addWidget(splitter)

        widget = QWidget()
        widget.setLayout(self.mainlayout)
        self.setCentralWidget(widget)

        # all modules are shown after init, hide Module if it is not shown based on settings
        if not GUI_SETTINGS["GUI"]["showGCode"]:
            self.__doGcodeAnimation()

        if not GUI_SETTINGS["GUI"]["showPlots"]:
            self.__doPlotAnimation()

        if not GUI_SETTINGS["GUI"]["showSetup"]:
            self.__doTabAnimation()

    def updateStatusIndicator(self, status):
        """Update the status indicator"""
        if status == "changed":
            self.gcodeStatusIndicator.setText(LANGUAGE_SETTINGS.languagePack["plotErstellung"]["GCodeStatusNichtAktuell"])
            self.gcodeStatusIndicator.setStyleSheet("background-color: #e85154; color: black; padding: 5px;")
        elif status == "warnings":
            self.gcodeStatusIndicator.setText(LANGUAGE_SETTINGS.languagePack["plotErstellung"]["GCodeStatusAktuell"])
            self.gcodeStatusIndicator.setStyleSheet("background-color: yellow; color: black; padding: 5px;")
        else:
            self.gcodeStatusIndicator.setText(LANGUAGE_SETTINGS.languagePack["plotErstellung"]["GCodeStatusAktuell"])
            self.gcodeStatusIndicator.setStyleSheet("background-color: green; color: white; padding: 5px;")

    def settingsChanged(self):
        """Method to call when settings are changed"""
        self.updateStatusIndicator("changed")

    def settingsApplied(self):
        """Method to call when settings are applied"""
        self.updateStatusIndicator("ok")

    def settingsAppliedWithWarnings(self):
        """Method to call when settings are applied"""
        self.updateStatusIndicator("warnings")

    #Methoden, die die Versteckfunktion steuern

    def __doGcodeAnimation(self) -> None:
        """Change the State of the G-Code Editor (shown/hidden)"""
        if self.frameGcodeeditor.isHidden():
            self.frameGcodeeditor.show()
            self.mainbuttonGcode.setIcon(QIcon('Images/arrow2.png'))
            GUI_SETTINGS["GUI"]["showGCode"] = True
            writeSettings()
        else:
            self.frameGcodeeditor.hide()
            self.mainbuttonGcode.setIcon(QIcon('Images/arrow3.png'))
            GUI_SETTINGS["GUI"]["showGCode"] = False
            writeSettings()

    def __doPlotAnimation(self) -> None:
        """Change the State of the Plot Window (shown/hidden)"""
        if self.framePlots.isHidden():
            self.framePlots.show()
            self.mainbuttonPlots.setIcon(QIcon('Images/arrow2.png'))
            GUI_SETTINGS["GUI"]["showPlots"] = True
            writeSettings()
        else:
            self.framePlots.hide()
            self.mainbuttonPlots.setIcon(QIcon('Images/arrow3.png'))
            GUI_SETTINGS["GUI"]["showPlots"] = False
            writeSettings()

    def __doTabAnimation(self) -> None:
        """Change the State of the Parameter Tab (shown/hidden)"""
        if self.frameTab.isHidden():
            self.frameTab.show()
            self.mainbuttonTab.setIcon(QIcon('Images/arrow2.png'))
            GUI_SETTINGS["GUI"]["showSetup"] = True
            writeSettings()
        else:
            self.frameTab.hide()
            self.mainbuttonTab.setIcon(QIcon('Images/arrow3.png'))
            GUI_SETTINGS["GUI"]["showSetup"] = False
            writeSettings()

    def showUserSelect(self) -> None:
        """Displays User Select and connect buttons"""

        self.menuBar().hide()
        userDialog = userDisplay()

        userDialog.set_user_button_advanced.clicked.connect(lambda: self.getSelectedUser("advanced"))
        userDialog.set_user_button_programmer.clicked.connect(lambda: self.getSelectedUser("programmer"))
        userDialog.set_user_button_mechanic.clicked.connect(lambda: self.getSelectedUser("mechanic"))

        self.setGeometry(self.top, self.left, self.width, self.height)

        self.setCentralWidget(userDialog)
        self.userDialog = userDialog

    def getSelectedUser(self, user: str) -> None:
        """get Selected User based on clicked Button"""
        loadUserRole(user)

        userLabel = ""
        if user == "advanced":
            userLabel = LANGUAGE_SETTINGS.languagePack["userDisplay"]["labelAdvanced"]
        elif user == "programmer":
            userLabel = LANGUAGE_SETTINGS.languagePack["userDisplay"]["labelProgrammer"]
        elif user == "mechanic":
            userLabel = LANGUAGE_SETTINGS.languagePack["userDisplay"]["labelMechanic"]

        self.InitWindow()
        self.statusBar().showMessage(userLabel + LANGUAGE_SETTINGS.languagePack["userDisplay"]["messageUserSelect"], 3000)

    def showStatusbarmessage(self, msg:str ,time: int = 0) -> None:
        """show a Message for a given time in the statusbar of the mainWindow"""
        self.thisStatusBar.showMessage(msg,time)
        self.App.processEvents()
        self.thisStatusBar

    def closeEvent(self, event) -> None:
        """terminate application when main window is closed"""
        quit()

    
