{% from 'message_box.html' import message_box %}

{% macro _render_errors(errors) -%}
    <ul>
        {%- for error in errors -%}
            <li>{{ error }}</li>
        {%- endfor -%}
    </ul>
{%- endmacro %}

{% macro form_header(form, method='post', action='', orientation='horizontal', id=none, classes='', multipart=false,
                     i_form=true, no_ajax=false, disable_if_locked=true, extra_attrs={}) -%}
    <form method="{{ method }}" {%- if action %} action="{{ action }}"{% endif %}
          class="{{ 'i-form' if i_form }} {{ 'disable-fields-if-locked' if disable_if_locked }} {{ orientation }} {{ classes }}"
          {% if id %}id="{{ id }}"{% endif %}
          {% if multipart %}enctype="multipart/form-data"{% endif %}
          {% if caller is defined %}{{ caller() }}{% endif %}
          {% if no_ajax %}data-no-ajax{% endif %}
          {{ extra_attrs|html_params }}>
        {% if form.meta.csrf -%}
            {{ form.csrf_token() }}
        {% endif %}
        {% for field in _iter_form_fields(form, hidden_fields=true, skip=('csrf_token',)) %}
            {{ field() }}
        {% endfor %}
{%- endmacro %}

{% macro form_row_static(label='', content=none, single_row=true, skip_label=false) -%}
    <div class="form-group">
        {% if not skip_label %}
            <div class="form-label {%- if single_row %} form-label-middle{% endif %}">
                {% if label %}
                    <label>{{ label }}</label>
                {% endif %}
            </div>
        {% endif %}
        <div class="form-field">
            <div class="static-text">
                {{ content or caller() }}
            </div>
        </div>
    </div>
{%- endmacro %}

{% macro form_field(field, field_classes, widget_attrs={}, disabled=none, hide_description=false) -%}
    <div class="{{ field_classes }}"{% if field.errors %} data-error="{{ _render_errors(field.errors) }}"{% endif %}>
        {{ _render_field(field, widget_attrs, disabled) }}
        {% if field.widget.input_type == 'checkbox' %}
            <div class="form-checkbox-label">{{ field.label() }}</div>
        {% endif %}
        {%- if caller is defined -%}
            {{ caller() }}
        {%- endif -%}
        {% if not hide_description and field.description %}
            <div class="form-field-description">{{ field.description | safe }}</div>
        {% endif %}
        {% if field.warning %}
            {%- call message_box('warning', fixed_width=true, classes='i-form-field-fixed-width form-field-warning') -%}
                {{ field.warning }}
            {%- endcall -%}
        {% endif %}
    </div>
{%- endmacro %}

{% macro form_row(field, widget_attrs={}, orientation='', allow_missing=false, skip_label=false, disabled=none, placeholder=false, classes='',
                  hide_description=false) %}
    {% set widget_attrs = widget_attrs|default({}) %}  {#- in case someone passed an Undefined object -#}
    {% if field or not allow_missing %}
        <div id="form-group-{{ field.id }}"
             class="form-group {{ orientation }}
                    {% if field.errors %}has-error{% endif %}
                    {% if field.flags.initially_hidden %}weak-hidden{% endif %}">
            {% if not skip_label and (orientation != 'vertical' or field.widget.input_type != 'checkbox') %}
                <div class="form-label{% if _is_single_line_field(field) %} form-label-middle{% endif %}
                            {%- if field.type == 'BooleanField' %} form-label-empty{% endif -%}">
                    {%- if field.widget.input_type != 'checkbox' and (not field.widget.input_type or not placeholder) -%}
                        {{ field.label() }}
                    {%- endif -%}
                    {%- if field.flags.required %}<i class="required" title="{% trans %}This field is required{% endtrans %}">*</i>{% endif -%}
                </div>
            {% endif %}
            {% set widget_attrs = dict(widget_attrs, placeholder=(field.label.text if placeholder else widget_attrs.get('placeholder', ''))) %}
            {% set classes = 'form-field %s' | format(classes) %}
            {%- if caller is defined -%}
                {% set caller_ = caller %}
                {% call form_field(field, classes, widget_attrs, disabled=disabled, hide_description=hide_description) -%}
                    {{ caller_() }}
                {%- endcall %}
            {%- else -%}
                {{ form_field(field, classes, widget_attrs, disabled=disabled, hide_description=hide_description) }}
            {%- endif -%}
        </div>
    {% endif %}
{%- endmacro %}

{% macro form_rows(form, fields=none, skip=(), orientation='', skip_labels=false, widget_attrs={}, disable=(), placeholder=false) %}
    {% for field in _iter_form_fields(form, fields=fields, skip=skip) %}
        {{ form_row(field, widget_attrs.get(field.short_name, {}), orientation, skip_label=skip_labels,
                    disabled=(true if field.short_name in disable else none), placeholder=placeholder) }}
    {% endfor %}
{% endmacro %}

{# `form` and `i_form` args are there in case we need them in the future #}
{% macro form_footer(form, i_form=true, skip_label=false, align_right=false, classes='') -%}
    {% if caller is defined %}
        <div class="form-group form-group-footer {{ classes }}">
            {% if not skip_label -%}
                <div class="form-label"></div>
            {%- endif %}
            <div class="form-field {{ 'flexrow f-j-end no-padding' if align_right }}">
                {{ caller() }}
            </div>
        </div>
    {% endif %}
    </form>
{% endmacro %}

{% macro form_fieldset(legend, description=none, disabled=false, render_as_fieldset=true, id=none,
                       collapsible=false, initially_collapsed=true) %}
    {% if not render_as_fieldset %}
        {#
        This is sugar for cases where you sometimes want the fieldset
        to show up as a fieldset and sometimes just want the contents.
        The most common use case for this is a form which has either
        a single fieldset or multiple fieldsets depending on the user's
        privileges. In this case it often looks better not to show the
        single fieldset as an actual fieldset.
        Using `render_as_fieldset` keep the code using this macro clean
        as it won't need extra conditions/macros/blocks to show the same
        content either inside or outside this fieldset.
        #}
        {{ caller() }}
    {% else %}
        <fieldset {% if id %}id="{{ id }}"{% endif %} {% if disabled %}disabled{% endif %} {% if collapsible %}class="collapsible {% if initially_collapsed %}initially-collapsed{% endif %}"{% endif %}>
            <legend>
                {{ legend }}
                {% if collapsible -%}
                    <div class="group right">
                        <span class="{{ 'icon-next' if initially_collapsed else 'icon-expand' }}"></span>
                    </div>
                {%- endif %}
            </legend>
            <div class="fieldset-content">
                {% if description %}
                    <p class="description">{{ description }}</p>
                {% endif %}
                {{ caller() }}
            </div>
        </fieldset>
    {% endif %}
{% endmacro %}

{# Renders a form with the most common default markup #}
{% macro simple_form(form, fields=none, submit=none, back=none, back_url=none, back_button=true,
                     disabled_until_change=true, disabled_fields=(), form_header_kwargs={}, skip_labels=false,
                     save_reminder=false, footer_align_right=false, disable_if_locked=true, message=none, fieldsets=none) %}
    {% set submit = submit or _('Save') %}
    {% set back = back or _('Back') %}
    {{ form_header(form, disable_if_locked=disable_if_locked, **form_header_kwargs) }}
    {% if message %}
        {{ message_box('warning', message=message, icon=true) }}
    {% endif %}
    {% if caller is defined %}
        {{ caller() }}
    {% elif fieldsets is not none %}
        {% for legend, fieldset_fields in fieldsets %}
            {% call form_fieldset(legend) %}
                {{ form_rows(form, fields=fieldset_fields, disable=disabled_fields, skip_labels=skip_labels) }}
            {% endcall %}
        {% endfor %}
    {% else %}
        {{ form_rows(form, fields=fields, disable=disabled_fields, skip_labels=skip_labels) }}
    {% endif %}
    {% call form_footer(form, skip_label=skip_labels, align_right=footer_align_right) %}
        <input class="i-button big highlight {{ 'hide-if-locked' if disable_if_locked }}" type="submit"
               value="{{ submit }}"
               {%- if disabled_until_change %} data-disabled-until-change{% endif %}
               {%- if save_reminder %} data-save-reminder{% endif %}>
        {% if back_button %}
            {% if back_url %}
                <a href="{{ back_url }}" class="i-button big" data-button-back>{{ back }}</a>
            {% else %}
                <button type="button" class="i-button big" data-button-back>{{ back }}</button>
            {% endif %}
        {% endif %}
    {% endcall %}
{% endmacro %}
