# Path: e3d/_baseManager.py
# class BaseManager(object):
#     def __init__(self):
#         self._engine = None
# 
#     def initialize(self, engine):
#         self._engine = engine
# 
#     def terminate(self):
#         pass
# 
# Path: e3d/plugin_management/PluginHandlers.py
# class PluginDescription(object):
#     def __init__(self, name='', description='', authorName='', authorEmail=''):
#         self.name = name
#         self.description = description
#         self.authorName = authorName
#         self.authorEmail = authorEmail
# 
#     def __repr__(self):
#         return self.name
# 
#     def _toDict(self):
#         d = dir(self)
#         dd = {v: getattr(self, v) for v in d if not v.startswith('_') and not callable(getattr(self, v))}
#         return dd
# 
#     def saveToDisk(self, destFolder):
#         try:
#             finalPath = path.abspath(path.join(destFolder, DESCRIPTIONNAME + '.json'))
#             with open(finalPath, 'w') as dest:
#                 dump(self._toDict(), dest, indent=4)
#         except:
#             raise
# 
#     @staticmethod
#     def fromDisk(folderPath):
#         descriptionPath = path.abspath(path.join(folderPath, DESCRIPTIONNAME + '.json'))
#         if not path.exists(descriptionPath):
#             raise FileNotFoundError('required plugin description file not found.')
#         with open(descriptionPath) as desc:
#             data = load(desc)
# 
#         description = PluginDescription(**data)
#         return description
# 
# class _Plugin(object):
#     def __init__(self, description, mainClass, pluginPath):
#         self.description = description
#         self.mainClass = mainClass
#         self.pluginPath = pluginPath
# 
# Path: e3d/plugin_management/RunnableClass.py
# MAINFILENAME = 'main.py'
# 
# MAINCLASSNAME = 'MAIN'
# 
# class Runnable(object):
#     def __init__(self, engine):
#         self.engine = engine
#         self.repiteCurrentPass = False
# 
#     def preparePlugin(self, data):
#         pass
# 
#     def onDrawPass(self, passNumber):
#         pass
# 
#     def onPreUpdate(self):
#         pass
# 
#     def onPostUpdate(self):
#         pass
# 
#     def terminate(self):
#         pass


from .._baseManager import BaseManager
from .PluginHandlers import PluginDescription, _Plugin
from .RunnableClass import MAINFILENAME, MAINCLASSNAME, Runnable
from sys import version_info
from os import path
from shutil import rmtree
from tempfile import mkdtemp
    from shutil import unpack_archive
        from importlib.machinery import SourceFileLoader
        from importlib import util
    import imp

    def addPlugin(self, ID, pluginPath, isEnabled=True):
        if ID in self._pluginPaths.keys():
            raise RuntimeError('the specified ID ({}) already exist.'.format(ID))
        self._pluginPaths[ID] = pluginPath
        self._enabled[ID] = isEnabled
        self._plugins[ID] = self._injectPlugin(ID, pluginPath)

    def removePlugin(self, ID):
        if ID not in self._pluginPaths.keys():
            raise RuntimeError('the specified ID ({}) does not exist.'.format(ID))
        self._enabled.pop(ID)
        self._pluginPaths.pop(ID)
        self._plugins.pop(ID)

    def setPluginEnableState(self, ID, stateBool):
        if ID not in self._pluginPaths.keys():
            raise RuntimeError('the specified ID ({}) does not exist.'.format(ID))
        self._enabled[ID] = bool(stateBool)

    def _injectPlugin(self, ID, pluginPath):
        tempDir = mkdtemp(prefix='e3d_' + ID + '_')
        self._tempPluginPaths[ID] = tempDir
        unpack_archive(pluginPath, tempDir, 'gztar')
        plugDesc = PluginDescription.fromDisk(tempDir)
        module_name = plugDesc.name.lower().replace(' ', '_')
        mainFilePath = path.join(tempDir, MAINFILENAME)
        plugin_module = self._loadModule(mainFilePath, module_name)

        mainClass = getattr(plugin_module, MAINCLASSNAME)(self._engine)

# Path: e3d/_baseManager.py
# class BaseManager(object):
#     def __init__(self):
#         self._engine = None
# 
#     def initialize(self, engine):
#         self._engine = engine
# 
#     def terminate(self):
#         pass
# 
# Path: e3d/plugin_management/PluginHandlers.py
# class PluginDescription(object):
#     def __init__(self, name='', description='', authorName='', authorEmail=''):
#         self.name = name
#         self.description = description
#         self.authorName = authorName
#         self.authorEmail = authorEmail
# 
#     def __repr__(self):
#         return self.name
# 
#     def _toDict(self):
#         d = dir(self)
#         dd = {v: getattr(self, v) for v in d if not v.startswith('_') and not callable(getattr(self, v))}
#         return dd
# 
#     def saveToDisk(self, destFolder):
#         try:
#             finalPath = path.abspath(path.join(destFolder, DESCRIPTIONNAME + '.json'))
#             with open(finalPath, 'w') as dest:
#                 dump(self._toDict(), dest, indent=4)
#         except:
#             raise
# 
#     @staticmethod
#     def fromDisk(folderPath):
#         descriptionPath = path.abspath(path.join(folderPath, DESCRIPTIONNAME + '.json'))
#         if not path.exists(descriptionPath):
#             raise FileNotFoundError('required plugin description file not found.')
#         with open(descriptionPath) as desc:
#             data = load(desc)
# 
#         description = PluginDescription(**data)
#         return description
# 
# class _Plugin(object):
#     def __init__(self, description, mainClass, pluginPath):
#         self.description = description
#         self.mainClass = mainClass
#         self.pluginPath = pluginPath
# 
# Path: e3d/plugin_management/RunnableClass.py
# MAINFILENAME = 'main.py'
# 
# MAINCLASSNAME = 'MAIN'
# 
# class Runnable(object):
#     def __init__(self, engine):
#         self.engine = engine
#         self.repiteCurrentPass = False
# 
#     def preparePlugin(self, data):
#         pass
# 
#     def onDrawPass(self, passNumber):
#         pass
# 
#     def onPreUpdate(self):
#         pass
# 
#     def onPostUpdate(self):
#         pass
# 
#     def terminate(self):
#         pass


# Path: e3d/plugin_management/PluginsManagerClass.py
from .._baseManager import BaseManager
from .PluginHandlers import PluginDescription, _Plugin
from .RunnableClass import MAINFILENAME, MAINCLASSNAME, Runnable
from sys import version_info
from os import path
from shutil import rmtree
from tempfile import mkdtemp
    from shutil import unpack_archive
        from importlib.machinery import SourceFileLoader
        from importlib import util
    import imp


    def addPlugin(self, ID, pluginPath, isEnabled=True):
        if ID in self._pluginPaths.keys():
            raise RuntimeError('the specified ID ({}) already exist.'.format(ID))
        self._pluginPaths[ID] = pluginPath
        self._enabled[ID] = isEnabled
        self._plugins[ID] = self._injectPlugin(ID, pluginPath)

    def removePlugin(self, ID):
        if ID not in self._pluginPaths.keys():
            raise RuntimeError('the specified ID ({}) does not exist.'.format(ID))
        self._enabled.pop(ID)
        self._pluginPaths.pop(ID)
        self._plugins.pop(ID)

    def setPluginEnableState(self, ID, stateBool):
        if ID not in self._pluginPaths.keys():
            raise RuntimeError('the specified ID ({}) does not exist.'.format(ID))
        self._enabled[ID] = bool(stateBool)

    def _injectPlugin(self, ID, pluginPath):
        tempDir = mkdtemp(prefix='e3d_' + ID + '_')
        self._tempPluginPaths[ID] = tempDir
        unpack_archive(pluginPath, tempDir, 'gztar')
        plugDesc = PluginDescription.fromDisk(tempDir)
        module_name = plugDesc.name.lower().replace(' ', '_')
        mainFilePath = path.join(tempDir, MAINFILENAME)
        plugin_module = self._loadModule(mainFilePath, module_name)

        mainClass = getattr(plugin_module, MAINCLASSNAME)(self._engine)

        if not issubclass(type(mainClass), Runnable):