#
# flp - Module to load fl forms from fd files
#
# Jack Jansen, December 1991
#
import os
import sys
import FL

SPLITLINE = '--------------------'
FORMLINE = '=============== FORM ==============='
ENDLINE = '=============================='

class error(Exception):
    pass

##################################################################
#    Part 1 - The parsing routines                               #
##################################################################

#
# Externally visible function. Load form.
#
def parse_form(filename, formname):
    forms = checkcache(filename)
    if forms is None:
        forms = parse_forms(filename)
    if forms.has_key(formname):
        return forms[formname]
    else:
        raise error, 'No such form in fd file'

#
# Externally visible function. Load all forms.
#
def parse_forms(filename):
    forms = checkcache(filename)
    if forms is not None: return forms
    fp = _open_formfile(filename)
    nforms = _parse_fd_header(fp)
    forms = {}
    for i in range(nforms):
        form = _parse_fd_form(fp, None)
        forms[form[0].Name] = form
    writecache(filename, forms)
    return forms

#
# Internal: see if a cached version of the file exists
#
MAGIC = '.fdc'
_internal_cache = {}                    # Used by frozen scripts only
def checkcache(filename):
    if _internal_cache.has_key(filename):
        altforms = _internal_cache[filename]
        return _unpack_cache(altforms)
    import marshal
    fp, filename = _open_formfile2(filename)
    fp.close()
    cachename = filename + 'c'
    try:
        fp = open(cachename, 'r')
    except IOError:
        #print 'flp: no cache file', cachename
        return None
    try:
        if fp.read(4) != MAGIC:
            print 'flp: bad magic word in cache file', cachename
            return None
        cache_mtime = rdlong(fp)
        file_mtime = getmtime(filename)
        if cache_mtime != file_mtime:
            #print 'flp: outdated cache file', cachename
            return None
        #print 'flp: valid cache file', cachename
        altforms = marshal.load(fp)
        return _unpack_cache(altforms)
    finally:
        fp.close()

def _unpack_cache(altforms):
        forms = {}
        for name in altforms.keys():
            altobj, altlist = altforms[name]
            obj = _newobj()
            obj.make(altobj)
            list = []
            for altobj in altlist:
                nobj = _newobj()
                nobj.make(altobj)
                list.append(nobj)
            forms[name] = obj, list
        return forms

def rdlong(fp):
    s = fp.read(4)
    if len(s) != 4: return None
    a, b, c, d = s[0], s[1], s[2], s[3]
    return ord(a)<<24 | ord(b)<<16 | ord(c)<<8 | ord(d)

def wrlong(fp, x):
    a, b, c, d = (x>>24)&0xff, (x>>16)&0xff, (x>>8)&0xff, x&0xff
    fp.write(chr(a) + chr(b) + chr(c) + chr(d))

def getmtime(filename):
    import os
    from stat import ST_MTIME
    try:
        return os.stat(filename)[ST_MTIME]
    except os.error:
        return None

#
# Internal: write cached version of the form (parsing is too slow!)
#
def writecache(filename, forms):
    import marshal
    fp, filename = _open_formfile2(filename)
    fp.close()
    cachename = filename + 'c'
    try:
        fp = open(cachename, 'w')
    except IOError:
        print 'flp: can\'t create cache file', cachename
        return # Never mind
    fp.write('\0\0\0\0') # Seek back and write MAGIC when done
    wrlong(fp, getmtime(filename))
    altforms = _pack_cache(forms)
    marshal.dump(altforms, fp)
    fp.seek(0)
    fp.write(MAGIC)
    fp.close()
    #print 'flp: wrote cache file', cachename

#
# External: print some statements that set up the internal cache.
# This is for use with the "freeze" script.  You should call
# flp.freeze(filename) for all forms used by the script, and collect
# the output on a file in a module file named "frozenforms.py".  Then
# in the main program of the script import frozenforms.
# (Don't forget to take this out when using the unfrozen version of
# the script!)
#
def freeze(filename):
    forms = parse_forms(filename)
    altforms = _pack_cache(forms)
    print 'import flp'
    print 'flp._internal_cache[', `filename`, '] =', altforms

#
# Internal: create the data structure to be placed in the cache
#
def _pack_cache(forms):
    altforms = {}
    for name in forms.keys():
        obj, list = forms[name]
        altobj = obj.__dict__
        altlist = []
        for obj in list: altlist.append(obj.__dict__)
        altforms[name] = altobj, altlist
    return altforms

#
# Internal: Locate form file (using PYTHONPATH) and open file
#
def _open_formfile(filename):
    return _open_formfile2(filename)[0]

def _open_formfile2(filename):
    if filename[-3:] != '.fd':
        filename = filename + '.fd'
    if filename[0] == '/':
        try:
            fp = open(filename,'r')
        except IOError:
            fp = None
    else:
        for pc in sys.path:
            pn = os.path.join(pc, filename)
            try:
                fp = open(pn, 'r')
                filename = pn
                break
            except IOError:
                fp = None
    if fp is None:
        raise error, 'Cannot find forms file ' + filename
    return fp, filename

#
# Internal: parse the fd file header, return number of forms
#
def _parse_fd_header(file):
    # First read the magic header line
    datum = _parse_1_line(file)
    if datum != ('Magic', 12321):
        raise error, 'Not a forms definition file'
    # Now skip until we know number of forms
    while 1:
        datum = _parse_1_line(file)
        if type(datum) == type(()) and datum[0] == 'Numberofforms':
            break
    return datum[1]
#
# Internal: parse fd form, or skip if name doesn't match.
# the special value None means 'always parse it'.
#
def _parse_fd_form(file, name):
    datum = _parse_1_line(file)
    if datum != FORMLINE:
        raise error, 'Missing === FORM === line'
    form = _parse_object(file)
    if form.Name == name or name is None:
        objs = []
        for j in range(form.Numberofobjects):
            obj = _parse_object(file)
            objs.append(obj)
        return (form, objs)
    else:
        for j in range(form.Numberofobjects):
            _skip_object(file)
    return None

#
# Internal class: a convenient place to store object info fields
#
class _newobj:
    def add(self, name, value):
        self.__dict__[name] = value
    def make(self, dict):
        for name in dict.keys():
            self.add(name, dict[name])

#
# Internal parsing routines.
#
def _parse_string(str):
    if '\\' in str:
        s = '\'' + str + '\''
        try:
            return eval(s)
        except:
            pass
    return str

def _parse_num(str):
    return eval(str)

def _parse_numlist(str):
    slist = str.split()
    nlist = []
    for i in slist:
        nlist.append(_parse_num(i))
    return nlist

# This dictionary maps item names to parsing routines.
# If no routine is given '_parse_num' is default.
_parse_func = { \
        'Name':         _parse_string, \
        'Box':          _parse_numlist, \
        'Colors':       _parse_numlist, \
        'Label':        _parse_string, \
        'Name':         _parse_string, \
        'Callback':     _parse_string, \
        'Argument':     _parse_string }

# This function parses a line, and returns either
# a string or a tuple (name,value)

import re
prog = re.compile('^([^:]*): *(.*)')

def _parse_line(line):
    match = prog.match(line)
    if not match:
        return line
    name, value = match.group(1, 2)
    if name[0] == 'N':
            name = ''.join(name.split())
            name = name.lower()
    name = name.capitalize()
    try:
        pf = _parse_func[name]
    except KeyError:
        pf = _parse_num
    value = pf(value)
    return (name, value)

def _readline(file):
    line = file.readline()
    if not line:
        raise EOFError
    return line[:-1]
        
def _parse_1_line(file):
    line = _readline(file)
    while line == '':
        line = _readline(file)
    return _parse_line(line)

def _skip_object(file):
    line = ''
    while not line in (SPLITLINE, FORMLINE, ENDLINE):
        pos = file.tell()
        line = _readline(file)
    if line == FORMLINE:
        file.seek(pos)

def _parse_object(file):
    obj = _newobj()
    while 1:
        pos = file.tell()
        datum = _parse_1_line(file)
        if datum in (SPLITLINE, FORMLINE, ENDLINE):
            if datum == FORMLINE:
                file.seek(pos)
            return obj
        if type(datum) is not type(()) or len(datum) != 2:
            raise error, 'Parse error, illegal line in object: '+datum
        obj.add(datum[0], datum[1])

#################################################################
#   Part 2 - High-level object/form creation routines            #
#################################################################

#
# External - Create a form an link to an instance variable.
#
def create_full_form(inst, (fdata, odatalist)):
    form = create_form(fdata)
    exec 'inst.'+fdata.Name+' = form\n'
    for odata in odatalist:
        create_object_instance(inst, form, odata)

#
# External - Merge a form into an existing form in an instance
# variable.
#
def merge_full_form(inst, form, (fdata, odatalist)):
    exec 'inst.'+fdata.Name+' = form\n'
    if odatalist[0].Class != FL.BOX:
        raise error, 'merge_full_form() expects FL.BOX as first obj'
    for odata in odatalist[1:]:
        create_object_instance(inst, form, odata)


#################################################################
#   Part 3 - Low-level object/form creation routines            #
#################################################################

#
# External Create_form - Create form from parameters
#
def create_form(fdata):
    import fl
    return fl.make_form(FL.NO_BOX, fdata.Width, fdata.Height)

#
# External create_object - Create an object. Make sure there are
# no callbacks. Returns the object created.
#
def create_object(form, odata):
    obj = _create_object(form, odata)
    if odata.Callback:
        raise error, 'Creating free object with callback'
    return obj
#
# External create_object_instance - Create object in an instance.
#
def create_object_instance(inst, form, odata):
    obj = _create_object(form, odata)
    if odata.Callback:
        cbfunc = eval('inst.'+odata.Callback)
        obj.set_call_back(cbfunc, odata.Argument)
    if odata.Name:
        exec 'inst.' + odata.Name + ' = obj\n'
#
# Internal _create_object: Create the object and fill options
#
def _create_object(form, odata):
    crfunc = _select_crfunc(form, odata.Class)
    obj = crfunc(odata.Type, odata.Box[0], odata.Box[1], odata.Box[2], \
            odata.Box[3], odata.Label)
    if not odata.Class in (FL.BEGIN_GROUP, FL.END_GROUP):
        obj.boxtype = odata.Boxtype
        obj.col1 = odata.Colors[0]
        obj.col2 = odata.Colors[1]
        obj.align = odata.Alignment
        obj.lstyle = odata.Style
        obj.lsize = odata.Size
        obj.lcol = odata.Lcol
    return obj
#
# Internal crfunc: helper function that returns correct create function
#
def _select_crfunc(fm, cl):
    if cl == FL.BEGIN_GROUP: return fm.bgn_group
    elif cl == FL.END_GROUP: return fm.end_group
    elif cl == FL.BITMAP: return fm.add_bitmap
    elif cl == FL.BOX: return fm.add_box
    elif cl == FL.BROWSER: return fm.add_browser
    elif cl == FL.BUTTON: return fm.add_button
    elif cl == FL.CHART: return fm.add_chart
    elif cl == FL.CHOICE: return fm.add_choice
    elif cl == FL.CLOCK: return fm.add_clock
    elif cl == FL.COUNTER: return fm.add_counter
    elif cl == FL.DIAL: return fm.add_dial
    elif cl == FL.FREE: return fm.add_free
    elif cl == FL.INPUT: return fm.add_input
    elif cl == FL.LIGHTBUTTON: return fm.add_lightbutton
    elif cl == FL.MENU: return fm.add_menu
    elif cl == FL.POSITIONER: return fm.add_positioner
    elif cl == FL.ROUNDBUTTON: return fm.add_roundbutton
    elif cl == FL.SLIDER: return fm.add_slider
    elif cl == FL.VALSLIDER: return fm.add_valslider
    elif cl == FL.TEXT: return fm.add_text
    elif cl == FL.TIMER: return fm.add_timer
    else:
        raise error, 'Unknown object type: ' + `cl`


def test():
    import time
    t0 = time.time()
    if len(sys.argv) == 2:
        forms = parse_forms(sys.argv[1])
        t1 = time.time()
        print 'parse time:', 0.001*(t1-t0), 'sec.'
        keys = forms.keys()
        keys.sort()
        for i in keys:
            _printform(forms[i])
    elif len(sys.argv) == 3:
        form = parse_form(sys.argv[1], sys.argv[2])
        t1 = time.time()
        print 'parse time:', round(t1-t0, 3), 'sec.'
        _printform(form)
    else:
        print 'Usage: test fdfile [form]'

def _printform(form):
    f = form[0]
    objs = form[1]
    print 'Form ', f.Name, ', size: ', f.Width, f.Height, ' Nobj ', f.Numberofobjects
    for i in objs:
        print '  Obj ', i.Name, ' type ', i.Class, i.Type
        print '    Box ', i.Box, ' btype ', i.Boxtype
        print '    Label ', i.Label, ' size/style/col/align ', i.Size,i.Style, i.Lcol, i.Alignment
        print '    cols ', i.Colors
        print '    cback ', i.Callback, i.Argument
