import os
Import('env')

#
# Need to make a copy because SCons uses the environment
# at it's final state, so StGermain ends up depending on
# StgDomain, etc. 
#

env = env.Clone()
env['CURR_PROJECT'] = "StgFEM"

#
# Inside each project we will be accessing headers without the
# project name as a prefix, so we need to let SCons know how to
# find those headers.
#

env.Append(CPPPATH=env['build_dir'] + '/include/StgFEM')

#
# Need to include the StgFEM library for binaries/plugins.
#

libs = ['StgFEM'] + env.get('LIBS', [])

#
# Keep a list of all the objects we build so we can make a library
# afterwards.
#

objs = []
suites = []
tst_exp = []
tst_input = []

#
# Process each directory uniformly.
#

dirs = Split('Discretisation SLE/SystemSetup ' \
             'SLE/ProvidedSystems/AdvDiff_CharGalerkin SLE/ProvidedSystems/Energy ' \
             'SLE/ProvidedSystems/StokesFlow SLE/ProvidedSystems SLE ' \
             'Assembly libStgFEM Utils')
for d in dirs:

    # Need the module name, which is just the directory.
    mod_name = env['ESCAPE']('"' + ''.join(d.split('/')) + '"')
    cpp_defs = [('CURR_MODULE_NAME', mod_name)] + env.get('CPPDEFINES', []) 

    # Setup where to look for files.
    src_dir = d + '/src'
    inc_dir = 'include/StgFEM/' + d
    tst_dir = d + '/tests'
    tst_exp_dir = tst_dir + '/expected'
    tst_input_dir = tst_dir + '/input'
    tst_install_dir = 'tests/StgFEM/' + d

    hdrs = env.Install(os.path.join(env['build_dir'],inc_dir), Glob(src_dir + '/*.h'))

    # Build our source files.
    srcs = Glob(src_dir + '/*.c')
    for src in srcs:
        stg_cpp_defs = cpp_defs + [('SOURCE_FILE', '"\\"' + src.name + '\\""')]
        objs += env.SharedObject(src, CPPDEFINES=stg_cpp_defs)

    # Build any test suites we might find.
    # suites += env.Object(Glob(tst_dir + '/*Suite.c'))

    # Install any test expected and input files
    # tst_exp += env.Install(os.path.join(env['build_dir'],tst_install_dir,'/expected'), Glob(tst_exp_dir + '/*'))
    # tst_input += env.Install(os.path.join(env['build_dir'],tst_install_dir,'/input'), Glob(tst_input_dir + '/*'))

# Need to install headers from libStgFEM.
env.Install(os.path.join(env['build_dir'],'include/StgFEM'), Glob('libStgFEM/src/*.h'))


pluginDirs = ['libStgFEM/Toolbox',]

pl_objs = []
pl_regs = []
for d in pluginDirs:

    name = 'StgFEM_' + d.split('/')[-1] + 'module'
    mod_name = env['ESCAPE']('"' + ''.join(d.split('/')) + '"')
    cpp_defs = [('CURR_MODULE_NAME', mod_name)] + env.get('CPPDEFINES', []) 

    env.Install(os.path.join(env['build_dir'],'include/StgFEM/',d.split('/')[-1]), Glob(d + '/*.h'))

    srcs = Glob(d + '/*.c')
    cur_objs = env.SharedObject(srcs, CPPDEFINES=cpp_defs)

    # If we have shared libraries, build the dynamic plugin.
    if env['shared_libs']:
        lib_pre = env['LIBPREFIXES']
        if not isinstance(lib_pre, list):
            lib_pre = [lib_pre]
        env.SharedLibrary('lib/' + name, cur_objs,
                          SHLIBPREFIX='',
                          LIBPREFIXES=lib_pre + [''],
                          LIBS=libs)

    # If we are building static libs we need to construct a C file
    # mapping the plugin's name to its register function.
    if env['static_libs']:
        pl_regs += [name]

    # Keep track of all the plugin objects.
    pl_objs += cur_objs

#
# Build shared library.
#

if env['shared_libs']:
    env.SharedLibrary('lib/StgFEM', objs)
    env.SharedLibrary(env['prefix'] + '/lib/StgFEM', objs)

