from zope.interface import implementer
from twisted.web.template import tags as T
from .. import iformal
from ..util import render_cssid


@implementer( iformal.IWidget )
class TextAreaWithSelect(object):
    """
    A large text entry area that accepts newline characters.

    <textarea>...</textarea>
    """

    cols = 48
    rows = 6

    def __init__(self, original, cols=None, rows=None, values=None):
        self.original = original
        self.values = values
        if cols is not None:
            self.cols = cols
        if rows is not None:
            self.rows = rows

    def _renderTag(self, request, key, value, readonly):
        html = []
        tag=T.textarea(name=key, id=render_cssid(key), cols=self.cols, rows=self.rows)[value or '']
        if readonly:
            tag(class_='readonly', readonly='readonly')
        html.append(tag)
        if self.values is None:
            return html

        def renderOptions(request,options):
            for value,label in options:
                yield T.option(value=value)[label]


        selecttrigger = T.select(name='%s__selecttrigger'%key, data=self.values)[ renderOptions ]


        # TODO: figure out where to get the form from
        form = iformal.IForm( request )
        js = T.xml("var x = document.getElementById('%(form)s');x.%(key)s.value += x.%(key)s__selecttrigger.options[x.%(key)s__selecttrigger.options.selectedIndex].value + &quot;\\n&quot;;"%{'key':key,'form':form.name})
        aonclick = T.a(onclick=js)[ 'add' ]
        html.append(T.div(class_="add")[selecttrigger,aonclick])
        return html

    def render(self, request, key, args, errors):
        if errors:
            value = args.get(key, [''])[0]
        else:
            value = iformal.IStringConvertible(self.original).fromType(args.get(key))
        return self._renderTag(request, key, value, False)

    def renderImmutable(self, request, key, args, errors):
        value = iformal.IStringConvertible(self.original).fromType(args.get(key))
        return self._renderTag(request, key, value, True)

    def processInput(self, request, key, args, default=''):
        value = args.get(key, [default])[0].decode("utf-8")
        value = iformal.IStringConvertible(self.original).fromType(value)
        return self.original.validate(value)
