#! /usr/local/bin/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'

# Check that string is a legal C identifier
def checkid(str):
    if not str: return 0
    if not str[0] in string.letters+'_':
	return 0
    for c in str[1:]:
	if not c in string.letters+string.digits+'_':
	    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'+`i+1`
	    rv = rv + objects[i].gencode(oname)
	    onames.append(oname)
	rv = rv + (name+' = genmodule.module()\n')
	rv = rv + (name+'.name = '+`self.name_entry.get()`+'\n')
	rv = rv + (name+'.abbrev = '+`self.abbrev_entry.get()`+'\n')
	rv = rv + (name+'.methodlist = '+`getlistlist(self.method_list)`+'\n')
	rv = rv + (name+'.objects = ['+string.joinfields(onames, ',')+']\n')
	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'+`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 + (name+' = genmodule.object()\n')
	rv = rv + (name+'.name = '+`self.name_entry.get()`+'\n')
	rv = rv + (name+'.abbrev = '+`self.abbrev_entry.get()`+'\n')
	rv = rv + (name+'.methodlist = '+`getlistlist(self.method_list)`+'\n')
	fl = []
	for fn in genmodule.FUNCLIST:
	    vname = self.vpref + fn
	    if self.f5.getvar(vname) == '1':
		fl.append(fn)
	rv = rv + (name+'.funclist = '+`fl`+'\n')

	fl = []
	for fn in genmodule.TYPELIST:
	    vname = self.vpref + fn
	    if self.f5.getvar(vname) == '1':
		fl.append(fn)
		
	rv = rv + (name+'.typelist = '+`fl`+'\n')

	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()
