#!/usr/bin/env python

"""
journeylifter -- turn in-line track markers into a journey file.

Run in the scenario drectory of a campaign. Generates a journey.cfg and
rewrites the files to reference it.

All mainline campaigns have already undergone this conversion; this script
may be helpful with UMC.

Assumes any existing journey.cfg is generated and removes it.
Assumes wmllint has been run, converting DOT/CROSS macros to the new form.
Assumes the scenario's filenames sort in the order they present.
Assumes there is only one continuous span of journey markers per file.
"""

import os, sys, re, getopt, shutil

top = "."
if __name__ == "__main__":
    (options, arguments) = getopt.getopt(sys.argv[1:], "-d?hrc", [
        'directory',
        'help',
        'revert',
        'clean',
        ])
    revert = clean = False
    for (opt, val) in options:
        if opt in ('-d', '--directory'):
            top = val
        elif opt in ('-?', '-h', '-"# trackplacer: tracks begin\n'):
            print __doc__
            sys.exit(0)
        elif opt in ('-r', '--revert'):
            revert = True
        elif opt in ('-c', '--clean'):
            clean = True

    os.chdir(top)
    try:
        os.remove("journey.cfg")
    except OSError:
        pass
    files = filter(lambda x: x.endswith(".cfg"), os.listdir("."))
    files.sort()
    if revert:
        for name in files:
            if os.path.exists(name + ".bak"):
                os.rename(name + ".bak", name)
    elif clean:
        for name in files:
            if os.path.exists(name + ".bak"):
                os.remove(name + ".bak")
    else:
        jfp = open("journey.cfg", "w")
        jfp.write("# trackplacer: tracks begin\n\n")
        old_waypoint_re = re.compile("{OLD_[A-Z]+ +([0-9]+) +([0-9]+)}")
        new_waypoint_re = re.compile("{NEW_[A-Z]+ +([0-9]+) +([0-9]+)}")
        scenario_id_re = re.compile('id=[0-9]*_?"?([^"\n]*)')
        background_re = re.compile('background=.*')
        background = None
        mapfile = {}
        out = {}
        n = 0
        id_list = []
        indent = 8

        for name in files:
            out[name] = []
            lineno = 0
            scenario_id = None
            inside = False
            for line in open(name):
                lineno += 1
                if re.search(old_waypoint_re, line):
                    continue
                elif re.search(new_waypoint_re, line):
                    indent = 0
                    while line[indent] == ' ':
                        indent += 1
                    if not inside:
                        inside = True
                        n += 1
                        jfp.write("#define JOURNEY_STAGE%d\n" % n)
                        jfp.write("    # from %s, line %d\n" % (name, lineno))
                    jfp.write("    " + line.lstrip())
                elif re.search(background_re, line):
                    mapfile["JOURNEY_STAGE%d" % (n+1,)] = (line, name, lineno)
                    out[name].append(line)
                else:
                    if inside:
                        inside = False
                        jfp.write("#enddef\n\n")
                        out[name].append((" " * indent) + "{TO_%s}\n" % scenario_id)
                        id_list.append((scenario_id, name))
                    out[name].append(line)
                    if not scenario_id:
                        m = scenario_id_re.search(line)
                        if m:
                            scenario_id = m.group(1).upper()
        # Now edit out background lines in relevant [parts]s
        for (line, name, lineno) in mapfile.values():
            i = lineno
            while True:
                if '[part]' in out[name][i]:
                    break
                if 'background' in out[name][i]:
                    out[name] = out[name][:i] + out[name][i+1:]
                    break
                i -= 1
        # Done processing individual files, now write the journey postamble
        jfp.write("# trackplacer: tracks end\n")
        jfp.write("# wmllint: no translatables\n\n")
        n = 0
        for (scenario_id, name) in id_list:
            n += 1
            jfp.write("#define TO_%s\n" % scenario_id)
            jfp.write("    # from %s\n" % name)
            segment = "JOURNEY_STAGE%d" % n
            if segment in mapfile:
                (line, name, lineno) = mapfile[segment]
                jfp.write("    " + line.lstrip())
            jfp.write("    {%s}\n" % segment)
            jfp.write("#enddef\n\n")
        jfp.close()
        for name in files:
            os.rename(name, name + ".bak")
            open(name, "w").writelines(out[name])
