from django import template
from django.utils.safestring import mark_safe
from django.template.loader import render_to_string

register = template.Library()

@register.filter
def render_field(field, template=None):
    """
    Renders the specified Form field.
    
    Example::
    
        {{ form.first_name|render_field }}

    This will output markup for the field, including a <label>, <input>, errors and help text.
    Markup is generated by rendering "form_helpers/field.html"

    You can customize the markup by overriding the "form_helpers/field.html" template.
    
    You can also specify the template to use on a per-field basis.
    This is useful for rendering different markup for different widgets.
    There are two possible syntaxes for this:
    
        {{ form.terms_of_use|render_field:"checkbox" }}
        
    which renders "form_helpers/checkbox_field.html", and:

        {{ form.terms_of_use|render_field:"myapp/myfield.html" }}
        
    which renders the template specified.
    
    # Finally, it's possible to specify default templates for specific widget types in settings.py:
    # 
    # FORM_FIELD_TEMPLATES = {
    #     Textarea: "form_helpers/textbox.html",
    #     DateTimeWidget: "form_helpers/datepicker.html"
    # }
    # 
    """
    classes = ['field', field.field.__class__.__name__]
    if field.errors:
        classes.append('with_errors')
    if field.field.required:
        classes.append('required')
    
    if field.help_text:
        help_text_html = u'<p class="help">%s</p>' % field.help_text
    else:
        help_text_html = u''
        
    field_templates = [
        'forms/%s.html' % field.field.__class__.__name__,
        'forms/field.html',
    ]
    if template:
        if '.' in template:
            field_templates.insert(0, template)
        else:
            field_templates.insert(0, 'forms/%s_field.html' % template)
    data = {
        'classes': " ".join(classes),
        'label': field.label_tag(),
        'errors': field.errors,
        'field': field,
        'help_text': help_text_html,
        'field_id': '#TODO'
    }
    rendered_field = render_to_string(field_templates, data)
    return mark_safe(rendered_field)
    
@register.filter
def render_fields(form, args):
    """
    Renders a list of fields using `render_field`.
    Use: {{ form|render_fields:"first_name,last_name,email" }}
    """
    output = ""
    fields = get_fields(form, args)
    for field in fields:
        output += render_field(field)
    return mark_safe(output)
    
@register.filter
def get_fields(form, args):
    """
    Returns a list of fields from the given form.
    This is handy for granular rendering of many fields.
    Use:
    {% for field in form|get_fields:"first_name,last_name,email" %}
        {{ field|render_field }}
    {% endfor %}
    
    """
    bound_fields = {}
    fields = []
    for field in form:
        bound_fields.update({field.name: field})
    for field_name in args.split(','):
        if field_name in bound_fields:
            fields.append(bound_fields[field_name])
    return fields