from types import ListType

from ExamplePage import ExamplePage

debug = 0


class ListBox(ExamplePage):
    """List box example.

    This page provides a list box interface with controls
    for changing its size and adding and removing items.

    The source is a good example of how to use awake() and actions.

    It also shows how to avoid repeated exectution on refresh/reload.

    """

    def awake(self, transaction):
        ExamplePage.awake(self, transaction)
        sess = self.session()
        if sess.hasValue('vars'):
            self._vars = sess.value('vars')
        else:
            self._vars = {
                'list':      [],
                'height':    10,
                'width':    250,
                'newCount':   1,
                'formCount':  1,
            }
            sess.setValue('vars', self._vars)
        self._error = None

    def writeContent(self):
        enc, wr = self.htmlEncode, self.writeln
        wr('<div style="text-align:center">')
        if debug:
            wr('<p>fields = %s</p>' % enc(str(self.request().fields())))
            wr('<p>vars = %s</p>' % enc(str(self._vars)))
        # Intro text is provided by our class' doc string:
        intro = self.__class__.__doc__.strip().split('\n\n')
        wr('<h2>%s</h2>' % intro.pop(0))
        for s in intro:
            wr('<p>%s</p>' % '<br>'.join(
                map(lambda s: s.strip(), s.split('\n'))))
        wr('<p style="color:red">%s</p>' % (self._error or '&nbsp;'))
        wr('''
<form action="ListBox" method="post">
<input name="formCount" type="hidden" value="%(formCount)d">
<select multiple name="list" size="%(height)d"
style="width:%(width)dpt;text-align:center">
''' % self._vars)
        index = 0
        for item in self._vars['list']:
            wr('<option value="%d">%s</option>' % (index, enc(item['name'])))
            index += 1
        if not index:
            wr('<option value="" disabled>--- empty ---</option>')
        wr('''
</select>
<p>
<input name="_action_new" type="submit" value="New">
<input name="_action_delete" type="submit" value="Delete">
&nbsp; &nbsp; &nbsp;
<input name="_action_taller" type="submit" value="Taller">
<input name="_action_shorter" type="submit" value="Shorter">
&nbsp; &nbsp; &nbsp;
<input name="_action_wider" type="submit" value="Wider">
<input name="_action_narrower" type="submit" value="Narrower">
</p>
</form>
</div>
''')

    def heightChange(self):
        return 1

    def widthChange(self):
        return 30


    ## Commands ##

    def new(self):
        """Add a new item to the list box."""
        req = self.request()
        self._vars['list'].append(
            {'name': 'New item %d' % self._vars['newCount']})
        self._vars['newCount'] += 1
        self.writeBody()

    def delete(self):
        """Delete the selected items in the list box."""
        req = self.request()
        if req.hasField('list'):
            indices = req.field('list')
            if type(indices) is not ListType:
                indices = [indices]
            try:
                indices = map(int, indices) # convert strings to ints
            except ValueError:
                indices = []
            indices.sort() # sort...
            indices.reverse() # in reverse order
            # remove the objects:
            for index in indices:
                del self._vars['list'][index]
        else:
            self._error = 'You must select a row to delete.'
        self.writeBody()

    def taller(self):
        self._vars['height'] += self.heightChange()
        self.writeBody()

    def shorter(self):
        if self._vars['height'] > 2:
            self._vars['height'] -= self.heightChange()
        self.writeBody()

    def wider(self):
        self._vars['width'] += self.widthChange()
        self.writeBody()

    def narrower(self):
        if self._vars['width'] >= 60:
            self._vars['width'] -= self.widthChange()
        self.writeBody()


    ## Actions ##

    def actions(self):
        acts = ExamplePage.actions(self)
        # check whether form is valid (no repeated execution)
        try:
            formCount = int(self.request().field('formCount'))
        except Exception:
            formCount = 0
        if formCount == self._vars['formCount']:
            acts.extend(['new', 'delete',
                'taller', 'shorter', 'wider', 'narrower'])
            self._vars['formCount'] += 1
        return acts