{% from 'macros.tmpl' import license %}
{#
    This file is for property handlers which use the templating engine to
    reduce (handwritten) code duplication.

    The `properties' dict can be used to access a property's parameters in
    jinja2 templates (i.e. setter, getter, initial, type_name)
#}
#include "config.h"
#include "StyleBuilderFunctions.h"

#include "CSSValueKeywords.h"
#include "core/css/BasicShapeFunctions.h"
#include "core/css/CSSPrimitiveValueMappings.h"
#include "core/css/Pair.h"
#include "core/css/resolver/StyleResolverState.h"

{% macro declare_initial_function(property_id) %}
void StyleBuilderFunctions::applyInitial{{property_id}}(StyleResolverState& state)
{%- endmacro %}
{% macro declare_inherit_function(property_id) %}
void StyleBuilderFunctions::applyInherit{{property_id}}(StyleResolverState& state)
{%- endmacro %}
{% macro declare_value_function(property_id) %}
void StyleBuilderFunctions::applyValue{{property_id}}(StyleResolverState& state, CSSValue* value)
{%- endmacro %}
{% macro set_value(property) %}
{%- if property.font %}
state.fontBuilder().{{property.setter}}
{%- else %}
state.style()->{{property.setter}}
{%- endif %}
{% endmacro %}
{% macro convert_and_set_value(property) %}
{% if property.converter %}
{{set_value(property)}}(StyleBuilderConverter::{{property.converter}}(state, value));
{%- else %}
{{set_value(property)}}(static_cast<{{property.type_name}}>(*toCSSPrimitiveValue(value)));
{%- endif %}
{% endmacro %}

namespace blink {

{% for property_id, property in properties.items() if property.should_declare_functions %}
{% set apply_type = property.apply_type %}
{% if not property.custom_initial %}
{{declare_initial_function(property_id)}}
{
    {% if property.font %}
    {{set_value(property)}}(FontBuilder::{{property.initial}}());
    {% else %}
    {{set_value(property)}}(RenderStyle::{{property.initial}}());
    {% endif %}
}

{% endif %}
{% if not property.custom_inherit %}
{{declare_inherit_function(property_id)}}
{
    {% if property.font %}
    {{set_value(property)}}(state.parentFontDescription().{{property.getter}}());
    {% else %}
    {{set_value(property)}}(state.parentStyle()->{{property.getter}}());
    {% endif %}
}

{% endif %}
{% if not property.custom_value %}
{{declare_value_function(property_id)}}
{
    {{convert_and_set_value(property)}}
}

{% endif %}
{% endfor %}

{% macro apply_animation(property_id, attribute, animation) %}
{% set vector = attribute|lower_first + "List()" %}
{{declare_initial_function(property_id)}}
{
    CSS{{animation}}Data& data = state.style()->access{{animation}}s();
    data.{{vector}}.clear();
    data.{{vector}}.append(CSS{{animation}}Data::initial{{attribute}}());
}

{{declare_inherit_function(property_id)}}
{
    const CSS{{animation}}Data* parentData = state.parentStyle()->{{animation|lower}}s();
    if (!parentData)
        applyInitial{{property_id}}(state);
    else
        state.style()->access{{animation}}s().{{vector}} = parentData->{{vector}};
}

{{declare_value_function(property_id)}}
{
    CSS{{animation}}Data& data = state.style()->access{{animation}}s();
    data.{{vector}}.clear();
    for (CSSValueListIterator i = value; i.hasMore(); i.advance())
        data.{{vector}}.append(state.styleMap().mapAnimation{{attribute}}(i.value()));
}
{% endmacro %}
{{apply_animation('CSSPropertyAnimationDelay', 'Delay', 'Animation')}}
{{apply_animation('CSSPropertyAnimationDirection', 'Direction', 'Animation')}}
{{apply_animation('CSSPropertyAnimationDuration', 'Duration', 'Animation')}}
{{apply_animation('CSSPropertyAnimationFillMode', 'FillMode', 'Animation')}}
{{apply_animation('CSSPropertyAnimationIterationCount', 'IterationCount', 'Animation')}}
{{apply_animation('CSSPropertyAnimationName', 'Name', 'Animation')}}
{{apply_animation('CSSPropertyAnimationPlayState', 'PlayState', 'Animation')}}
{{apply_animation('CSSPropertyAnimationTimingFunction', 'TimingFunction', 'Animation')}}
{{apply_animation('CSSPropertyTransitionDelay', 'Delay', 'Transition')}}
{{apply_animation('CSSPropertyTransitionDuration', 'Duration', 'Transition')}}
{{apply_animation('CSSPropertyTransitionProperty', 'Property', 'Transition')}}
{{apply_animation('CSSPropertyTransitionTimingFunction', 'TimingFunction', 'Transition')}}

{% macro apply_auto(property_id, auto_getter=none, auto_setter=none, auto_identity='CSSValueAuto') %}
{% set property = properties[property_id] %}
{% set auto_getter = auto_getter or 'hasAuto' + property.name_for_methods %}
{% set auto_setter = auto_setter or 'setHasAuto' + property.name_for_methods %}
{{declare_initial_function(property_id)}}
{
    state.style()->{{auto_setter}}();
}

{{declare_inherit_function(property_id)}}
{
    if (state.parentStyle()->{{auto_getter}}())
        state.style()->{{auto_setter}}();
    else
        {{set_value(property)}}(state.parentStyle()->{{property.getter}}());
}

{{declare_value_function(property_id)}}
{
    if (!value->isPrimitiveValue())
        return;

    CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
    if (primitiveValue->getValueID() == {{auto_identity}})
        state.style()->{{auto_setter}}();
    else
        {{convert_and_set_value(property)}}
}
{% endmacro %}
{{apply_auto('CSSPropertyClip')}}
{{apply_auto('CSSPropertyZIndex')}}

static bool lengthTypeAndValueMatch(const Length& length, LengthType type, float value)
{
    return length.type() == type && length.value() == value;
}

static bool lengthTypeAndValueMatch(const LengthBox& lengthBox, LengthType type, float value)
{
    return (lengthTypeAndValueMatch(lengthBox.left(), type, value)
        && lengthTypeAndValueMatch(lengthBox.right(), type, value)
        && lengthTypeAndValueMatch(lengthBox.top(), type, value)
        && lengthTypeAndValueMatch(lengthBox.bottom(), type, value));
}

static bool lengthTypeAndValueMatch(const BorderImageLength& borderImageLength, LengthType type, float value)
{
    return borderImageLength.isLength() && lengthTypeAndValueMatch(borderImageLength.length(), type, value);
}

static bool lengthTypeAndValueMatch(const BorderImageLengthBox& borderImageLengthBox, LengthType type, float value)
{
    return (lengthTypeAndValueMatch(borderImageLengthBox.left(), type, value)
        && lengthTypeAndValueMatch(borderImageLengthBox.right(), type, value)
        && lengthTypeAndValueMatch(borderImageLengthBox.top(), type, value)
        && lengthTypeAndValueMatch(borderImageLengthBox.bottom(), type, value));
}

{% macro apply_border_image_modifier(property_id, modifier_type) %}
{{ declare_initial_function(property_id) }}
{
    const NinePieceImage& currentImage = state.style()->borderImage();
    {# Check for equality in case we can bail out before creating a new NinePieceImage. #}
    {% if modifier_type == 'Outset' %}
    if (lengthTypeAndValueMatch(currentImage.outset(), Fixed, 0))
        return;
    {% elif modifier_type == 'Repeat' %}
    if (currentImage.horizontalRule() == StretchImageRule && currentImage.verticalRule() == StretchImageRule)
        return;
    {% elif modifier_type == 'Slice' %}
    if (currentImage.fill() == false && lengthTypeAndValueMatch(currentImage.imageSlices(), Percent, 100))
        return;
    {% elif modifier_type == 'Width' %}
    if (lengthTypeAndValueMatch(currentImage.borderSlices(), Fixed, 1))
        return;
    {% endif %}

    NinePieceImage image(currentImage);
    {% if modifier_type == 'Outset' %}
    image.setOutset(Length(0, Fixed));
    {% elif modifier_type == 'Repeat' %}
    image.setHorizontalRule(StretchImageRule);
    image.setVerticalRule(StretchImageRule);
    {% elif modifier_type == 'Slice' %}
    image.setImageSlices(LengthBox({{ (['Length(100, Percent)']*4) | join(', ') }}));
    image.setFill(false);
    {% elif modifier_type == 'Width' %}
    image.setBorderSlices(1.0);
    {% endif %}
    state.style()->setBorderImage(image);
}

{{declare_inherit_function(property_id)}}
{
    NinePieceImage image(state.style()->borderImage());
    {% if modifier_type == 'Outset' %}
    image.copyOutsetFrom(state.parentStyle()->borderImage());
    {% elif modifier_type == 'Repeat' %}
    image.copyRepeatFrom(state.parentStyle()->borderImage());
    {% elif modifier_type == 'Slice' %}
    image.copyImageSlicesFrom(state.parentStyle()->borderImage());
    {% elif modifier_type == 'Width' %}
    image.copyBorderSlicesFrom(state.parentStyle()->borderImage());
    {% endif %}
    state.style()->setBorderImage(image);
}

{{declare_value_function(property_id)}}
{
    NinePieceImage image(state.style()->borderImage());
    {% if modifier_type == 'Outset' %}
    image.setOutset(state.styleMap().mapNinePieceImageQuad(value));
    {% elif modifier_type == 'Repeat' %}
    state.styleMap().mapNinePieceImageRepeat(value, image);
    {% elif modifier_type == 'Slice' %}
    state.styleMap().mapNinePieceImageSlice(value, image);
    {% elif modifier_type == 'Width' %}
    image.setBorderSlices(state.styleMap().mapNinePieceImageQuad(value));
    {% endif %}
    state.style()->setBorderImage(image);
}
{% endmacro %}
{{apply_border_image_modifier('CSSPropertyBorderImageOutset', 'Outset')}}
{{apply_border_image_modifier('CSSPropertyBorderImageRepeat', 'Repeat')}}
{{apply_border_image_modifier('CSSPropertyBorderImageSlice', 'Slice')}}
{{apply_border_image_modifier('CSSPropertyBorderImageWidth', 'Width')}}

{% macro apply_value_border_image_source(property_id) %}
{{declare_value_function(property_id)}}
{
    {% set property = properties[property_id] %}
    {{set_value(property)}}(state.styleImage({{property_id}}, value));
}
{% endmacro %}
{{apply_value_border_image_source('CSSPropertyBorderImageSource')}}

{% macro apply_color(property_id, initial_color='StyleColor::currentColor') %}
{% set property = properties[property_id] %}
{{declare_initial_function(property_id)}}
{
    StyleColor color = {{initial_color}}();
    {{set_value(property)}}(color);
}

{{declare_inherit_function(property_id)}}
{
    StyleColor color = state.parentStyle()->{{property.getter}}();
    Color resolvedColor = color.resolve(state.parentStyle()->color());
    {{set_value(property)}}(resolvedColor);
}

{{declare_value_function(property_id)}}
{
    {{set_value(property)}}(StyleBuilderConverter::convertColor(state, value));
}
{% endmacro %}
{{apply_color('CSSPropertyBackgroundColor', initial_color='RenderStyle::initialBackgroundColor') }}
{{apply_color('CSSPropertyBorderBottomColor')}}
{{apply_color('CSSPropertyBorderLeftColor')}}
{{apply_color('CSSPropertyBorderRightColor')}}
{{apply_color('CSSPropertyBorderTopColor')}}
{{apply_color('CSSPropertyOutlineColor')}}
{{apply_color('CSSPropertyTextDecorationColor')}}
{{apply_color('CSSPropertyWebkitTextEmphasisColor')}}
{{apply_color('CSSPropertyWebkitTextFillColor')}}
{{apply_color('CSSPropertyWebkitTextStrokeColor')}}

{% macro apply_counter(property_id, action) %}
{% set property = properties[property_id] %}
{{declare_initial_function(property_id)}} { }

{{declare_inherit_function(property_id)}}
{
    CounterDirectiveMap& map = state.style()->accessCounterDirectives();
    CounterDirectiveMap& parentMap = state.parentStyle()->accessCounterDirectives();

    typedef CounterDirectiveMap::iterator Iterator;
    Iterator end = parentMap.end();
    for (Iterator it = parentMap.begin(); it != end; ++it) {
        CounterDirectives& directives = map.add(it->key, CounterDirectives()).storedValue->value;
        directives.inherit{{action}}(it->value);
    }
}

{{declare_value_function(property_id)}}
{
    CounterDirectiveMap& map = state.style()->accessCounterDirectives();
    typedef CounterDirectiveMap::iterator Iterator;

    Iterator end = map.end();
    for (Iterator it = map.begin(); it != end; ++it)
        it->value.clear{{action}}();

    if (!value->isValueList()) {
        ASSERT(value->isPrimitiveValue() && toCSSPrimitiveValue(value)->getValueID() == CSSValueNone);
        return;
    }

    CSSValueList* list = toCSSValueList(value);

    int length = list ? list->length() : 0;
    for (int i = 0; i < length; ++i) {
        CSSValue* currValue = list->item(i);
        if (!currValue->isPrimitiveValue())
            continue;

        Pair* pair = toCSSPrimitiveValue(currValue)->getPairValue();
        if (!pair || !pair->first() || !pair->second())
            continue;

        AtomicString identifier(pair->first()->getStringValue());
        int value = pair->second()->getIntValue();
        CounterDirectives& directives = map.add(identifier, CounterDirectives()).storedValue->value;
        {% if action == 'Reset' %}
        directives.setResetValue(value);
        {% else %}
        directives.addIncrementValue(value);
        {% endif %}
    }
}
{% endmacro %}

{% macro apply_fill_layer(property_id, fill_type) %}
{% set access_layers = 'accessBackgroundLayers' %}
{% set map_fill = 'mapFill' + fill_type %}
{{declare_initial_function(property_id)}}
{
    FillLayer* currChild = &state.style()->{{access_layers}}();
    currChild->set{{fill_type}}(FillLayer::initialFill{{fill_type}}(BackgroundFillLayer));
    for (currChild = currChild->next(); currChild; currChild = currChild->next())
        currChild->clear{{fill_type}}();
}

{{declare_inherit_function(property_id)}}
{
    FillLayer* currChild = &state.style()->{{access_layers}}();
    FillLayer* prevChild = 0;
    const FillLayer* currParent = &state.parentStyle()->backgroundLayers();
    while (currParent && currParent->is{{fill_type}}Set()) {
        if (!currChild)
            currChild = prevChild->ensureNext();
        currChild->set{{fill_type}}(currParent->{{fill_type|lower_first}}());
        prevChild = currChild;
        currChild = prevChild->next();
        currParent = currParent->next();
    }

    while (currChild) {
        /* Reset any remaining layers to not have the property set. */
        currChild->clear{{fill_type}}();
        currChild = currChild->next();
    }
}

{{declare_value_function(property_id)}}
{
    FillLayer* currChild = &state.style()->{{access_layers}}();
    FillLayer* prevChild = 0;
    if (value->isValueList() && !value->isImageSetValue()) {
        /* Walk each value and put it into a layer, creating new layers as needed. */
        CSSValueList* valueList = toCSSValueList(value);
        for (unsigned int i = 0; i < valueList->length(); i++) {
            if (!currChild)
                currChild = prevChild->ensureNext();
            state.styleMap().{{map_fill}}(currChild, valueList->item(i));
            prevChild = currChild;
            currChild = currChild->next();
        }
    } else {
        state.styleMap().{{map_fill}}(currChild, value);
        currChild = currChild->next();
    }
    while (currChild) {
        /* Reset all remaining layers to not have the property set. */
        currChild->clear{{fill_type}}();
        currChild = currChild->next();
    }
}
{% endmacro %}
{{apply_fill_layer('CSSPropertyBackgroundAttachment', 'Attachment')}}
{{apply_fill_layer('CSSPropertyBackgroundClip', 'Clip')}}
{{apply_fill_layer('CSSPropertyBackgroundImage', 'Image')}}
{{apply_fill_layer('CSSPropertyBackgroundOrigin', 'Origin')}}
{{apply_fill_layer('CSSPropertyBackgroundPositionX', 'XPosition')}}
{{apply_fill_layer('CSSPropertyBackgroundPositionY', 'YPosition')}}
{{apply_fill_layer('CSSPropertyBackgroundRepeatX', 'RepeatX')}}
{{apply_fill_layer('CSSPropertyBackgroundRepeatY', 'RepeatY')}}
{{apply_fill_layer('CSSPropertyBackgroundSize', 'Size')}}
{{apply_fill_layer('CSSPropertyWebkitBackgroundComposite', 'Composite')}}

{% macro apply_value_number(property_id, id_for_minus_one) %}
{{declare_value_function(property_id)}}
{
    {% set property = properties[property_id] %}
    if (!value->isPrimitiveValue())
        return;

    CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
    if (primitiveValue->getValueID() == {{id_for_minus_one}})
        {{set_value(property)}}(-1);
    else
        {{set_value(property)}}(primitiveValue->getValue<{{property.type_name}}>(CSSPrimitiveValue::CSS_NUMBER));
}
{% endmacro %}

{% macro apply_alignment(property_id, alignment_type) %}
{% set property = properties[property_id] %}
{{declare_initial_function(property_id)}}
{
    state.style()->set{{alignment_type}}(RenderStyle::initial{{alignment_type}}());
    state.style()->set{{alignment_type}}OverflowAlignment(RenderStyle::initial{{alignment_type}}OverflowAlignment());
}

{{declare_inherit_function(property_id)}}
{
    state.style()->set{{alignment_type}}(state.parentStyle()->{{property.getter}}());
    state.style()->set{{alignment_type}}OverflowAlignment(state.parentStyle()->{{property.getter}}OverflowAlignment());
}

{{declare_value_function(property_id)}}
{
    CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
    if (Pair* pairValue = primitiveValue->getPairValue()) {
        state.style()->set{{alignment_type}}(*pairValue->first());
        state.style()->set{{alignment_type}}OverflowAlignment(*pairValue->second());
    } else {
        state.style()->set{{alignment_type}}(*primitiveValue);
    }
}
{% endmacro %}
{{apply_alignment('CSSPropertyAlignItems', 'AlignItems')}}
{{apply_alignment('CSSPropertyAlignSelf', 'AlignSelf')}}

} // namespace blink
