"""
    Autodoc.py
    
    generates html docs from nebula cmd source files.

    Run from within nebula/bin,
    html files are created in nebula/doc/autodoc.

    30-Aug-01   leaf    created.
    
"""
import os, fnmatch, re, time

# global dict of all classes
classes = {}

class aCmd:
    "simple structure for storing cmd details"
    name = ""
    input = ""
    output = ""
    info = ""
    def __repr__(self):
        return self.name

class aClass:
    "simple structure for storing class details"
    name = ""
    info = ""
    def findSubclasses(self):
        """recursively finds subclasses, adds them as
        subclasses list (very brute force)."""
        self.subclasses = []
        for k in classes.keys():
            if classes[k].superclass == self.name:
                classes[k].findSubclasses()
                self.subclasses.append(classes[k])
        self.subclasses.sort()
    def __repr__(self):
        return self.name
    def __cmp__(self, other):
        if self.name < other.name: return -1
        if self.name > other.name: return 1
        return 0

# regular expressions to extract class/cmd info
rClass = re.compile(r"@scriptclass\s*(?P<classname>\S*)\s*@superclass\s*(?P<superclass>\S*)\s*@classinfo\s*(?P<info>.*?)\s*\*/", re.S)
rCmd = re.compile(r"@cmd\s*(?P<cmd>\S*)\s*@input\s*(?P<input>.*?)\s*@output\s*(?P<output>.*?)\s*@info\s*(?P<info>.*?)\s*\*/", re.S)

def scanFiles(pathname):
    """Recursively scans a directory tree,
    looking for *_cmds.cc files and extracting
    class/cmd information from them."""
    dirlist = os.listdir(pathname)
    for filename in dirlist:
        path = os.path.join(pathname, filename)
        if os.path.isdir(path):
            scanFiles(path)
        if fnmatch.fnmatch(filename, "*_cmds.cc"):
            fp = open(path, "r")
            file = fp.read()
            mClass = rClass.search(file)
            if mClass:
                clas = aClass()
                clas.name = mClass.group('classname')
                clas.superclass = mClass.group('superclass')
                clas.info = mClass.group('info')
                cmds = []
                mCmd = rCmd.search(file)
                while mCmd:
                    cmd = aCmd()
                    cmd.name = mCmd.group('cmd')
                    cmd.input = mCmd.group('input')
                    cmd.output = mCmd.group('output')
                    cmd.info = mCmd.group('info')
                    cmds.append(cmd)
                    mCmd = rCmd.search(file, mCmd.end())
                clas.cmds = cmds
                classes[clas.name] = clas
            fp.close()

# functions for creating the html
def classTree(clas, indent = 0):
    out = indent*" " + '<a href="cmds.html#%s" target="cmds"><b>%s</b></a>\n' % (clas.name, clas.name)
    indent += 2
    for sc in clas.subclasses:
        out += classTree(sc, indent)
    indent -= 2
    return out

def classInfo(clas):
    out =  "<table width=\"100%%\" bgcolor=\"#88ccaa\">"
    out += "<td align='center'><h2><a name=\"%s\">class %s</a></h2></td></table>\n" % (clas.name, clas.name)
    out += "<ul><b>super class:</b>\n<ul>%s</ul>\n" % (clas.superclass)
    out += "<b>info:</b>\n<ul><pre>%s</pre></ul>\n" % (clas.info.replace("\n    ","\n"))
    out += "<b>commands:</b>\n"
    out += "<ul><table width=\"60%%\"><td>"
    for cmd in clas.cmds:
        out += "<a href=\"#%s\">%s</a> " % (clas.name+cmd.name, cmd.name)
    out += "</td></table></ul></ul><br/>"
    return out

def cmdBlock(cmd, clas):
    out = "<table width=\"100%%\" bgcolor=\"#99bbdd\"><td><h3><a name=\"%s\">%s</a></h3></td></table>\n" % (clas.name+cmd.name, cmd.name)
    out += "<ul><b>input:</b><ul>%s</ul>\n" % (cmd.input)
    out += "<b>output:</b><ul>%s</ul>\n" % (cmd.output)
    out += "<b>info:</b><ul><pre>%s</pre></ul></ul>\n" % (cmd.info.replace("\n    ","\n"))
    return out

def classBlock(clas):
    out = classInfo(clas)
    for cmd in clas.cmds:
        out += cmdBlock(cmd, clas)
    out += "</ul><hr color='#000000'/><br/>\n"
    return out

def cmdsPage(root):
    out = classBlock(root)
    for clas in root.subclasses:
        out += cmdsPage(clas)
    return out

# parse all the cmd files
pathname = "../code/src/"
scanFiles(pathname)

# create html files
root = classes['nroot']
root.findSubclasses()
out =  """
<html>
    <head>
        <style>
            A { font-family: 'verdana, sans-serif';};
        </style>
    </head>
    <body bgcolor="#aaccee" text="#000000">
        <pre>"""
out += classTree(root)
out += """
        </pre>
    </body>
</html>"""

fp = open("../doc/autodoc/hierarchy.html","w")
fp.write(out)
fp.close()


out = """
<html>
    <head>
        <style>
            PRE,UL,H2,H3,B     {font-family: 'verdana, sans-serif';};
        </style>
    </head>
    <body bgcolor="#aaccee" text="#000000">
    """
out += cmdsPage(root)
out += """
    </body>
</html>"""

fp = open("../doc/autodoc/cmds.html","w")
fp.write(out)
fp.close()

out = """
<html>
    <head>
	<title>Nebula Script Commands (generated %s)</title>
    </head>
    <frameset cols="30%%,*">
	<frame src="hierarchy.html" target="cmds">
	<frame src="cmds.html" name="cmds">
    </frameset>
</html>""" % (time.strftime("%d/%m/%y %H:%M"))

fp = open("../doc/autodoc/autodoc.html","w")
fp.write(out)
fp.close()





