'''
Created on 02.08.2019

@author: mdoc
'''

from mutil.XmlExtractor import XmlExtractor
from mutil import XmlExtractor as XMLE
import re
'''
def outfirst(outfile, tpllayer, attrs, value):
    if tpllayer["value"]:
        ostr = tpllayer["value"]
        if "$value" in ostr:
            ostr = re.sub(r"\$value", value, ostr, flags=re.MULTILINE)
        print (ostr, end="", file=outfile)

def outlast(outfile, tpllayer, attrs, value):
    if tpllayer["value"]:
        print (file=outfile)
'''
def process_file_layer(source, outfile, global_defs, hierarc, functions, target):


    (ctl,elem, value, attrs) = source.extractElement(XMLE.EC_BEG)
    while ctl != XMLE.EC_END:
        items = None
        nexthiera = {}
        if elem in hierarc:
            items = hierarc[elem]
        elif elem in global_defs:
            items = global_defs[elem]
        elif elem == "verbatim" and attrs["target"] == target:
            print (value, end="", file=outfile)
        #elif elem == "exec":
        #    r = eval(functions[attrs["function"]])
        #    print (r, end="", file=outfile)
        else:
            print ("Warning: No mapping for item:" +elem)
        if items:
            # search for "first"
            for item in items:
                if "position" in item["attrs"]:
                    if item["attrs"]["position"] == "first":
                        print (item["value"], end="", file=outfile)
            # proceed working
            for item in items:
                if not "position" in item["attrs"]:
                    # determine line end
                    end = "\n"
                    if "end" in item["attrs"]:
                        end = item["attrs"]["end"]
                    # check "pre"
                    if "pre" in item["attrs"]:
                        text = item["attrs"]["pre"]
                        if text.startswith(r"\n"):
                            print (file=outfile)
                            text = text[2:]
                        print (text, end="", file=outfile)
                    if "exec" in item["attrs"]:
                        # call function
                        store_current_node = source.currentNode
                        l = {"out" : None, "source":source}
                        exec(functions[item["attrs"]["exec"]], globals(), l)
                        # proceed on previous position
                        source.currentNode = store_current_node
                        print (l["out"], file=outfile)
                    else:
                        # proceed working
                        nexthiera = item["items"]
                        if value:
                            print (value, end="", file=outfile)
                        process_file_layer(source, outfile, global_defs, nexthiera, functions, target)
                    # check "post"
                    if "post" in item["attrs"]:
                        print (item["attrs"]["post"], end="", file=outfile)
                    print (end=end, file=outfile)
            # search for "last"
            for item in items:
                if "position" in item["attrs"]:
                    if item["attrs"]["position"] == "last":
                        print (item["value"], end="", file=outfile)

        (ctl,elem, value, attrs) = source.extractElement(ctl)
        
def convert (file, format):
    
    source = XmlExtractor()
    source.openInput(file)

    # read whole template
    tple = XmlExtractor()
    tpl = tple.readFile("tpl/"+format+".tpl")
    functions_in_file = tpl["mdoc"][0]["items"]["functions"][0]["items"]["function"]
    # compile functions
    functions = {}
    for f in functions_in_file:
        name = f["attrs"]["name"]
        functions[name] = compile(f["value"], '<string>', "exec")
    
    global_defs = tpl["mdoc"][0]["items"]["global"][0]["items"]
    hierarc = tpl["mdoc"][0]["items"]["hierarchical"][0]["items"]
    
    # open output file
    ext = tpl["mdoc"][0]["attrs"]["extension"]
    outname = re.sub(r"\.xml", "."+ext, file)
    outfile = open(outname, "w")
    #print ("hallo", file=outfile)
    
    process_file_layer(source, outfile, global_defs, hierarc, functions, format)
    
