#
#		Python GUI - Message handlers - Generic
#

class MessageHandler(object):
    """A MessageHandler is an object which can form part of the
    message handling hierarchy. This hierarchy is used to handle
    keyboard events, menu commands, and action messages generated
    by buttons or other components.
    
    At any given moment, one of the application's windows is the
    'target window' for messages. Within the target window, some
    component is designated as the 'target object', or just 'target'.
    
    Messages are initially delivered to the target object, and
    passed up the hierarchy using the handle() method. At each step,
    if the object has a method with the same name as the message, it
    is called with the message's arguments. Otherwise the message is
    passed on to the object determined by the next_handler() method.
    Usually this is the object's container, but need not be.

    The become_target() method is used to make a component the target
    within its window. The targeted() method is called to notify a
    component when it has become or ceased to be the target. The
    is_target() method can be used to test whether a component is
    currently the target."""

    #----- Message handling -----
    
    def handle(self, message, *args):
        """If there is a method with the same name as the message, call
        it with the given args. Otherwise, pass the message up to the
        next handler."""
        method = getattr(self, message, None)
        if method:
            method(*args)
        else:
            self.pass_to_next_handler(message, *args)
    
    def pass_to_next_handler(self, message, *args):
        """Pass the given message on to the next handler, if any."""
        next = self.next_handler()
        if next:
            next.handle(message, *args)

    def next_handler(self):
        """Return the object, if any, to which messages not handled
        by this object should be passed on."""
        return None

    #----- Default handlers and callbacks -----
    
    def targeted(self, state):
        """Called when a Component becomes or ceases to be the target
        within its Window."""
        pass

    def _setup_menus(self, m):
        self.pass_to_next_handler('_setup_menus', m)
        self.setup_menus(m)
    
    def setup_menus(self, m):
        """Called before a menu is pulled down, to allow the Component to
        enable menu commands that it responds to."""
        pass
        
