#!/usr/bin/python

#
# Copyright 2003 TransGaming Technologies
#
# David Hammerton (david@transgaming.com)
#


import sys

class container:
    def __init__(self, fileReader, name, desc, parent):
        self.children = []
        self.properties = []
        self.name = name
        self.desc = desc
        self.parent = parent
        self.fileReader = fileReader
        self.fileReader.currentContainer = self
        if self.parent != 0:
            self.level = self.parent.level + 1
        else:
            self.level = 1

    def readLine(self, line):
        curspaces = 0
        if line[0] == "#": return # nothing to do
        while line[curspaces] == " ":
            curspaces = curspaces + 1
        if curspaces == 0: return # nothing to do
        if (self.level * 2) > curspaces:
            self.fileReader.currentContainer = self.parent
            self.parent.readLine(line)
            return
        splitline = line.split()
        if len(splitline) < 2:
            raise Exception("invalid line")
        if splitline[0] == "SubContainer":
            newContainer = container(self.fileReader, self.name + "_" + splitline[1], splitline[1], self)
            self.children.append(newContainer)
        elif splitline[0] == "Property":
            propval = "";
            i = 2
            while i < len(splitline):
              propval += splitline[i] + " "
              i = i + 1
            propval = (propval.strip()).strip("\"")
            property = ( splitline[1], propval )
            self.properties.append(property)
        else:
            raise Exception("invalid line")

class fileReader:
    def __init__(self, file):
        self.f = file

    def read(self):
        done = 0
        while (done == 0):
            rootline = self.f.readline()
            if rootline[0] == "R": done = 1
        if rootline != "Root\n":
            raise Exception('unexpected file format')
        for line in self.f.readlines():
            self.currentContainer.readLine(line)

class fileWriter:
    def __init__(self, file):
        self.f = file
        self.f.write("/* dxdiagn\n")
        self.f.write(" * AUTOMATICALLY GENERATED FILE - DO NOT EDIT\n")
        self.f.write(" * file generated by 'make_builtins.py'\n")
        self.f.write(" */\n\n")
        self.f.write('#include "windef.h"\n')
        self.f.write('#include "winbase.h"\n')
        self.f.write('#include "winuser.h"\n')
        self.f.write('#include "winnls.h"\n')
        self.f.write('#include "winreg.h"\n')
        self.f.write('#include "objbase.h"\n')
        self.f.write('#include "wine/debug.h"\n')
        self.f.write('#include "winerror.h"\n')
        self.f.write('#include "oleauto.h"\n')
        self.f.write("\n")
        self.f.write('#include "dxdiag.h"\n')
        self.f.write('#include "dxdiagn_private.h"\n')
        self.f.write("\n")
        self.f.write('extern ICOM_VTABLE(IDxDiagContainer) dxDiagContainerVT;\n')
        self.f.write("\n\n")

    def write(self, container):
        for subContainer in container.children:
            self.write(subContainer)
        self.f.write("/*********** Container: %s */\n\n" % container.name)
        self.f.write("WCHAR containerName_%s[] =\n" % container.name)
        self.f.write("  { ")
        for letter in container.desc:
            self.f.write("'%c' ," % letter)
        self.f.write("0 };\n")
        self.f.write("Container_SubContainer subConts_%s[] = {\n" % container.name)
        for subContainer in container.children:
            self.f.write("  { containerName_%s, &container_%s },\n" % ( subContainer.name, subContainer.name ))
        self.f.write("  { NULL, NULL }\n")
        self.f.write("};\n")
        for property in container.properties:
            self.f.write("WCHAR propertyName_%s_%s[] =\n" % ( container.name, property[0] ) )
            self.f.write("  { ")
            for letter in property[0]:
                self.f.write("'%c', " % letter)
            self.f.write("0 };\n")
            if property[0][0:2] == "sz" or property[0][0:3] == "ull":
                self.f.write("  WCHAR propertyWSTRVal_%s_%s[] = \n" % ( container.name, property[0] ) )
                self.f.write("    { ")
                for letter in property[1]:
                    self.f.write("'%c', " % letter)
                self.f.write("0 };\n")

        self.f.write("Container_Property properties_%s[] = {\n" % container.name)
        for property in container.properties:
            prop_dw = "0"
            prop_i = "0"
            prop_ull = "NULL"
            prop_l = "0"
            prop_b = "FALSE"
            prop_sz = "NULL"
            if property[0][0:2] == "dw":
                prop_dw = property[1]
                prop_type = "DXD_DWORD"
            elif property[0][0:1] == "i":
                prop_i = property[1]
                prop_type = "DXD_INT"
            elif property[0][0:3] == "ull":
                prop_ull = "propertyWSTRVal_%s_%s" % ( container.name, property[0] )
                prop_type = "DXD_ULL"
            elif property[0][0:1] == "l":
                prop_l = property[1]
                prop_type = "DXD_LONG"
            elif property[0][0:1] == "b":
                prop_b = property[1]
                prop_type = "DXD_BOOL"
            elif property[0][0:2] == "sz":
                prop_sz = "propertyWSTRVal_%s_%s" % ( container.name, property[0] )
                prop_type = "DXD_STR"
            else:
                raise Exception("invalid property tpye")
            self.f.write("  { propertyName_%s_%s, %s, %s, %s, %s, %s, %s, %s },\n" %
              ( container.name, property[0], prop_type, prop_dw, prop_i, prop_ull, prop_l, prop_b, prop_sz ))
        self.f.write("  { NULL, DXD_EMPTY, 0, 0, 0, 0, FALSE, NULL }")
        self.f.write("};\n")
        self.f.write("IDxDiagContainerImpl container_%s =\n" % container.name)
        self.f.write("                       { &dxDiagContainerVT, 1,\n")
        self.f.write("                         subConts_%s,\n" % container.name)
        self.f.write("                         properties_%s\n" % container.name)
        self.f.write("                       };\n\n\n")

try:
    fin = open('builtin_containers_dx9')
except IOError, e:
    print "couldn't open file: " + e.__str__()
    sys.exit(1)

try:
    fout = open('builtin_containers.c', 'w')
except IOError, e:
    print "couldn't open file: " + e.__str__()
    fin.close()
    sys.exit(1)


try:
    freader = fileReader(fin)
    rootContainer = container(freader, "root", "root", 0)
    freader.read()
    fin.close()
    fwriter = fileWriter(fout)
    fwriter.write(rootContainer)
    fout.close
except Exception, e:
    print "something bad happened: " + e.__str__()
    fin.close()
    fout.close()
    sys.exit(1)


