

import gi
gi.require_version('Gimp', '3.0')
from gi.repository import Gimp
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk

import copy,glob
from container import *
from configuration import *

class ResourceManager(object):
    def __init__(self, configuration: Configuration, procedureData):
        self.configuration=configuration
        self.procedureData=procedureData
        self.resourceType =procedureData.type
        self.containers: dict[str,ResourceContainer] = self.getContainers()
        self.checkButtons = []
        trace(f'Manager of {self.resourceType} created OK')

    def getContainers(self):
        activeResourcesDir=self.configuration.getValue(self.resourceType,'resources_active')
        storedResourcesDir=self.configuration.getValue(self.resourceType,'resources_stored')
        useLinks=self.configuration.getBooleanValue(self.resourceType,'use_links')
        containers = {}
        trace(f'''Getting containers of {self.resourceType}')
             - active resources directory: {activeResourcesDir} 
             - stored resources directory: {storedResourcesDir}
             - use links: {useLinks}''')
        for path in glob.glob(os.path.join(storedResourcesDir, '*')):
            container=None
            if os.path.isdir(path):
                if useLinks:
                    container=LinkedDirectory(path, activeResourcesDir)
                else:
                    container=CopiedDirectory(path, activeResourcesDir)
            elif os.path.isfile(path) and zipfile.is_zipfile(path):
                container=ZipFile(path, activeResourcesDir)
            else:
                trace(f'File {path} neither zip nor directory: ignored')
            containers[container.containerName()]=container
        trace(f'{len(containers)} containers found in {storedResourcesDir}')
        return containers

    def containerNames(self):
        return self.containers.keys()

    def activeContainersNames(self):
        return [c for c in self.containers if self.containers[c].isActive()]

    def initProgress(self,totalUpdates):
        self.totalUpdates = totalUpdates
        self.currentUpdates = -1
        self.bumpProgress()

    def bumpProgress(self):
        self.currentUpdates+=1
        self.setProgress(self.currentUpdates / self.totalUpdates)
        Gtk.main_iteration()

    def doUpdateActiveResources(self, deactivatedContainersNames, activatedContainersNames):
        self.initProgress(len(deactivatedContainersNames)+len(activatedContainersNames))
        self.setStatus("Deactivating removed resources...")
        for containerName in deactivatedContainersNames:
            self.containers[containerName].deactivate()
            self.bumpProgress()

        self.setStatus("Activating added resources...")
        for containerName in activatedContainersNames:
            self.containers[containerName].activate()
            self.bumpProgress()

        self.setStatus("Refreshing list...")
        trace(f'Refreshing list...')
        try:
            trace(f'Refresh: {self.procedureData.refresh}')
            self.procedureData.refresh()
            trace('Refresh OK')
        except Exception as e:
            trace(f'Error when refreshing: {e}')

        self.setStatus('Done.')
        Gtk.main_iteration()

    def clickedOK(self, widget, data=None):
        trace('OK sensed')
        oldActiveContainersNames = set(self.activeContainersNames())
        newActiveContainersNames = set(
            [button.get_label() for button in self.checkButtons if button.get_active()])

        activatedContainersNames = newActiveContainersNames - oldActiveContainersNames
        deactivatedContainersNames = oldActiveContainersNames - newActiveContainersNames

        trace(
            f"""Actions:
            - Old containers: {oldActiveContainersNames}
            - New containers: {newActiveContainersNames}
            - Activated containers: {activatedContainersNames}
            - Deactivated containers: {deactivatedContainersNames}""")
        self.doUpdateActiveResources(deactivatedContainersNames, activatedContainersNames)

    def setStatus(self, s):
        self.status.set_text(s)

    def setProgress(self, p):
        self.progressbar.set_fraction(p)

    def destroyMainDialog(self, widget, data=None):
        trace('Destroying main')
        Gtk.main_quit()

    def showMainDialog(self):
        trace('Creating main dialog')
        self.mainDialog = Gtk.Dialog()
        self.mainDialog.connect("destroy", self.destroyMainDialog)
        self.mainDialog.set_title(self.configuration.getValue(self.resourceType,'dialog_title'))
        self.mainDialog.set_border_width(10)
        self.mainDialog.set_size_request(300, 500)
        trace('Main dialog created')

        scrollBox = Gtk.ScrolledWindow()
        scrollBox.set_border_width(10)
        scrollBox.set_policy(Gtk.PolicyType.AUTOMATIC,Gtk.PolicyType.AUTOMATIC)
        self.mainDialog.vbox.pack_start(scrollBox, True, True, 0)
        scrollBox.show()
        trace('Scrollbox created')
        self.status = Gtk.Label("Select/deselect sets above")
        self.mainDialog.vbox.pack_start(self.status, False, False, 0)
        self.progressbar = Gtk.ProgressBar()
        self.mainDialog.vbox.pack_start(self.progressbar, False, False, 0)
        self.status.show()
        self.progressbar.show()

        vbox = Gtk.VBox()
        self.checkButtons = []
        for containerName in sorted(self.containers.keys()):
            button = Gtk.CheckButton(containerName)
            button.set_active(containerName in self.activeContainersNames())
            self.checkButtons.append(button)
            vbox.pack_start(button, False, False, 1)
            button.show()
        scrollBox.add_with_viewport(vbox)
        vbox.show()
        trace('VBox created')

        cancelButton = Gtk.Button(stock=Gtk.STOCK_CLOSE)
        cancelButton.connect_object("clicked", Gtk.Widget.destroy, self.mainDialog)
        self.mainDialog.action_area.pack_start(cancelButton, True, True, 0)
        cancelButton.show()
        trace('Cancel button created')

        okButton = Gtk.Button(stock=Gtk.STOCK_OK)
        okButton.connect("clicked", self.clickedOK)
        self.mainDialog.action_area.pack_start(okButton, True, True, 0)
        okButton.show()
        trace('OK button created')

        self.mainDialog.show()
        Gtk.main_iteration()

    def main(self):
        Gtk.main()

