Import('env')

import os
import os.path
import sys

def run_doxygen(target, source, env):
    os.environ['PATH']=env['ENV']['PATH']
    env.Execute("doxygen --version")
    env.Execute("doxygen "+source[0].abspath)
def print_doxygen(target, source, env):
    print "running doxygen"
def print_generate_doxygen(target, source, env):
    print "generating doxygen configuration"


def make_output(nodes):
    return "     "+"\\\n     ".join(['"'+x.abspath+'"' for x in nodes])

# Generate doxygen.conf from doxygen.conf.in
def generate_doxygen(target, source, env):
    print "generating doxygen.conf"
    infile = file(source[0].path, 'r')
    outfile = file(target[0].path, 'w')
    source_path= os.path.split(os.path.split(os.path.split(source[0].abspath)[0])[0])[0]
    target_path= os.path.split(os.path.split(os.path.split(target[0].abspath)[0])[0])[0]
    print >> outfile, "# Auto-generated by SConscript; do NOT edit directly!"
    print >> outfile, "# Edit %s instead\n" % source[0].path
    examples=[]
    inputs=[]
    images=[]
    dots=[]
    has_dot=str(source[1].get_contents())
    for s in source[2:]:
        ss= str(s)
        if ss.endswith(".png"):
            images.append(s)
        else:
            put=False
            if ss.find('example') !=-1 and not ss.endswith(".dox"):
                examples.append(s)
                put=True
            if ss.endswith(".dox") \
                    or ss.endswith(".h"):
                inputs.append(s)
                put=True
            elif ss.endswith(".py"):
                put=True
                if ss.find("/_") ==-1 or ss.endswith("__init__.py"):
                    inputs.append(s)
            elif ss.endswith(".dot"):
                dots.append(s)
                put=True
            if not put:
                print >> sys.stderr, "Warning, do not know what to do with the file "+ ss
    for line in infile:
        if '@IMP_IMAGES@' in line:
            outfile.write(make_output(images))
        elif '@INPUTS@' in line:
            outfile.write(make_output(inputs))
        elif '@IMP_EXAMPLES@' in line:
            outfile.write(make_output(examples))
        elif '@IMP_DOTS@' in line:
            outfile.write(make_output(dots))
        elif '@IMP_SOURCE_PATH@' in line:
            outfile.write(line.replace('@IMP_SOURCE_PATH@', source_path))
        elif '@IMP_TARGET_PATH@' in line:
            outfile.write(line.replace('@IMP_TARGET_PATH@', target_path))
        elif '@IMP_ENABLED_SECTIONS@' in line:
            if has_dot == "True":
                outfile.write(line.replace('@IMP_ENABLED_SECTIONS@', "graphs"))
            else:
                outfile.write("")
        elif '@IMP_HAS_DOT@' in line:
            if has_dot=="True":
                outfile.write(line.replace('@IMP_HAS_DOT@', 'YES'))
            else:
                outfile.write(line.replace('@IMP_HAS_DOT@', 'NO'))
        elif not line.startswith('#'):
            outfile.write(line)
    infile.close()
    outfile.close()


def generate_example_index(target, source, env):
    print "generating index"
    outfile= open(target[0].abspath, "w")
    print >> outfile, """/** \page examples IMP Examples
Each modules has its own set of examples demonstrating how to use the features of that particular module."""
    for p in source:
        contents= open(p.abspath, "r").read()
        # rather dumb, I think
        name= contents[contents.find("\page")+6:].split(" ")[0]
        print >> outfile, " - \\ref "+name +"\n"
    print >> outfile, "*/"
    print "done generating examples"

if not env['doxygen']:
    print "Warning: IMP documentation requires doxygen."
    Return

env.Append(BUILDERS = {'RunDoxygen': Builder(action=env.Action(run_doxygen,
                                                               print_doxygen))})

docdir = env.GetInstallDirectory('docdir', 'html')

# Install all files from 'dox' directory into the 'docdir' directory (cannot
# use env.InstallAs() right now, due to scons bug #1751)

input_files=Glob("#/examples/README") +Glob("#/examples/*/README")\
    +Glob("#/examples/*.py") +Glob("#/examples/*/*.py")\
    +Glob("#/examples/*.cpp") +Glob("#/examples/*/*.cpp")

env.Append(BUILDERS = {'GenerateDoxygen': Builder(action=env.Action(generate_doxygen,
                                                                    print_generate_doxygen))})



env.Append(BUILDERS = {'GenerateExamples': Builder(action=generate_example_index)})

modexamples = Glob("#/modules/*/examples/.generated/examples.dox",
                   ondisk=False) \
              + ['#/kernel/examples/.generated/examples.dox']
example_index = env.GenerateExamples(".generated/all_examples.dox", modexamples)

rawheaders=[]
for h in Glob("#/build/include/*.h", ondisk=False) \
         + Glob("#/build/include/IMP/*.h", ondisk=False) \
         + Glob("#/build/include/IMP/*/*.h", ondisk=False):
    if h.path.find("internal")==-1:
        rawheaders.append(h)
headers=[]
first=[]
# leftover from attempt to get things to work with 1.6.1.
for h in rawheaders:
    if h.path.find('macros') == -1 and h.path.find('config.h') == -1:
        headers.append(h)
    else:
        first.append(h)
headers= first+headers
sources = headers + Glob("#/kernel/doc/*.dox") + [example_index] \
          + Glob("#/doc/*.dox") \
          + Glob("#/modules/*/doc/*.dox") \
          + Glob("#/modules/*/examples/*.xml") \
          + Glob("#/modules/*/examples/*/*.xml") \
          + Glob("#/kernel/doc/.generated/*.dox") \
          + Glob("#/modules/*/doc/.generated/*.dox") + modexamples \
          + Glob("#/modules/*/doc/*.dot") + Glob("#/kernel/doc/*.dot")

if env['python']:
    sources += Glob("#/build/lib/IMP/*.py", ondisk=False) \
               + Glob("#/build/lib/IMP/*/*.py", ondisk=False)
examples= Glob("#/modules/example/src/*.cpp") + Glob("#/build/include/IMP/example/*.h")\
    + Glob("#/modules/*/examples/*.py") + Glob("#/modules/*/examples/*/*.py")\
    + Glob("#/modules/*/examples/*.cpp") + Glob("#/modules/*/examples/*/*.cpp")\
    + Glob("#/modules/*/examples/.generated/*.html") \
    + Glob("#/modules/*/examples/*/.generated/*.html")\
    + Glob("#/kernel/examples/*.py") + Glob("#/kernel/examples/*/*.py")\
    + Glob("#/kernel/examples/*.cpp") + Glob("#/kernel/examples/*/*.cpp")\
    + Glob("#/kernel/examples/.generated/*.html") \
    + Glob("#/kernel/examples/*/.generated/*.html")\
    + Glob("#/modules/*/doc/*.dox") + Glob("#/modules/*/doc/*/*.dox")\
    + Glob("#/modules/*/doc/*.png") + Glob("#/modules/*/doc/*/*.png")\
    + Glob("#/modules/*/doc/*.html") + Glob("#/modules/*/doc/*/*.html")\
    + Glob("#/kernel/doc/*.dox") + Glob("#/kernel/doc/*/*.dox")\
    + Glob("#/kernel/doc/*.png") + Glob("#/kernel/doc/*/*.png")\
    + Glob("#/kernel/doc/*.html") + Glob("#/kernel/doc/*/*.html")\

#sources.sort()
examples.sort()

doxconf=env.GenerateDoxygen("doxygen.conf", ["doxygen.conf-in", env.Value(env['dot'])] +sources+examples)
env.Depends(doxconf, ['#/build/include'])

dox = env.RunDoxygen("#/build/doc/html/index.html", ["doxygen.conf"]+sources)
env.Depends(dox, '#/scons_tools/doxypy.py')
env.Requires(dox, env.Alias("doc-files"))

install=env.Command(Dir(env.subst(docdir)), dox,
                    "install -d $TARGET && cp -r ${SOURCE.dir}/* $TARGET")
env.Alias('doc-install', install)
env.Alias('doc', dox)
env.Requires(install, env.Alias('doc'))
env.Depends(env.Alias('all'), [env.Alias('doc')])
Clean(dox, Glob("#/build/doc/html/*"))
