"""
  
  BGL - Brisbane Gameloft Libs (BeaGLe)

  The problem this lib tries to solve is that there are
  currently a bunch of python libs (both 3rd party and 
  in-house) scattered all over the place.  Python code 
  needs to find these modules.  This creates scattered
  spaghetti-code like dependencies of hard-coded changes
  to sys.path and assumed changes to PYTHONPATH.  This 
  makes the python code brittle.

  This file attempts to solve that problem by customizing 
  the way files are loaded in Python by collecting all 
  the paths to python libs in one place.  Here.  

  We do this by intercepting import calls in python code 
  and redirecting calls that start with the beagle names
  space bgl. Modules are imported on demand.

  In order to use this lib we still have to tell python
  where to load this file.  But that's one hard-coded 
  path as opposed to many.

  This file is also going to be the canonical location 
  for path constants!

  Ultimately it would be nice to physically collect 
  all the libs together into one place in the dir 
  structure and throw this module away.  The reason
  we should get rid of this file is because it uses
  some non-obvious python "magic".  In the meantime, 
  hopefully, this will make life a little easier.

  
  FIXME: there's a problem with interdependencies
  between the "libs" dirs and the survivor dirs.

  There's paths in here that should only be in
  survivor and there's back-references in here
  to code that should be moved out of the game 
  dir and into the libs dirs ("rki", "rk", tlib 
  etc).
  

"""
import sys
import os
from os.path import abspath, join, dirname
import importlib

#
# Canonical Path Constants
#

# Where the bgl libs live.  Work out all the other paths relative to this.
BGL_DIR = abspath(dirname(__file__))   

# ../code/3rdParty
THIRD_PARTY_DIR = abspath(join(BGL_DIR, "..", "..", ".."))
# ../code/3rdParty/bne_lib
BNE_LIB_DIR = join(THIRD_PARTY_DIR, "bne_lib")
# ../code/3rdParty/bne_lib/tools
BNE_LIB_TOOLS_DIR = join(BNE_LIB_DIR, "tools")
# ../code/3rdParty/tools/BuildSystem/SConsHome 
SCONS_HOME = join("BuildSystem", "SConsHome")


# ../code/3rdParty/tools
THIRD_PARTY_TOOLS_DIR = join(THIRD_PARTY_DIR, "tools")
# ../code/3rdParty/tools/BuildSystem
TOOLS_BUILD_SYSTEM_DIR = join(THIRD_PARTY_TOOLS_DIR, "BuildSystem")
# ../code/3rdParty/tools/Corona
CORONA_DIR = join(THIRD_PARTY_TOOLS_DIR, "Corona")
# ../code/3rdParty/tools/7Zip
SEVEN_ZIP_DIR = join(THIRD_PARTY_TOOLS_DIR, "7Zip")


# ../code/survivor
SURVIVOR_DIR = abspath(join(BGL_DIR, "..", "..", "..", "..", "survivor"))
# ../code/survivor/data/Survivor
SURVIVOR_DATA_DIR = join(SURVIVOR_DIR, "data", "Survivor")
# ../code/survivor/data/Survivor/Data/Runtime
SURVIVOR_DATA_RUNTIME_DIR = join(SURVIVOR_DATA_DIR, "Data", "Runtime")


#
# Executables
#
SEVEN_ZIP = join(SEVEN_ZIP_DIR, "7z.exe")


#
# Expose some environment variables that must be set
#
#if "PYTHONHOME" not in os.environ:
# raise Exception("The PYTHONHOME variable must be set!")
#PYTHON_HOME = os.environ["PYTHONHOME"]


class BGLImporter(object):
  """
  Customize Python module loading.  Only for modules starting 
  with bgl.  Check out PEP 302 for information about what I'm 
  doing here.

  """
  def __init__(self):
    self.jinja2 = None
    
    # Lookup table: "module_name" -> "path_to_module"
    self.import_redirects = { 
      "jinja2": join(BNE_LIB_TOOLS_DIR, "Jinja2-2.8"),
      "rk" : SURVIVOR_DATA_RUNTIME_DIR,
      "rki" : SURVIVOR_DATA_RUNTIME_DIR,

      "utils": BGL_DIR,
      # Add more modules here...
    }

    # Lookup table for modules already imported: "module_name" -> loaded_module_obj
    self.imported_modules = {}
    return

  
  def find_module(self, module_name, package_path):
    """
    Part of the Python Module Loader contract.
    We only handle module names starting with "bgl."

    """
    if module_name.startswith("bgl."):
      return self
    return None

    
  def load_module(self, module_name):
    """
    Load a module using a redirected path from a lookup table..

    """
    # We only care about modules starting with "bgl."
    if module_name.startswith("bgl."):
      module_name = module_name[4:]

      # Do we redirect this module?
      if module_name in self.import_redirects.keys():

        print module_name

        # If we redirect this module have we already loaded it?
        if module_name not in self.imported_modules:

          # We do redirect this module but haven't done so yet!
         # So load the module using the redirected path now.
          module_path = self.import_redirects[module_name]
          sys.path.append(module_path)
          module = importlib.import_module(module_name)
          self.imported_modules[module_name] = module

        # return the imported module
        return self.imported_modules[module_name]

    # we don't know how to load this module!
    return None
  

# register BGLImporter to customize module loading
sys.meta_path.append(BGLImporter())
