""" attendee registration newforms custom field extensions
"""
from django.newforms.fields import Field
from django.newforms.widgets import Widget, RadioFieldRenderer, RadioInput
from django.newforms.widgets import CheckboxSelectMultiple, CheckboxInput
from django.utils.datastructures import MultiValueDict
from django.utils.html import escape
from django.utils.translation import ugettext
from django.utils.encoding import StrAndUnicode, force_unicode
from django.newforms.util import flatatt
from itertools import chain
from models import Tutorial
import copy

class RadioFieldInlineRenderer(RadioFieldRenderer):
    def render(self):
        tags = ( (force_unicode(w), w.attrs['id']+u'-sel') for w in self )
        inner = u'\n'.join([u'<span class="inline-selection" id="%s">%s</span>'
                                % (id, t) for t, id in tags])
        return u'<div class="inline-select">' + inner + u'</div>'


class TutorialRadioInput(RadioInput):
    """
    An object used by RadioFieldRenderer that represents a single
    <input type='radio'>.
    """

    def __init__(self, name, value, attrs, choice, index):
        super(TutorialRadioInput, self).__init__(name, value, attrs,
                                                 choice, index)
        self.tutorial = choice[1]

    def __unicode__(self):
        return u'<label>%s %s</label>' % (self.tag(), self.render_label())

    def render_label(self):
        if isinstance(self.tutorial, Tutorial) and self.tutorial.pageurl:
            title, authors = self.choice_label, u''
            res = title.rindex('(') if '(' in title else 0
            if res:
                authors = title[res:].strip()
                title = title[:res].strip()
            return u'<a href="%s">%s</a> %s' % (self.tutorial.pageurl,
                                             escape(title), escape(authors))
        return escape(self.choice_label)

class TutorialRadioFieldRenderer(RadioFieldRenderer):
    """
    An object used by RadioSelect to enable customization of radio widgets.
    """
    def __iter__(self):
        for i, choice in enumerate(self.choices):
            yield TutorialRadioInput(self.name, self.value, self.attrs.copy(),
                                     choice, i)
    def __getitem__(self, idx):
        choice = self.choices[idx] # Let the IndexError propogate
        return TutorialRadioInput(self.name, self.value, self.attrs.copy(),
                                  choice, idx)
    def render(self):
        """Outputs a <ul> for this set of radio fields."""
        return (u'<div class="tutorial-list"/>' +
                super(TutorialRadioFieldRenderer, self).render() + u'</div>')


class CheckboxInlineSelectMultiple(CheckboxSelectMultiple):
    def render(self, name, value, attrs=None, choices=()):
        if value is None: value = []
        has_id = attrs and 'id' in attrs
        final_attrs = self.build_attrs(attrs, name=name)
        output = [u'<div class="inline-multi">']
        str_values = set([force_unicode(v) for v in value]) # Normalize to strings.
        for i, (option_value, option_label) in enumerate(chain(self.choices, choices)):
            # If an ID attribute was given, add a numeric index as a suffix,
            # so that the checkboxes don't all have the same ID attribute.
            if has_id:
                final_attrs = dict(final_attrs, id='%s_%s' % (attrs['id'], i))
            cb = CheckboxInput(final_attrs, check_test=lambda value: value in str_values)
            option_value = force_unicode(option_value)
            rendered_cb = cb.render(name, option_value)
            output.append(u'<span class="inline-checkbox"><label>%s %s</label></span>' %
                          (rendered_cb, escape(force_unicode(option_label))))
        output.append(u'</div>')
        return u'\n'.join(output)

class HtmlInjectionWidget(Widget):
    def __init__(self, attrs=None, html=u''):
        self.html = html
        super(HtmlInjectionWidget, self).__init__(attrs)
    def render(self, name, value=None, attrs=None):
        return self.html

class HiddenHtmlInjectionWidget(HtmlInjectionWidget):
    def render(self, *args, **kwdargs):
        return (u'\n<!-- ' +
                super(HiddenHtmlInjectionWidget, self).render(*args, **kwdargs)
                + u' -->\n')

class HtmlInjectionField(Field):
    widget=HtmlInjectionWidget
    hidden_widget=HiddenHtmlInjectionWidget

    def set_html(self, val):
        self.widget.html = val
    def get_html(self):
        return self.widget.html
    def del_html(self):
        self.widget.html = u''
    html  = property(get_html, set_html, del_html)

    def __init__(self, required=False, widget=None, label=None, initial=None,
                 help_text=None, html=u''):
        super(HtmlInjectionField, self).__init__(required, widget, label, initial)
        self.html = html
