from Component import ServletComponent, Component

class NotifyServletComponent(ServletComponent):

    """
    Collects and presents status messages. NotifyComponent should
    be used in your class definitions.

    Adds two methods, ``message(msg)`` and ``writeMessages(prefix,
    postfix)``.

    ``message(msg)`` adds a message to be presented to the user.
    These messages are simply queued in the session.

    ``writeMessages(prefix, postfix)`` writes the messages that
    have been collected, and empties the queue.  You might want
    to define:

    class SitePage(CPage):
        components = [NotifyComponent()]
        def writeBodyParts(self):
            self.writeMessages()
        CPage.writeBodyParts(self)

    prefix and postfix are used to surround the messages, if there
    are any messages.  By default it's put in a box.  Typically
    you'd use it like:

    class SomePage(SitePage):

        def awake(self, trans):
            CPage.awake(self, trans)
        if self.request().field('setSomething', 0):
            # do stuff...
            self.message('Stuff done successfully')
            raise HTTPRedirect, 'StuffIndex'

        def writeContent(self):
            self.write('form for doing stuff...')

    Be careful; if you redirect *after* you call ``writeMessages``,
    the messages will be removed from the queue, but the user will
    probably never see them.  For this reason, all redirects should
    happen in ``awake()``.
    """

    _servletMethods = ['message', 'writeMessages', 'messageText',
                       'hasMessages', 'getMessages']

    def message(self, msg):
        """
        Add a message to the session
        """
        ses = self.servlet().session()
        msgs = ses.value('NotifyServletComponent.message', [])
        msgs.append(msg)
        ses.setValue('NotifyServletComponent.message', msgs)

    def writeMessages(self, **kw):
        """
        Write any queued messages to the servlet response (equivalent
        to ``self.write(self.messageText(...))``)
        """
        self.servlet().response().write(self.messageText(**kw))

    def messageText(self, prefix='<center><div class="notifyMessage">',
                 postfix='</div></center>'):
        """
        Return the text of the message, wrapped with ``prefix`` and
        ``postfix``, or the empty string if no messages are available.
        """
        msgs = self.getMessages()
        if not msgs:
            return ''
        return '%s%s%s' % (prefix, '<br>\n'.join(msgs), postfix)

    def hasMessages(self):
        """
        Are there any messages waiting in the session message queue?
        """
        return not not self.getMessages(remove=False)
        
    def getMessages(self, remove=True):
        """
        Get a list of messages (empty list if none) from the session queue.
        As long as ``remove`` is true (the default) then they messages
        will be removed from the queue.
        """
        if not self.servlet().transaction().hasSession():
            return []
        ses = self.servlet().session()
        msgs = ses.value('NotifyServletComponent.message', [])
        if remove:
            ses.setValue('NotifyServletComponent.message', [])
        return msgs

class NotifyComponent(Component):

    _componentClass = NotifyServletComponent
