{% macro process(object, context) %}
    {% for group in object.getGroups() %}
        {{ _self.call(group.macro, group, context) }}
    {% endfor %}

    {% for element in object.getElements() %}
        {{ _self.call(element.macro, element, context) }}
    {% endfor %}
{% endmacro %}


{% macro form(form, context) %}
<cf-form{{ form.getAttribs(context)|attribs }}>
    {{ _self.process(form, context) }}
</cf-form>
{% endmacro %}


{% macro group(group, context) %}
<cf-form-group ng-model="{{ group.fullyQualifiedAngularModel }}"{{ group.getAttribs(context)|attribs }}>
    {{ _self.helper_group_label(group.label) }}
    {{ _self.process(group, context) }}
</cf-form-group>
{% endmacro %}


{% macro display_group(group, context) %}
<div{{ group.getAttribs(context)|attribs }}>
    {{ _self.helper_group_label(group.label) }}
    {{ _self.process(group, context) }}
</div>
{% endmacro %}


{% macro collection(collection, context, params) %}
<div{{ _self.helper_attribs(params, 'container', 0, 'cf-form-collection-container') }}>
    {{ _self.helper_group_label(collection.label) }}
    <cf-form-collection item-model='{{ collection.prototypeInstance.values|json_encode|raw }}'{{ collection.getAttribs(context)|attribs }}>
        {{ _self.call('display_group', collection.prototypeInstance, context) }}
    </cf-form-collection>
    {{ _self.helper_element_errors(collection, true) }}
</div>
{% endmacro %}


{% macro element(element, context, params) %}
<div{{ _self.helper_attribs(params, 'container', 0, 'cf-form-field') }}>
    <span{{ _self.helper_attribs(params, 'label', 1, 'cf-form-field-label') }}><label for="{{ element.fullyQualifiedId }}">{{ _self.helper_element_required(element.required) }}{{ element.label|raw }}{{ _self.helper_element_optional(element.required) }}</label></span>
    <span{{ _self.helper_attribs(params, 'element', 2, 'cf-form-field-element') }}>
        {{ element.render(context)|raw }}
        {{ _self.helper_element_errors(element) }}
        {{ _self.helper_element_required_placeholder(element.required) }}
        {% if element.description %}
            <span{{ _self.helper_attribs(params, 'description', 3, 'cf-form-field-description') }}>{{ element.description }}</span>
        {% endif %}
    </span>
</div>
{% endmacro %}


{% macro element_label_behind(element, context, params) %}
<div{{ _self.helper_attribs(params, 'container', 0, 'cf-form-field') }}>
    <span{{ _self.helper_attribs(params, 'element', 2, 'cf-form-field-element') }}>
        {{ element.render(context)|raw }}
        {{ _self.helper_element_errors(element) }}
    </span>
    <span{{ _self.helper_attribs(params, 'label', 1, 'cf-form-field-label') }}><label for="{{ element.fullyQualifiedId }}">{{ _self.helper_element_required(element.required) }}{{ element.label|raw }}</label></span>
</div>
{% endmacro %}


{% macro element_inside_label(element, context, params) %}
<div{{ _self.helper_attribs(params, 'container', 0, 'cf-form-field') }}>
    <label for="{{ element.fullyQualifiedId }}">{{ _self.helper_element_required(element.required) }} {{ element.render(context)|raw }} {{ element.label|raw }}</label>
    {{ _self.helper_element_errors(element) }}
</div>
{% endmacro %}


{% macro element_basic(element, context, params) %}
<div{{ _self.helper_attribs(params, 'container', 0, 'cf-form-field') }}>
    {{ element.render(context)|raw }}
</div>
{% endmacro %}


{% macro element_bare(element, context) %}
{{ element.render(context)|raw }}
{% endmacro %}




{% macro helper_attribs(params, property, index, class) %}
{% if attribute(params, property) %}
    {% set attribs = '' %}
    {% for key, value in attribute(params, property) %}
        {% if key == 'class' %}
            {% set attribs = attribs ~ ' ' ~ key ~ '="' ~ class ~ ' ' ~ value ~ '"' %}
        {% else %}
            {% set attribs = attribs ~ ' ' ~ key ~ '="' ~ value ~ '"' %}
        {% endif %}
    {% endfor %}
{% elseif attribute(params, index) %}
    {% set attribs = ' class="' ~ class ~ ' ' ~ attribute(params, index) ~ '"' %}
{% else %}
    {% set attribs = ' class="' ~ class ~ '"' %}
{% endif %}
{{ attribs|raw }}{% endmacro %}


{% macro helper_element_required(is_required) %}
{% if is_required %}<abbr title="Required" class="cf-form-required">&bull;</abbr> {% endif %}
{% endmacro %}

{% macro helper_element_optional(is_required) %}
{% if not is_required %} <em title="Optional" class="cf-form-optional">(optional)</em>{% endif %}
{% endmacro %}

{% macro helper_element_required_placeholder(is_required) %}
{% if is_required %}<abbr title="Required" class="cf-form-required Placeholder-required">&bull;</abbr> {% endif %}
{% endmacro %}

{% macro helper_element_errors(element, skip_collection) %}
{% if not skip_collection and element.inCollection %}
    {% for validatorType, validatorErrorMessage in element.angularRepresentation %}
        <span ng-class="{visible: item_{{ "{{$index}}" }}.{{ element.name }}.$dirty, exists: item_{{ "{{$index}}" }}.{{ element.name }}.$error.{{ validatorType }}}" class="cf-form-error">{{ validatorErrorMessage }}</span>
    {% endfor %}
        <span ng-class="{exists: item_{{ "{{$index}}" }}.{{ element.name }}.$error.server}" class="cf-form-error" ng-bind="item_{{ "{{$index}}" }}.{{ element.name }}.$error.server"></span>
{% else %}
    {% for validatorType, validatorErrorMessage in element.angularRepresentation %}
        <span ng-class="{visible: form.{{ element.name }}.$dirty, exists: form.{{ element.name }}.$error.{{ validatorType }}}" class="cf-form-error">{{ validatorErrorMessage }}</span>
    {% endfor %}
        <span ng-class="{exists: form.{{ element.name }}.$error.server}" class="cf-form-error" ng-bind="form.{{ element.name }}.$error.server"></span>
{% endif %}
{% endmacro %}

{% macro helper_group_label(label) %}
{% if label %}<div class="cf-form-group-label">{{ label|raw }}</div>{% endif %}
{% endmacro %}


{% macro link(element, context, params) %}
    <div{{ _self.helper_attribs(params, 'container', 0, 'cf-form-field') }}>
        <a ng-href="{{ params.container.url }}" target="_blank" class="LinkElement">{{ params.container.label }}</a>
    </div>
{% endmacro %}

{% macro placeholder(element, context, params) %}
    <div{{ _self.helper_attribs(params, 'container', 0, 'cf-form-field cf-form-placeholder') }}>
        {{ element.label|raw }}
    </div>
{% endmacro %}
