import re
from distutils.cmd import Command
from time import strftime
from pretty_printer import PrettyPrinter

class Protoize(Command):
    description = 'generate adesklets.commands module'
    user_options = []
    def __init__(self,dist):
        Command.__init__(self,dist)
        self.pp=PrettyPrinter(80,'adesklets/commands.py')
        
    def initialize_options(self):
        pass
    def finalize_options(self):
        pass
    def run(self):
        # Usefull regular expressions
        re_asterix=re.compile('\*')
        re_brackets=re.compile('^\[(.*)\]$')
        re_boolean=re.compile('\s?bool\s+')
        re_spaces=re.compile('\s+')

        # Open and read files
        fd=file('../enums', 'r')
        lines=fd.readlines()
        fd.close()
        fd=file('../prototypes','r')
        lines2=fd.readlines()
        fd.close()
        
        # Ouput the prelude
        print '"""'
        print 'adesklets commands module'
        print
        print '===', strftime('%Y-%m-%d %H:%M:%S'), '==='
        print 'Automatically generated by `setup.py protoize\' from'
        print 'files `../prototypes\' and `../enums\'.'
        print str(len(lines)) + ' constants and ' + str(len(lines2)) + ' functions successfully created.'
        print 
        print '"""'
        print '# Imports'
        print '#'
        print 'from error_handler import ADESKLETSError'
        print 'import commands_handler'
        print 'import strings'
        print
        print '# Constants'
        print '#'

        for name,value in map(lambda x: x.strip().split('\t'), lines):
            print '%-20s = %2d' % (name,int(value))

        print
        print '# Functions'
        print '#'
        for line in lines2:
            cmd,help,proto=line.strip().split('\t')
            args=[]
            if proto!='void':
                match=re_brackets.match(proto)
                if match:
                    newproto=match.expand('\\1')
                    optional=True
                else:
                    newproto=proto
                    optional=False
                for param in newproto.split(','):
                    if re_asterix.search(param):
                        param=re_asterix.sub('',param)
                        stringify=True
                    else:
                        if re_boolean.search(param):
                            stringify=True
                        else:
                            stringify=False
                    args.append((param.split()[-1],optional or stringify))
                
            # Ok, now we collected all needed information,
            # so let's define the function
            output=''
            for arg in args:
                output+=arg[0] + ' '
            if optional:
                output=re_spaces.sub('=None ',output)
            output=re_spaces.sub(', ',output.strip())
            self.pp.state=True
            print 'def', cmd + '(' + output + '):'
            print '\t"""'
            print '\t' + help
            self.pp.state=False
            print
            self.pp.state=True
            print '\t'+proto
            print '\t"""'
            self.pp.state=False
            print '\tcomm=commands_handler._Static_commands_handler()'
            if len(args)>0:
                print '\tprint >> comm,',"'"+cmd+"',",
                output=''
                for arg, stringify in args:
                    if stringify:
                        output+='strings.String('+arg+') '
                    else:
                        output+=arg + ' '
                output=re_spaces.sub(', ',output.strip())
                print output
            else:
                print '\tprint >> comm,',"'"+cmd+"'"
            print '\treturn comm.out()\n'

        # Close file
        fd.close()

