# -*- coding: utf-8 -*-

# Copyright (c) 2021 - 2022 Detlev Offenbach <detlev@die-offenbachs.de>
#

"""
Module implementing a widget to manage the QtHelp documentation settings.
"""

from PyQt6.QtCore import pyqtSlot, pyqtSignal
from PyQt6.QtWidgets import QWidget, QListWidgetItem, QDialog

from EricWidgets.EricApplication import ericApp
from EricWidgets import EricMessageBox, EricFileDialog

from .Ui_QtHelpDocumentationSettingsWidget import (
    Ui_QtHelpDocumentationSettingsWidget
)

from .QtHelpDocumentationSettings import QtHelpDocumentationSettings


class QtHelpDocumentationSettingsWidget(QWidget,
                                        Ui_QtHelpDocumentationSettingsWidget):
    """
    Class implementing a widget to manage the QtHelp documentation settings.
    
    @signal documentationSettingsChanged(settings) emitted to signal a change
        of the documentation configuration
    """
    documentationSettingsChanged = pyqtSignal(QtHelpDocumentationSettings)
    
    def __init__(self, parent=None):
        """
        Constructor
        
        @param parent reference to the parent widget (defaults to None)
        @type QWidget (optional)
        """
        super().__init__(parent)
        self.setupUi(self)
        
        self.__settings = None
        
        try:
            self.__pluginHelpDocuments = (
                ericApp().getObject("PluginManager").getPluginQtHelpFiles()
            )
        except KeyError:
            from PluginManager.PluginManager import PluginManager
            pluginManager = PluginManager(self, doLoadPlugins=False)
            pluginManager.loadDocumentationSetPlugins()
            pluginManager.activatePlugins()
            self.__pluginHelpDocuments = pluginManager.getPluginQtHelpFiles()
        self.addPluginButton.setEnabled(bool(self.__pluginHelpDocuments))
    
    @pyqtSlot()
    def on_removeDocumentsButton_clicked(self):
        """
        Private slot to remove a document from the help database.
        """
        selectedItems = self.documentsList.selectedItems()[:]
        if not selectedItems:
            return
        
        for itm in selectedItems:
            namespace = itm.text()
            self.documentsList.takeItem(self.documentsList.row(itm))
            del itm
            
            self.__settings.removeDocumentation(namespace)
        
        self.documentationSettingsChanged.emit(self.__settings)
    
    @pyqtSlot()
    def on_addDocumentsButton_clicked(self):
        """
        Private slot to add QtHelp documents to the help database.
        """
        filenames = EricFileDialog.getOpenFileNames(
            self,
            self.tr("Add Documentation"),
            "",
            self.tr("Qt Compressed Help Files (*.qch)"))
        if not filenames:
            return
        
        self.__registerDocumentation(filenames)
    
    @pyqtSlot()
    def on_addPluginButton_clicked(self):
        """
        Private slot to add QtHelp documents provided by plug-ins to
        the help database.
        """
        from .QtHelpDocumentationSelectionDialog import (
            QtHelpDocumentationSelectionDialog
        )
        dlg = QtHelpDocumentationSelectionDialog(
            self.__pluginHelpDocuments,
            QtHelpDocumentationSelectionDialog.AddMode,
            self)
        if dlg.exec() == QDialog.DialogCode.Accepted:
            documents = dlg.getData()
            if documents:
                self.__registerDocumentation(documents)
    
    def __registerDocumentation(self, filenames):
        """
        Private method to register a given list of documentations.
        
        @param filenames list of documentation files to be registered
        @type list of str
        """
        added = False
        
        for filename in filenames:
            if not self.__settings.addDocumentation(filename):
                EricMessageBox.warning(
                    self,
                    self.tr("Add Documentation"),
                    self.tr("""The file <b>{0}</b> could not be added.""")
                    .format(filename)
                )
                continue
            
            if not added:
                added = True
                self.documentsList.clearSelection()
            
            namespace = self.__settings.namespace(filename)
            itm = QListWidgetItem(namespace)
            self.documentsList.addItem(itm)
            
            itm.setSelected(True)
        self.__applyDocumentsListFilter()
        
        if added:
            self.documentationSettingsChanged.emit(self.__settings)
    
    @pyqtSlot()
    def on_managePluginButton_clicked(self):
        """
        Private slot to manage the QtHelp documents provided by plug-ins.
        """
        from .QtHelpDocumentationSelectionDialog import (
            QtHelpDocumentationSelectionDialog
        )
        dlg = QtHelpDocumentationSelectionDialog(
            self.__pluginHelpDocuments,
            QtHelpDocumentationSelectionDialog.ManageMode,
            self)
        dlg.exec()
    
    @pyqtSlot()
    def on_documentsList_itemSelectionChanged(self):
        """
        Private slot handling a change of the documents selection.
        """
        self.removeDocumentsButton.setEnabled(
            len(self.documentsList.selectedItems()) != 0)
    
    @pyqtSlot(str)
    def on_filterEdit_textChanged(self, txt):
        """
        Private slot to react on changes of the document filter text.
        
        @param txt current entry of the filter
        @type str
        """
        self.__applyDocumentsListFilter()
    
    @pyqtSlot()
    def __applyDocumentsListFilter(self):
        """
        Private slot to apply the current documents filter.
        """
        filterStr = self.filterEdit.text()
        for row in range(self.documentsList.count()):
            itm = self.documentsList.item(row)
            matches = filterStr == "" or filterStr in itm.text()
            
            if not matches:
                itm.setSelected(False)
            itm.setHidden(not matches)
    
    def setDocumentationSettings(self, settings):
        """
        Public method to set the reference to the QtHelp documentation
        configuration object.
        
        @param settings reference to the created QtHelpDocumentationSettings
            object
        @type QtHelpDocumentationSettings
        """
        self.__settings = settings
        
        self.documentsList.clear()
        
        for namespace in self.__settings.namespaces():
            itm = QListWidgetItem(namespace)
            self.documentsList.addItem(itm)
        self.__applyDocumentsListFilter()
        
        self.removeDocumentsButton.setEnabled(False)
    
    def documentationSettings(self):
        """
        Public method to get the reference to the QtHelp documentation
        configuration object.
        
        @return reference to the created QtHelpDocumentationSettings object
        @rtype QtHelpDocumentationSettings
        """
        return self.__settings
