import glob
import imp
import os
import string
import types

from compClust.mlx import wrapper

class WrapperPlugins:
  """Manage wrappers that can be plugged into GUIs
  """
  def __init__(self):
    self.algorithms = {} # dictionary is 
    self.__getGuiCompatibleClusteringAlgorithms()

  #############
  # provide access to the dictionaries.
  def keys(self):
    return self.algorithms.keys()

  def values(self):
    return self.algorithms.values()

  def items(self):
    return self.algorithms.items()
  
  def __getitem__(self, name):
    return self.algorithms[name]

  def getClass(self, name):
    """Return wrapper class used to instantiate an algorithm
    """
    return self.algorithms[name]

  def isComposable(self, name):
    """Return true if the algorithm is designed to wrap other algorithms
    """
    return name in ("MultiRun")


  def getParameters(self, name):
    """Return parameters dictionary for an algorithm
    """
    return self.algorithms[name][1]
  
  #############
  # load modules
  def __loadModule(self, module_path, moduleName):
    """Given a module name, load the appropriate module
    """ 	                                                
    if type(moduleName) == types.ModuleType:
      return moduleName
    elif type(moduleName) == types.StringType or type(moduleName) == types.UnicodeType: 
      file, filename, modType = imp.find_module(moduleName, module_path) 
    return imp.load_module(moduleName, file, filename, modType)

  def __moduleFilter(self, x):
    """
    Filter out test modules and __init__.py
    """
    if string.find(x, 'Test') >= 0:
      return False
    elif string.find(x, '__init__.py') > 0:
      return False
  
    return True

  def __getModuleFilePaths(self, path):
    """
    Return a list of modules in a give path, minus filtered
    """
    pathPattern = os.path.join(path[0], '*.py')
    filePathList = glob.glob(pathPattern)
    return filter(self.__moduleFilter, filePathList)

  def __getModuleList(self, pathList):
    """
    Get moduleName list from a list of python files
    """
    moduleList = []
    for path in pathList:
      filePath, fileName = os.path.split(path)
      moduleName = string.replace(fileName, '.py', '')
      moduleList.append(moduleName)
    return moduleList

  def __getGuiCompatibleClusteringAlgorithms(self):
    """Load modules looking for ones that have a parameter description
    """
    path = wrapper.__path__
    pathList = self.__getModuleFilePaths(wrapper.__path__)
    moduleList = self.__getModuleList(pathList)
    for moduleName in moduleList:
      myMod = self.__loadModule(path, moduleName)
      #print 'SEARCHING %s' % (path[0])
      try:
        r = type(myMod.Parameters)
        #print 'GUI Compatible Module Found: %s' % (moduleName)
        self.algorithms[moduleName] = myMod.__dict__[moduleName]
      except AttributeError:
        #print 'Skipping: %s' % (moduleName)
        pass

#  def _getAlgorithmDictionaries():
#    """Figure out where 
#    """
#    __getGuiCompatibleClusteringAlgorithms(wrapper.__path__, moduleList)
## not sure if this is needed or not, after this refactoring    
#    if PY2EXE_MODE:
#      algorithmParamDict = {}
#      algorithmClassDict = {}
#  
#      from compClust.mlx.wrapper.DiagEM import DiagEM
#      from compClust.mlx.wrapper.DiagEM import getDefaultParameterDescriptions as DiagEMDefaults
#      algorithmParamDict['DiagEM'] = DiagEMDefaults()                                         
#      algorithmClassDict['DiagEM'] = DiagEM
#  
#      from compClust.mlx.wrapper.KMeans import KMeans
#      from compClust.mlx.wrapper.KMeans import getDefaultParameterDescriptions as KMeansDefaults
#      algorithmParamDict['KMeans'] = KMeansDefaults()                                         
#      algorithmClassDict['KMeans'] = KMeans
#      
#      return (algorithmParamDict, algorithmClassDict)
#  
#    else:
