#! /usr/bin/env python
#
# Modulator - Generate skeleton modules.
#
# The user fills out some forms with information about what the module
# should support (methods, objects), names of these things, prefixes to
# use for C code, whether the objects should also support access as numbers,
# etc etc etc.
# When the user presses 'Generate code' we generate a complete skeleton
# module in C.
#
# Alternatively, the selections made can be save to a python sourcefile and
# this sourcefile can be passed on the command line (resulting in the same
# skeleton C code).
#
# Jack Jansen, CWI, October 1994.
#

import sys, os
if os.name <> 'mac':
    sys.path.append(os.path.join(os.environ['HOME'],
                                 'src/python/Tools/modulator'))

from Tkinter import *
from Tkextra import *
from ScrolledListbox import ScrolledListbox
import sys
import genmodule
import string

oops = 'oops'

IDENTSTARTCHARS = string.letters + '_'
IDENTCHARS = string.letters + string.digits + '_'

# Check that string is a legal C identifier
def checkid(str):
    if not str: return 0
    if not str[0] in IDENTSTARTCHARS:
        return 0
    for c in str[1:]:
        if not c in IDENTCHARS:
            return 0
    return 1

def getlistlist(list):
    rv = []
    n = list.size()
    for i in range(n):
        rv.append(list.get(i))
    return rv

class UI:
    def __init__(self):
        self.main = Frame()
        self.main.pack()
        self.main.master.title('Modulator: Module view')
        self.cmdframe = Frame(self.main, {'relief':'raised', 'bd':'0.5m',
                                          Pack:{'side':'top',
                                                 'fill':'x'}})
        self.objframe = Frame(self.main, {Pack:{'side':'top', 'fill':'x',
                                                'expand':1}})


        self.check_button = Button(self.cmdframe,
                                  {'text':'Check', 'command':self.cb_check,
                                   Pack:{'side':'left', 'padx':'0.5m'}})
        self.save_button = Button(self.cmdframe,
                                  {'text':'Save...', 'command':self.cb_save,
                                   Pack:{'side':'left', 'padx':'0.5m'}})
        self.code_button = Button(self.cmdframe,
                                  {'text':'Generate code...',
                                   'command':self.cb_gencode,
                                   Pack:{'side':'left', 'padx':'0.5m'}})
        self.quit_button = Button(self.cmdframe,
                                  {'text':'Quit',
                                   'command':self.cb_quit,
                                   Pack:{'side':'right', 'padx':'0.5m'}})

        self.module = UI_module(self)
        self.objects = []
        self.modified = 0

    def run(self):
        self.main.mainloop()

    def cb_quit(self, *args):
        if self.modified:
            if not askyn('You have not saved\nAre you sure you want to quit?'):
                return
        sys.exit(0)

    def cb_check(self, *args):
        try:
            self.module.synchronize()
            for o in self.objects:
                o.synchronize()
        except oops:
            pass

    def cb_save(self, *args):
        try:
            pycode = self.module.gencode('m', self.objects)
        except oops:
            return

        fn = askfile('Python file name: ')
        if not fn:
            return

        fp = open(fn, 'w')

        fp.write(pycode)
        fp.close()

    def cb_gencode(self, *args):
        try:
            pycode = self.module.gencode('m', self.objects)
        except oops:
            pass

        fn = askfile('C file name: ')
        if not fn:
            return

        fp = open(fn, 'w')

        try:
            exec pycode
        except:
            message('An error occurred:-)')
            return
        genmodule.write(fp, m)
        fp.close()

class UI_module:
    def __init__(self, parent):
        self.parent = parent
        self.frame = Frame(parent.objframe, {'relief':'raised', 'bd':'0.2m',
                                             Pack:{'side':'top',
                                                   'fill':'x'}})
        self.f1 = Frame(self.frame, {Pack:{'side':'top', 'pady':'0.5m',
                                           'fill':'x'}})
        self.f2 = Frame(self.frame, {Pack:{'side':'top', 'pady':'0.5m',
                                           'fill':'x'}})
        self.f3 = Frame(self.frame, {Pack:{'side':'top', 'pady':'0.5m',
                                           'fill':'x'}})
        self.f4 = Frame(self.frame, {Pack:{'side':'top', 'pady':'0.5m',
                                           'fill':'x'}})

        self.l1 = Label(self.f1, {'text':'Module:', Pack:{'side':'left',
                                                        'padx':'0.5m'}})
        self.name_entry = Entry(self.f1, {'relief':'sunken',
                              Pack:{'side':'left', 'padx':'0.5m', 'expand':1}})
        self.l2 = Label(self.f1, {'text':'Abbrev:', Pack:{'side':'left',
                                                        'padx':'0.5m'}})
        self.abbrev_entry = Entry(self.f1, {'relief':'sunken', 'width':5,
                              Pack:{'side':'left', 'padx':'0.5m'}})

        self.l3 = Label(self.f2, {'text':'Methods:', Pack:{'side':'left',
                                                        'padx':'0.5m'}})
        self.method_list = ScrolledListbox(self.f2, {'relief':'sunken','bd':2,
                                      Pack:{'side':'left', 'expand':1,
                                            'padx':'0.5m', 'fill':'both'}})

        self.l4 = Label(self.f3, {'text':'Add method:', Pack:{'side':'left',
                                                              'padx':'0.5m'}})
        self.method_entry = Entry(self.f3, {'relief':'sunken',
                             Pack:{'side':'left', 'padx':'0.5m', 'expand':1}})
        self.method_entry.bind('<Return>', self.cb_method)
        self.delete_button = Button(self.f3, {'text':'Delete method',
                                              'command':self.cb_delmethod,
                                              Pack:{'side':'left',
                                                    'padx':'0.5m'}})

        self.newobj_button = Button(self.f4, {'text':'new object',
                                              'command':self.cb_newobj,
                                              Pack:{'side':'left',
                                                    'padx':'0.5m'}})

    def cb_delmethod(self, *args):
        list = self.method_list.curselection()
        for i in list:
            self.method_list.delete(i)

    def cb_newobj(self, *arg):
        self.parent.objects.append(UI_object(self.parent))

    def cb_method(self, *arg):
        name = self.method_entry.get()
        if not name:
            return
        self.method_entry.delete('0', 'end')
        self.method_list.insert('end', name)

    def synchronize(self):
        n = self.name_entry.get()
        if not n:
            message('Module name not set')
            raise oops
        if not checkid(n):
            message('Module name not an identifier:\n'+n)
            raise oops
        if not self.abbrev_entry.get():
            self.abbrev_entry.insert('end', n)
        m = getlistlist(self.method_list)
        for n in m:
            if not checkid(n):
                message('Method name not an identifier:\n'+n)
                raise oops

    def gencode(self, name, objects):
        rv = ''
        self.synchronize()
        for o in objects:
            o.synchronize()
        onames = []
        for i in range(len(objects)):
            oname = 'o%d' % (i+1)
            rv = rv + objects[i].gencode(oname)
            onames.append(oname)
        rv = rv + '%s = genmodule.module()\n' % (name,)
        rv = rv + '%s.name = %r\n' % (name, self.name_entry.get())
        rv = rv + '%s.abbrev = %r\n' % (name, self.abbrev_entry.get())
        rv = rv + '%s.methodlist = %r\n' % (name, getlistlist(self.method_list))
        rv = rv + '%s.objects = [%s]\n' % (name, ','.join(onames))
        rv = rv + '\n'
        return rv

object_number = 0

class UI_object:
    def __init__(self, parent):
        global object_number

        object_number = object_number + 1
        self.num = object_number
        self.vpref = 'o%r_' % self.num
        self.frame = Toplevel(parent.objframe)
#       self.frame.pack()
        self.frame.title('Modulator: object view')
#       self.frame = Frame(parent.objframe, {'relief':'raised', 'bd':'0.2m',
#                                            Pack:{'side':'top',
#                                                  'fill':'x'}})
        self.f1 = Frame(self.frame, {Pack:{'side':'top', 'pady':'0.5m',
                                           'fill':'x'}})
        self.f2 = Frame(self.frame, {Pack:{'side':'top', 'pady':'0.5m',
                                           'fill':'x'}})
        self.f3 = Frame(self.frame, {Pack:{'side':'top', 'pady':'0.5m',
                                           'fill':'x'}})
        self.f4 = Frame(self.frame, {Pack:{'side':'top', 'pady':'0.5m',
                                           'fill':'x'}})


        self.l1 = Label(self.f1, {'text':'Object:', Pack:{'side':'left',
                                                        'padx':'0.5m'}})
        self.name_entry = Entry(self.f1, {'relief':'sunken',
                              Pack:{'side':'left', 'padx':'0.5m', 'expand':1}})
        self.l2 = Label(self.f1, {'text':'Abbrev:', Pack:{'side':'left',
                                                        'padx':'0.5m'}})
        self.abbrev_entry = Entry(self.f1, {'relief':'sunken', 'width':5,
                              Pack:{'side':'left', 'padx':'0.5m'}})

        self.l3 = Label(self.f2, {'text':'Methods:', Pack:{'side':'left',
                                                        'padx':'0.5m'}})
        self.method_list = ScrolledListbox(self.f2, {'relief':'sunken','bd':2,
                                      Pack:{'side':'left', 'expand':1,
                                            'padx':'0.5m', 'fill':'both'}})

        self.l4 = Label(self.f3, {'text':'Add method:', Pack:{'side':'left',
                                                              'padx':'0.5m'}})
        self.method_entry = Entry(self.f3, {'relief':'sunken',
                             Pack:{'side':'left', 'padx':'0.5m', 'expand':1}})
        self.method_entry.bind('<Return>', self.cb_method)
        self.delete_button = Button(self.f3, {'text':'Delete method',
                                              'command':self.cb_delmethod,
                                              Pack:{'side':'left',
                                                    'padx':'0.5m'}})


        self.l5 = Label(self.f4, {'text':'functions:',
                                  Pack:{'side':'left',
                                        'padx':'0.5m'}})
        self.f5 = Frame(self.f4, {Pack:{'side':'left', 'pady':'0.5m',
                                           'fill':'both'}})
        self.l6 = Label(self.f4, {'text':'Types:',
                                  Pack:{'side':'left', 'padx':'0.5m'}})
        self.f6 = Frame(self.f4, {Pack:{'side':'left', 'pady':'0.5m',
                                           'fill':'x'}})
        self.funcs = {}
        for i in genmodule.FUNCLIST:
            vname = self.vpref+i
            self.f5.setvar(vname, 0)
            b = Checkbutton(self.f5, {'variable':vname, 'text':i,
                                      Pack:{'side':'top', 'pady':'0.5m',
                                            'anchor':'w','expand':1}})
            self.funcs[i] = b
        self.f5.setvar(self.vpref+'new', 1)

        self.types = {}
        for i in genmodule.TYPELIST:
            vname = self.vpref + i
            self.f6.setvar(vname, 0)
            b = Checkbutton(self.f6, {'variable':vname, 'text':i,
                                      Pack:{'side':'top', 'pady':'0.5m',
                                            'anchor':'w'}})
            self.types[i] = b

    def cb_method(self, *arg):
        name = self.method_entry.get()
        if not name:
            return
        self.method_entry.delete('0', 'end')
        self.method_list.insert('end', name)

    def cb_delmethod(self, *args):
        list = self.method_list.curselection()
        for i in list:
            self.method_list.delete(i)

    def synchronize(self):
        n = self.name_entry.get()
        if not n:
            message('Object name not set')
            raise oops
        if not self.abbrev_entry.get():
            self.abbrev_entry.insert('end', n)
        n = self.abbrev_entry.get()
        if not checkid(n):
            message('Abbreviation not an identifier:\n'+n)
            raise oops
        m = getlistlist(self.method_list)
        for n in m:
            if not checkid(n):
                message('Method name not an identifier:\n'+n)
                raise oops
        if m:
            self.f5.setvar(self.vpref+'tp_getattr', 1)
        pass

    def gencode(self, name):
        rv = ''
        rv = rv + '%s = genmodule.object()\n' % (name,)
        rv = rv + '%s.name = %r\n' % (name, self.name_entry.get())
        rv = rv + '%s.abbrev = %r\n' % (name, self.abbrev_entry.get())
        rv = rv + '%s.methodlist = %r\n' % (name, getlistlist(self.method_list))
        fl = []
        for fn in genmodule.FUNCLIST:
            vname = self.vpref + fn
            if self.f5.getvar(vname) == '1':
                fl.append(fn)
        rv = rv + '%s.funclist = %r\n' % (name, fl)

        fl = []
        for fn in genmodule.TYPELIST:
            vname = self.vpref + fn
            if self.f5.getvar(vname) == '1':
                fl.append(fn)

        rv = rv + '%s.typelist = %r\n' % (name, fl)

        rv = rv + '\n'
        return rv


def main():
    if len(sys.argv) < 2:
        ui = UI()
        ui.run()
    elif len(sys.argv) == 2:
        fp = open(sys.argv[1])
        pycode = fp.read()
        try:
            exec pycode
        except:
            sys.stderr.write('An error occurred:-)\n')
            sys.exit(1)
        ##genmodule.write(sys.stdout, m)
    else:
        sys.stderr.write('Usage: modulator [file]\n')
        sys.exit(1)

main()
