# Module 'panel'
#
# Support for the Panel library.
# Uses built-in module 'pnl'.
# Applications should use 'panel.function' instead of 'pnl.function';
# most 'pnl' functions are transparently exported by 'panel',
# but dopanel() is overridden and you have to use this version
# if you want to use callbacks.
from warnings import warnpy3k
warnpy3k("the panel module has been removed in Python 3.0", stacklevel=2)
del warnpy3k


import pnl


debug = 0


# Test if an object is a list.
#
def is_list(x):
    return type(x) == type([])


# Reverse a list.
#
def reverse(list):
    res = []
    for item in list:
        res.insert(0, item)
    return res


# Get an attribute of a list, which may itself be another list.
# Don't use 'prop' for name.
#
def getattrlist(list, name):
    for item in list:
        if item and is_list(item) and item[0] == name:
            return item[1:]
    return []


# Get a property of a list, which may itself be another list.
#
def getproplist(list, name):
    for item in list:
        if item and is_list(item) and item[0] == 'prop':
            if len(item) > 1 and item[1] == name:
                return item[2:]
    return []


# Test if an actuator description contains the property 'end-of-group'
#
def is_endgroup(list):
    x = getproplist(list, 'end-of-group')
    return (x and x[0] == '#t')


# Neatly display an actuator definition given as S-expression
# the prefix string is printed before each line.
#
def show_actuator(prefix, a):
    for item in a:
        if not is_list(item):
            print prefix, item
        elif item and item[0] == 'al':
            print prefix, 'Subactuator list:'
            for a in item[1:]:
                show_actuator(prefix + '    ', a)
        elif len(item) == 2:
            print prefix, item[0], '=>', item[1]
        elif len(item) == 3 and item[0] == 'prop':
            print prefix, 'Prop', item[1], '=>',
            print item[2]
        else:
            print prefix, '?', item


# Neatly display a panel.
#
def show_panel(prefix, p):
    for item in p:
        if not is_list(item):
            print prefix, item
        elif item and item[0] == 'al':
            print prefix, 'Actuator list:'
            for a in item[1:]:
                show_actuator(prefix + '    ', a)
        elif len(item) == 2:
            print prefix, item[0], '=>', item[1]
        elif len(item) == 3 and item[0] == 'prop':
            print prefix, 'Prop', item[1], '=>',
            print item[2]
        else:
            print prefix, '?', item


# Exception raised by build_actuator or build_panel.
#
panel_error = 'panel error'


# Dummy callback used to initialize the callbacks.
#
def dummy_callback(arg):
    pass


# Assign attributes to members of the target.
# Attribute names in exclist are ignored.
# The member name is the attribute name prefixed with the prefix.
#
def assign_members(target, attrlist, exclist, prefix):
    for item in attrlist:
        if is_list(item) and len(item) == 2 and item[0] not in exclist:
            name, value = item[0], item[1]
            ok = 1
            if value[0] in '-0123456789':
                value = eval(value)
            elif value[0] == '"':
                value = value[1:-1]
            elif value == 'move-then-resize':
                # Strange default set by Panel Editor...
                ok = 0
            else:
                print 'unknown value', value, 'for', name
                ok = 0
            if ok:
                lhs = 'target.' + prefix + name
                stmt = lhs + '=' + repr(value)
                if debug: print 'exec', stmt
                try:
                    exec stmt + '\n'
                except KeyboardInterrupt: # Don't catch this!
                    raise KeyboardInterrupt
                except:
                    print 'assign failed:', stmt


# Build a real actuator from an actuator description.
# Return a pair (actuator, name).
#
def build_actuator(descr):
    namelist = getattrlist(descr, 'name')
    if namelist:
        # Assume it is a string
        actuatorname = namelist[0][1:-1]
    else:
        actuatorname = ''
    type = descr[0]
    if type[:4] == 'pnl_': type = type[4:]
    act = pnl.mkact(type)
    act.downfunc = act.activefunc = act.upfunc = dummy_callback
    #
    assign_members(act, descr[1:], ['al', 'data', 'name'], '')
    #
    # Treat actuator-specific data
    #
    datalist = getattrlist(descr, 'data')
    prefix = ''
    if type[-4:] == 'puck':
        prefix = 'puck_'
    elif type == 'mouse':
        prefix = 'mouse_'
    assign_members(act, datalist, [], prefix)
    #
    return act, actuatorname


# Build all sub-actuators and add them to the super-actuator.
# The super-actuator must already have been added to the panel.
# Sub-actuators with defined names are added as members to the panel
# so they can be referenced as p.name.
#
# Note: I have no idea how panel.endgroup() works when applied
# to a sub-actuator.
#
def build_subactuators(panel, super_act, al):
    #
    # This is nearly the same loop as below in build_panel(),
    # except a call is made to addsubact() instead of addact().
    #
    for a in al:
        act, name = build_actuator(a)
        act.addsubact(super_act)
        if name:
            stmt = 'panel.' + name + ' = act'
            if debug: print 'exec', stmt
            exec stmt + '\n'
        if is_endgroup(a):
            panel.endgroup()
        sub_al = getattrlist(a, 'al')
        if sub_al:
            build_subactuators(panel, act, sub_al)
    #
    # Fix the actuator to which whe just added subactuators.
    # This can't hurt (I hope) and is needed for the scroll actuator.
    #
    super_act.fixact()


# Build a real panel from a panel definition.
# Return a panel object p, where for each named actuator a, p.name is a
# reference to a.
#
def build_panel(descr):
    #
    # Sanity check
    #
    if (not descr) or descr[0] != 'panel':
        raise panel_error, 'panel description must start with "panel"'
    #
    if debug: show_panel('', descr)
    #
    # Create an empty panel
    #
    panel = pnl.mkpanel()
    #
    # Assign panel attributes
    #
    assign_members(panel, descr[1:], ['al'], '')
    #
    # Look for actuator list
    #
    al = getattrlist(descr, 'al')
    #
    # The order in which actuators are created is important
    # because of the endgroup() operator.
    # Unfortunately the Panel Editor outputs the actuator list
    # in reverse order, so we reverse it here.
    #
    al = reverse(al)
    #
    for a in al:
        act, name = build_actuator(a)
        act.addact(panel)
        if name:
            stmt = 'panel.' + name + ' = act'
            exec stmt + '\n'
        if is_endgroup(a):
            panel.endgroup()
        sub_al = getattrlist(a, 'al')
        if sub_al:
            build_subactuators(panel, act, sub_al)
    #
    return panel


# Wrapper around pnl.dopanel() which calls call-back functions.
#
def my_dopanel():
    # Extract only the first 4 elements to allow for future expansion
    a, down, active, up = pnl.dopanel()[:4]
    if down:
        down.downfunc(down)
    if active:
        active.activefunc(active)
    if up:
        up.upfunc(up)
    return a


# Create one or more panels from a description file (S-expressions)
# generated by the Panel Editor.
#
def defpanellist(file):
    import panelparser
    descrlist = panelparser.parse_file(open(file, 'r'))
    panellist = []
    for descr in descrlist:
        panellist.append(build_panel(descr))
    return panellist


# Import everything from built-in method pnl, so the user can always
# use panel.foo() instead of pnl.foo().
# This gives *no* performance penalty once this module is imported.
#
from pnl import *                       # for export

dopanel = my_dopanel                    # override pnl.dopanel
