"""
Module to show a additional Window with the general settings of the application
"""

import os
import json

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

from PIL import ImageColor

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

import LayoutElements.mainWindowGUI as mainWindowGUI

LANGUAGE_PACK_SETTINGS = LANGUAGE_SETTINGS.languagePack["settingsManager"]

class settingsManager(QWidget):
    """Module to show a additional Window with the general settings of the application"""
    
    def __init__(self, mainWindow: mainWindowGUI):
        """Create the Window with to set the settings of the application"""
        super().__init__()

        global LANGUAGE_PACK_SETTINGS
        LANGUAGE_PACK_SETTINGS = LANGUAGE_SETTINGS.languagePack["settingsManager"]

        self.mainWindow: mainWindowGUI = mainWindow

        layout = QHBoxLayout()
        tabs = QTabWidget()
        layout.addWidget(tabs)
        self.setLayout(layout)
        self.setWindowTitle(LANGUAGE_PACK_SETTINGS["title"])

        self.generalTab = QWidget()
        self.pathTab = QWidget()
        self.gCodeTab = QWidget()

        

        tabs.addTab(self.generalTab, LANGUAGE_PACK_SETTINGS["generalTabLabel"])
        tabs.addTab(self.pathTab, LANGUAGE_PACK_SETTINGS["pathTabLabel"])
        tabs.addTab(self.gCodeTab, LANGUAGE_PACK_SETTINGS["gCodeEditorTabLabel"])

        self.__initPathTab()
        self.__initGCodeTab()
        self.__initGeneralTab()

    def showSettings(self) -> None:
        self.show()

    def __initGeneralTab(self) -> None:
        """
        Function to Init the General Tab, only to be accesed locally during init routine
        """
        layout = QFormLayout()

        # userSelectRow = QHBoxLayout()
        # user = GUI_SETTINGS["GUI"]["userRole"]
        # 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"]

        # userSelectRow.addWidget(QLabel(LANGUAGE_PACK_SETTINGS['userLabel']))
        #
        # selectedUser = QLabel(userLabel)
        # selectedUser.setStyleSheet("background-color: #F8F8F8; color: #555555; padding: 3px")
        # userSelectRow.addWidget(selectedUser)

        # userSelectButton = QPushButton(LANGUAGE_PACK_SETTINGS['userSelectButton'])
        # userSelectButton.clicked.connect(self.close)
        # userSelectButton.clicked.connect(self.mainWindow.showUserSelect)
        # userSelectRow.addWidget(userSelectButton)

        #layout.addRow(userSelectRow)

        self.languageSelect = QComboBox()
        self.languagePackPaths = self.__getLanguagePackNames()
        
        languageSelectLayout = QHBoxLayout()
        languageSelectLayout.addWidget(self.languageSelect)
        languageChangeButton = QPushButton(LANGUAGE_PACK_SETTINGS['languageSelectButton'])
        languageChangeButton.clicked.connect(self.__loadSelectedLanguage)
        languageSelectLayout.addWidget(languageChangeButton)

        layout.addRow(LANGUAGE_PACK_SETTINGS['languageSelect'], languageSelectLayout)
        
        self.safteyTolerance = doubleEditLine(str(GUI_SETTINGS["safteyTolerance"]), 0, 1, 3)
        self.safteyTolerance.textChanged.connect(self.__saveSafteyTolerance)
        layout.addRow(f"{LANGUAGE_PACK_SETTINGS['safteyTolerance']} [mm]", self.safteyTolerance)

        self.generalTab.setLayout(layout)

    def __saveSafteyTolerance(self) -> None:
        """
        Writes new Saftey Tolerance to settings
        """
        GUI_SETTINGS["safteyTolerance"] = textToFloat(self.safteyTolerance.text())
        writeSettings()


    def __loadSelectedLanguage(self) -> None:
        """
        Triggers loading of selected Language Pack and restarts GUI
        """
        path = self.languagePackPaths[self.languageSelect.currentIndex()]
        GUI_SETTINGS["languagePack"] = path
        writeSettings()
        LANGUAGE_SETTINGS.changeLanguage(path)
        self.close()
        self.mainWindow.InitWindow()

    def __initGCodeTab(self) -> None:
        """
        Function to Init the G Code Tab, only to be accesed locally during init routine
        """
        layoutColorpicker = QFormLayout()

        gCoodeSize = QSpinBox()
        gCoodeSize.setRange(8, 16)
        gCoodeSize.setSizeIncrement(1, 1)
        gCoodeSize.setSuffix(" pt")
        gCoodeSize.setValue(GUI_SETTINGS["gCodeSize"])
        gCoodeSize.valueChanged.connect(lambda: self.mainWindow.thisGcodeEditor.adjustTextSize(int(gCoodeSize.value())))
        layoutColorpicker.addRow(LANGUAGE_PACK_SETTINGS["gCodeSizeLabel"], gCoodeSize)

        self.colorpicker = colorpickerWidget(self.gCodeTab.width(), self.gCodeTab.height())
        layoutColorpicker.addRow(self.colorpicker)
        self.gCodeTab.setLayout(layoutColorpicker)

    def __initPathTab(self) -> None:
        """
        Function to Init the Paths Tab, only to be accesed locally during init routine
        """
        tabLayout = QFormLayout()

        tabLayout.addRow(LANGUAGE_PACK_SETTINGS["machineConfigs"], settingsPathSelect("machineConfigs"))
        tabLayout.addRow(LANGUAGE_PACK_SETTINGS["toolConfigs"], settingsPathSelect("toolConfigs"))
        tabLayout.addRow(LANGUAGE_PACK_SETTINGS["autoSaves"], settingsPathSelect("autoSaves"))

        self.pathTab.setLayout(tabLayout)

    def __getLanguagePackNames(self) -> list[str]:
        """
        Returns a arroy of Strings with the title of langugagePacks found in the languagePacks directory.
        Adds all Language Packs to Dropdown
        """

        languagePackPaths = []
        
        with open(LANGUAGE_PACK_DEFAULT, 'r') as languageFile:
            defaultName = json.load(languageFile)["languageName"]
            self.languageSelect.addItem(defaultName + " - " + LANGUAGE_PACK_SETTINGS["defaultLanguage"])
            languagePackPaths.append(LANGUAGE_PACK_DEFAULT)

        currentIndex = 0
        selectedIndex = 0

        if os.path.isdir(PATH_LANGUAGE_PACK):
            for f in os.listdir(PATH_LANGUAGE_PACK):
                filePath = PATH_LANGUAGE_PACK + f
                if os.path.isfile(filePath) and filePath.endswith('.json'):
                    with open(filePath, 'r') as languageFile:
                        try: 
                            languagePack = json.load(languageFile)

                            # select is only added if file seems to be a language pack
                            if "languageName" in languagePack:
                                # file seems to be languagePack
                                self.languageSelect.addItem(languagePack["languageName"])
                                languagePackPaths.append(filePath)
                                currentIndex = currentIndex + 1

                            if filePath == GUI_SETTINGS["languagePack"]:
                                # save Entry Index of selected Language Pack to select in combo Box current language
                                selectedIndex = currentIndex
                        except:
                            pass

        self.languageSelect.setCurrentIndex(selectedIndex)



        return languagePackPaths

class settingsPathSelect(QGridLayout):
    """Class to create a Row with a settings Path and a Dialog to adjust the path"""
    def __init__(self, pathName: str) -> None:
        """Create a Row for the path defined by pathname, pathname is the label used in the settings file"""
        super().__init__()

        self.pathName = pathName
        self.selectedPath = QLabel(os.path.expandvars(GUI_SETTINGS["paths"][self.pathName]))
        self.selectPathButton = QPushButton(LANGUAGE_PACK_SETTINGS["pathButton"])
        self.selectPathButton.setFixedWidth(120)
        self.addWidget(self.selectedPath, 1, 1, 1, 2)
        self.addWidget(self.selectPathButton, 1, 3, 1, 1)

        self.selectPathButton.clicked.connect(self.changePath)

    def changePath(self) -> None:
        """Open a Dialog to select a new path and write this path to the settings"""
        returnPath = QFileDialog.getExistingDirectory(None, LANGUAGE_PACK_SETTINGS["pathButton"], 
        os.path.expandvars(GUI_SETTINGS["paths"][self.pathName]))

        if returnPath == '':
            return
        
        else:
            returnPath = returnPath.replace("/", "\\") + "\\"
            #returnPath = returnPath.replace(os.path.expandvars("$APPDATA"), "$APPDATA")
            GUI_SETTINGS["paths"][self.pathName] = returnPath
            writeSettings()

            self.selectedPath.setText(os.path.expandvars(GUI_SETTINGS["paths"][self.pathName]))

            return


class colorpickerWidget (QFrame):
    """Colorpicker to change the colors for the G-Code Editor"""

    def __init__(self, width: int, height: int) -> None:
        """Create the colorpicker to change the color for syntax highlighting for the G-Code"""
        super().__init__()
        self.setFixedSize(width, height)

        #Initialize rectangular colors
        self.commentColor = QColor()
        self.commentColor.setNamedColor(GUI_SETTINGS["gCodeColors"]["htmlCommentColor"])
        self.lineNumberColor = QColor()
        self.lineNumberColor.setNamedColor(GUI_SETTINGS["gCodeColors"]["htmlLineNumberColor"])
        self.gCommandColor = QColor()
        self.gCommandColor.setNamedColor(GUI_SETTINGS["gCodeColors"]["htmlGCommandColor"])
        self.fCommandColor = QColor()
        self.fCommandColor.setNamedColor(GUI_SETTINGS["gCodeColors"]["htmlFCommandColor"])
        self.mCommandColor = QColor()
        self.mCommandColor.setNamedColor(GUI_SETTINGS["gCodeColors"]["htmlMCommandColor"])
        self.coordColor = QColor()
        self.coordColor.setNamedColor(GUI_SETTINGS["gCodeColors"]["htmlCoordColor"])
        self.defaultColor = QColor()
        self.defaultColor.setNamedColor(GUI_SETTINGS["gCodeColors"]["htmlDefaultColor"])

        self.commentColorRow = texteditorSelectColorRow(LANGUAGE_PACK_SETTINGS["commentColorLabel"], LANGUAGE_PACK_SETTINGS["commentColorToolTip"], self.commentColor, "htmlCommentColor")
        self.lineNumberColorRow = texteditorSelectColorRow(LANGUAGE_PACK_SETTINGS["lineNumberColorLabel"], LANGUAGE_PACK_SETTINGS["lineNumberColorToolTip"], self.lineNumberColor, "htmlLineNumberColor")
        self.gCommandColorRow = texteditorSelectColorRow(LANGUAGE_PACK_SETTINGS["gCommandColorLabel"], LANGUAGE_PACK_SETTINGS["gCommandColorToolTip"], self.gCommandColor, "htmlGCommandColor")
        self.fCommandColorRow = texteditorSelectColorRow(LANGUAGE_PACK_SETTINGS["fCommandColorLabel"], LANGUAGE_PACK_SETTINGS["fCommandColorToolTip"], self.fCommandColor, "htmlFCommandColor")
        self.mCommandColorRow = texteditorSelectColorRow(LANGUAGE_PACK_SETTINGS["mCommandColorLabel"], LANGUAGE_PACK_SETTINGS["mCommandColorToolTip"], self.mCommandColor, "htmlMCommandColor")
        self.coordColorRow = texteditorSelectColorRow(LANGUAGE_PACK_SETTINGS["coordColorLabel"], LANGUAGE_PACK_SETTINGS["coordColorToolTip"], self.coordColor, "htmlCoordColor")
        self.defaultColorRow = texteditorSelectColorRow(LANGUAGE_PACK_SETTINGS["defaultColorLabel"], LANGUAGE_PACK_SETTINGS["defaultColorToolTip"], self.defaultColor, "htmlDefaultColor")

        layout = QFormLayout()
        layout.addRow(self.commentColorRow)
        layout.addRow(self.lineNumberColorRow)
        layout.addRow(self.gCommandColorRow)
        layout.addRow(self.fCommandColorRow)
        layout.addRow(self.mCommandColorRow)
        layout.addRow(self.coordColorRow)
        layout.addRow(self.defaultColorRow)

        self.resetButton = QPushButton(LANGUAGE_PACK_SETTINGS["resetAllColorsButton"])
        self.resetButton.clicked.connect(self.resetEditorColors)
        layout.addRow(self.resetButton)

        self.setLayout(layout)

    def resetEditorColors(self) -> None:
        """Reset the Color to default values for the G-Code Editor"""

        self.commentColorRow.resetColor()
        self.lineNumberColorRow.resetColor()
        self.gCommandColorRow.resetColor()
        self.fCommandColorRow.resetColor()
        self.mCommandColorRow.resetColor()
        self.coordColorRow.resetColor()
        self.defaultColorRow.resetColor()
class texteditorSelectColorRow(QFrame):
    """Single Color Row for the color picker class"""

    def __init__(self, labeltext: str, tooltip: str, defaultRectColor: QColor, jsonElementName: str) -> None:
        """Create a new row to pick a color for the color picker"""
        super().__init__()

        self.defaultRectColor = defaultRectColor
        self.row = texteditorSelectRow(labeltext, tooltip)
        self.row.selectColorButton.clicked.connect(self.openColorDialog)
        self.row.resetButton.clicked.connect(self.resetColor)
        layout = QFormLayout()
        layout.addRow(self.row)
        self.setLayout(layout)

        self.brush = QBrush(self.defaultRectColor, Qt.SolidPattern)
        self.jsonElementName = jsonElementName



    def paintEvent(self, e) -> None:
        """Draw the rectangel with the selected color"""
        painter = QPainter(self)
        painter.setBrush(self.brush)
        painter.drawRect(150, 10, 20, 20)

    def openColorDialog(self) -> None:
        """Open the Dialor to select a new Color"""
        color = QColorDialog.getColor()

        if color.isValid():

            GUI_SETTINGS["gCodeColors"][self.jsonElementName] = color.name()
            writeSettings()

            r = ImageColor.getcolor(color.name(), "RGB")[0]
            g = ImageColor.getcolor(color.name(), "RGB")[1]
            b = ImageColor.getcolor(color.name(), "RGB")[2]
            pickedColor = QColor()
            pickedColor.setRgb(r, g, b)
            self.brush.setColor(pickedColor)

            self.update()

    def resetColor(self) -> None:
        """Reset the color to the Default Value"""
        defaultColor = QColor()
        defaultColor.setNamedColor(GUI_SETTINGS["gCodeColors"][self.jsonElementName + 'Default'])
        GUI_SETTINGS["gCodeColors"][self.jsonElementName] = GUI_SETTINGS["gCodeColors"][self.jsonElementName + 'Default']
        writeSettings()


        self.brush.setColor(defaultColor)
        self.update()

class texteditorSelectRow(QGridLayout):
    """Sub Layout for the texteditorSelectColorRow to place the label and the buttons"""

    def __init__(self, labeltext: str, tooltip: str) -> None:
        """Create the Label and buttons for a texteditorSelectColorRow"""
        super().__init__()

        self.labeltext = labeltext
        self.label = QLabel(self.labeltext)
        self.selectColorButton = QPushButton(LANGUAGE_PACK_SETTINGS["allColorButtons"])
        self.selectColorButton.setToolTip(tooltip)
        self.resetButton = QPushButton(LANGUAGE_PACK_SETTINGS["allColorResetButtons"])
        self.addWidget(self.label, 1, 1, 1, 2)
        self.addWidget(self.resetButton, 1, 2, 1, 1 )
        self.addWidget(self.selectColorButton, 1, 3, 1, 1)
