#!/usr/bin/python

#We need command line arguments - stored in sys.argv (including script name)
import sys
moduleSourceFilename = sys.argv[1]

# we are using regular expression matching
import re

moduleRootPattern = re.compile( "(([\w_]+)Module)[\.][cC][pP]*" )
moduleRootMatches = moduleRootPattern.search( moduleSourceFilename )
moduleRoot = moduleRootMatches.group(1)
moduleRootBase = moduleRootMatches.group(2)

sourceFolderPattern = re.compile( "(.*[%/])[\w_]+[\.][cC][pP]*" )
sourceFolderMatches = sourceFolderPattern.match( moduleSourceFilename )
sourceFolder = sourceFolderMatches.group(1)

outfile = open( '../Lua/' + moduleRootBase + '.lua', 'w' )
outfile.write( 'module("' + moduleRootBase + '",package.seeall)\n' )
outfile.write( 'require("Tethys")\n' )
outfile.write( 'require("Units")\n' )

regComponentPattern = re.compile('[\s]+registerComponent[\(][\s]*new[\s]+([\w_]+)')
regMissionCompPattern = re.compile( '[\s]*registerBehaviorCreator[\(][\s]*([\w_]+)IF::' );
importInterfacePattern = re.compile( '#include[\s]+[\"]([\w/_]+IF.h)"' )
namespacePattern = re.compile( '[\s]*namespace[\s]+([\w_]+)' );
staticConstStrPattern = re.compile( '[\s]*static[\s]+const[\s]+Str[\s]+([\w_]+)[\(][\s]*[\"]([\w_]+)[\"]' )
missonComponentPattern = re.compile( '[\s]*:[\s]*MissionComponent[\s]*[\(][\s]*[^,]+,[^,]+,[\s]*([^,\s]+),[\s]*([^\)\s]+)' )
otherComponentPattern = re.compile( '[\s]*:[\s]*[\w]+[\s]*[\(]');
newInputReaderPattern = re.compile( '[\s]*[\w_]+[\s]*=[\s]*Slate::NewInputReader[\(][\s]*([\w:_]+)' )
newUniversalWriterPattern = re.compile( '[\s]*[\w_]+[\s]*=[\s]*Slate::NewUniversalWriter[\(][\s]*([\w:_]+)' )
universalURIPattern = re.compile( 'UniversalURI::([\w_]+)' )
enumStartPattern = re.compile( '[\s]*[\w_]+?[\s]*enum' )
enumItemPattern = re.compile( '[\s]*([\w_]+)' )
enumEndPattern = re.compile( '[\s]*[\}]' )
staticConstDoublePattern = re.compile( '[\s]*static[\s]+const[\s]+double[\s]+([\w_]+)[\s]*[\(][\s]*([^\s\)]+)[\s]*[\)]' )

moduleFile = open( moduleSourceFilename )
for moduleLine in moduleFile.readlines():

    componentClass = None
    isMissionComponentClass = False
    regComponentMatches = regComponentPattern.match( moduleLine )
    if regComponentMatches:
        componentClass = regComponentMatches.group( 1 )
    regMissionCompMatches = regMissionCompPattern.match( moduleLine )
    if regMissionCompMatches:
        componentClass = regMissionCompMatches.group( 1 )
        isMissionComponentClass = True;
    if not componentClass:
         continue

    itemType = None
    dict = {};
    classSourceFile = open( sourceFolder + componentClass + ".cpp" )
    for sourceLine in classSourceFile.readlines():
        
        importInterfaceMatches = importInterfacePattern.match( sourceLine )
        if importInterfaceMatches:
            interfacePath = importInterfaceMatches.group(1)
            if re.search( '/', interfacePath ) or interfacePath == "VehicleIF.h":
                interfacePath = "../Source/" + interfacePath
            else:
                interfacePath = sourceFolder + interfacePath
            
            namespace = "";
            interfaceFile = open( interfacePath )
            for ifLine in interfaceFile.readlines():
            
                namespaceMatches = namespacePattern.match( ifLine )
                if namespaceMatches:
                    namespace = namespaceMatches.group(1);
                    #print "namespace="+namespace
                    
                staticConstStrMatches = staticConstStrPattern.match( ifLine )
                if staticConstStrMatches:
                    id = staticConstStrMatches.group(1)
                    name = staticConstStrMatches.group(2)
                    dict[namespace + "::" + id ] = name
                    #print namespace + "::" + id + " = " + name
            interfaceFile.close() 
        
        key = None

        if not itemType:
            missionComponentMatches = missonComponentPattern.match( sourceLine ) 
            if missionComponentMatches:
                if missionComponentMatches.group(1) == "true":
                    if missionComponentMatches.group(2) == "true":
                        itemType = "SequenceType"
                    else:
                        itemType = "ParallelType"
                else:
                    itemType = "SettingType"
            else:
                otherComponentMatches = otherComponentPattern.match( sourceLine )
                if otherComponentMatches:
                    itemType = "SettingType"
            
            if itemType:
                outfile.write( '\n' )
                outfile.write( componentClass )                
                if isMissionComponentClass:
                    outfile.write( ' = __DECLARE_MISSION_COMPONENT("' )                
                else:
                    outfile.write( ' = __DECLARE_COMPONENT("' )                
                outfile.write( componentClass + '", "' + moduleRootBase + '");\n' )                
        
        newInputReaderMatches = newInputReaderPattern.match( sourceLine )
        if newInputReaderMatches:
            key = newInputReaderMatches.group(1)

        newUniversalWriterMatches = newUniversalWriterPattern.match( sourceLine )
        if newUniversalWriterMatches:
            key = newUniversalWriterMatches.group(1)

        if not key: 
            continue
            
        value = dict.get(key, None)
        
        if not value:
            universalURIMatches = universalURIPattern.match( key )
            if universalURIMatches:
                value = universalURIMatches.group(1).lower()
        
        if value:
            outfile.write( componentClass + '.' + value )
            outfile.write( ' = __DECLARE_URI("' + componentClass + '", "' )
            outfile.write( value + '", "' + moduleRootBase + '");\n' )

    classSourceFile.close()
    
    enumMode = False
    enumValue = 0;
    classInterfaceFile = open( sourceFolder + componentClass + "IF.h" )
    for ifLine in classInterfaceFile.readlines():        
        if enumMode:
            enumItemMatch = enumItemPattern.match( ifLine )
            if enumItemMatch:
                enumItem = enumItemMatch.group(1)
                outfile.write( componentClass + '.' + enumItem + '= Units.enum(' + str(enumValue) + ')\n')
                enumValue = enumValue + 1
            else:
                if enumEndPattern.match( ifLine ):
                    enumMode = True
                    enumValue = 0
        elif enumStartPattern.match( ifLine ):
                enumMode = True
        else:
            staticConstDoubleMatches = staticConstDoublePattern.match( ifLine )
            if staticConstDoubleMatches:
                varName = staticConstDoubleMatches.group(1)
                value = staticConstDoubleMatches.group(2)
                outfile.write( componentClass + '.' + varName + '= ' + value + '\n')
                
    classInterfaceFile.close()
        
moduleFile.close()

outfile.close()    
