# python

"""
Notes:

- TODO:
-- Database?
-- Install?
-- Debug compile

- Dependencies
-- Doable using just Scons?
-- If not fast enough, can probably be made fast by explicitly declaring
   them with the Java dependecy builder.
--- env.Depends()
-- Only directly build haks/erfs, make .ncs files their dependencies
   and let Scons derive from there?
"""

from os.path import basename, exists, join
import re

## Specific files and directories we need to muck about with

includedir = Dir("include")
othersdir = Dir("others")
_2dasdir = Dir("2das")

scrollmerch = othersdir.File("prc_scrolls.utm")

## Builders
# NWScript

nwscript = Builder(
    action = "wine tools/nwnnsscomp.exe -cq -i include $SOURCE $TARGET",
    suffix = ".ncs",
    src_suffix = ".nss")


# Haks / Erf

erf = Builder(
    action = ["-@rm -f $TARGET",
              Action("wine tools/erf.exe --create $TARGET $SOURCES",
                     "Packaging $TARGET")]
    )

erffromdir = Builder(
    action = ["-@rm -f $TARGET",
              Action("wine tools/erf.exe --create $TARGET $SOURCE/*",
                     "Packaging $TARGET from files in directory $SOURCE")],
    source_factory=Dir
    )

# TLK

tlk = Builder(
    action = ["-@rm -f $TARGET",
              Action("tools/linux/xml2tlk $SOURCE $TARGET",
                     "Building TLK from XML")]
    )

# Other stuff

scrollmerchbuild = Builder(
    action = ["-@mkdir scrolltemp",
              Action("java -Xmx200m -jar tools/prc.jar buildscrhack 2das tlk scrolltemp",
                     "Creating scrolls and updating 2das"),
              Action("java -cp ./tools/modpacker/nwn-tools.jar org.progeeks.nwn.XmlToGff scrolltemp scrolltemp/*.uti.xml",
                     "Converting scroll XML to UTI"),
              Action("java -cp ./tools/modpacker/nwn-tools.jar org.progeeks.nwn.XmlToGff . prc_scrolls.utm.xml",
                     "Converting scroll merchant XML to UTM"),
              "@mv scrolltemp/*.uti others/",
              "@mv prc_scrolls.utm others/",
              "@rm -rf scrolltemp",
              "@rm -f prc_scrolls.utm.xml",
              "@rm -f System.out"] # Bug in nwn-tools, produces this file
    )

## Include scanner

include_regex = re.compile("^#include\s+\"(\w+)\"", re.MULTILINE)

def scan_nwscript(node, env, path):
    contents = node.get_contents()
    return ["../include/%s.nss" % (name,)
            for name in include_regex.findall(contents)
            if exists(includedir.File("%s.nss" % (name,)).abspath)]

nss_scan = Scanner(function = scan_nwscript,
                   skeys = [".nss"],
                   recursive = True)

## File lists
def mkobjectlist(scripts, objectdir):
    return [join(objectdir, basename(script).replace(".nss", ".ncs"))
            for script in scripts]

# Scripts
scripts          = Glob("#/scripts/*.nss",          strings=True)
spells           = Glob("#/spells/*.nss",           strings=True)
epicspellscripts = Glob("#/epicspellscripts/*.nss", strings=True)
racescripts      = Glob("#/racescripts/*.nss",      strings=True)
psionics         = Glob("#/psionics/*.nss",         strings=True)
newspellbooks    = Glob("#/newspellbook/*.nss",     strings=True)
includes         = Glob("#/include/*.nss",          strings=True)

# Object files
objects          = mkobjectlist(scripts, "objs")
spellobjs        = mkobjectlist(spells, "spellobjs")
epicspellobjs    = mkobjectlist(epicspellscripts, "epicspellobjs")
raceobjs         = mkobjectlist(racescripts, "raceobjs")
psionicsobjs     = mkobjectlist(psionics, "psionicsobjs")
newspellbookobjs = mkobjectlist(newspellbooks, "newspellbookobjs")

# 2das
_2das            = Glob("#/2das/*.2da",             strings=True)
race2das         = Glob("#/race2das/*.2da",         strings=True)
craft2das        = Glob("#/Craft2das/*.2da",        strings=True)

# Misc
gfx              = Glob("#/gfx/*.*",                strings=True)
others           = Glob("#/others/*.*",             strings=True)

# Erfs
erffiles         = Glob("#/erf/*.*",                strings=True)
ocfixscripts     = Glob("#/ocfixerf/*.nss",         strings=True)
ocfixobjs        = mkobjectlist(ocfixscripts, "ocfixerfobjs")



## Building

env = Environment(BUILDERS = {'NWScript' : nwscript,
                              'Erf' : erf,
                              'ErfFromDir' : erffromdir,
                              'Tlk' : tlk,
                              'ScrollMerch' : scrollmerchbuild})
env.Append(SCANNERS = nss_scan)

def buildscripts(scriptlist, objectlist):
    # Note: Assumes objectlist was directly derived from scriptlist
    #       and is therefore in the same order.
    for (script, object) in zip(scriptlist, objectlist):
        env.NWScript(object, script)

def buildhak(name, filelist):
    env.Erf("#/CompiledResources/%s.hak" % (name,), filelist)

def builderf(name, filelist):
    env.Erf("#/CompiledResources/%s.erf" % (name,), filelist)

# Compiling scripts

buildscripts(scripts, objects)
buildscripts(spells, spellobjs)
buildscripts(epicspellscripts, epicspellobjs)
buildscripts(racescripts, raceobjs)
buildscripts(psionics, psionicsobjs)
buildscripts(newspellbooks, newspellbookobjs)
buildscripts(ocfixscripts, ocfixobjs)

# Convert TLK

env.Tlk("#/tlk/prc8_consortium.tlk", "#/tlk/prc8_consortium.tlk.xml")

# Building haks

buildhak("prc8_scripts", scripts + objects)
buildhak("prc8_spells", spells + spellobjs)
buildhak("prc8_epicspells", epicspellscripts + epicspellobjs)
buildhak("prc8_psionics", psionics + psionicsobjs)
buildhak("prc8_newspellbook", newspellbooks + newspellbookobjs)
buildhak("prc8_include", includes)
buildhak("prc8_race", racescripts + raceobjs + race2das)


buildhak("prc8_2das", _2das)
buildhak("prc8_textures", gfx)
buildhak("prc8_craft2das", craft2das)


# Building erfs

builderf("prc8_consortium", erffiles)
builderf("prc8_ocfix", ocfixscripts + ocfixobjs)


# Special handling for misc hak:
# Depends on the scroll merchant file, which may need to be generated / updated

env.ScrollMerch(scrollmerch,
                [_2dasdir.File("spells.2da"),
                 _2dasdir.File("des_crft_scroll.2da"),
                 _2dasdir.File("des_crft_spells.2da"),
                 _2dasdir.File("iprp_spells.2da")
                 ] +
                Glob("#/2das/cls_spcr_*.2da"))

# Can't use Erf rule, since something crashes with it
# So instead declared the dependencies explicitly and then use dir build rule
env.Depends("#/CompiledResources/prc8_misc.hak",
            others + [scrollmerch])

env.ErfFromDir("#/CompiledResources/prc8_misc.hak", "others")