from django import forms
from django.db import models
from django.utils.text import capfirst


"""
CharField based Tag field.
"""



class TagField(models.CharField):

    __metaclass__ = models.SubfieldBase

    def __init__(self, choices, separator=None, *args, **kwds):
        self.separator = separator or '\t'
        kwds['choices'] = choices
        kwds['max_length'] = sum((len(c[0]) for c in choices)) + len(choices)
        super(TagField, self).__init__(*args, **kwds)

    def to_python(self, value):
        if isinstance(value, unicode):
            tags = value.split(self.separator)
            return [{'title':c[1], 'slug': c[0]} for c in self.choices if c[0] in tags]
        return value

    def get_db_prep_save(self, value):
        data = []
        slug_list = []
        title_list = []
        try:
            slug_list = [v['slug'] for v in value]
        except TypeError:
            title_list = value
        for slug, title in self.choices:
            if slug_list and slug in slug_list \
                    or title in title_list:
                data.append(slug)
                continue
        return self.separator.join(data)

    def formfield(self, form_class=None, **kwargs):
        defaults = {
                'required': not self.blank,
                'label': capfirst(self.verbose_name),
                'help_text': self.help_text
            }
        form_class = form_class or TagFormField
        defaults['choices'] = self.get_choices(include_blank=False)
        defaults['coerce'] = self.to_python
        for k in kwargs.keys():
            if k not in ('choices', 'label', 'help_text', 'error_messages'):
                del kwargs[k]
        defaults.update(kwargs)
        return form_class(**defaults)


class TagCheckboxSelect(forms.widgets.CheckboxSelectMultiple):
    def __init__(self, *args, **kwds):
        super(TagCheckboxSelect, self).__init__(*args, **kwds)

    def render(self, name, value, attrs=None, choices=()):
        data = []
        if value:
            data = [v['slug'] for v in value]
        return super(TagCheckboxSelect, self).render(name, data, attrs, choices)


class TagFormField(forms.ChoiceField):

    widget = TagCheckboxSelect
    field = TagField

    def __init__(self, *args, **kwds):
        kwds.pop('coerce', None)
        super(TagFormField, self).__init__(*args, **kwds)

    def clean(self, value):
        if not value:
            raise forms.ValidationError('Choose at least one tag')
        data = []
        for choice in self.choices:
            if choice[0] in value:
                data.append(choice[1])
                continue
        return data
