{% 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('CSSPropertyOrphans')}}
{{apply_auto('CSSPropertyWidows')}}
{{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) %}
{% set is_mask_box = 'MaskBox' in property_id %}
{% set getter = 'maskBoxImage' if is_mask_box else 'borderImage' %}
{% set setter = 'setMaskBoxImage' if is_mask_box else 'setBorderImage' %}
{{ declare_initial_function(property_id) }}
{
    const NinePieceImage& currentImage = state.style()->{{getter}}();
    {# 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' and is_mask_box %}
    // Masks have a different initial value for slices. Preserve the value of 0 for backwards compatibility.
    if (currentImage.fill() == true && lengthTypeAndValueMatch(currentImage.imageSlices(), Fixed, 0))
        return;
    {% elif modifier_type == 'Slice' and not is_mask_box %}
    if (currentImage.fill() == false && lengthTypeAndValueMatch(currentImage.imageSlices(), Percent, 100))
        return;
    {% elif modifier_type == 'Width' and is_mask_box %}
    // Masks have a different initial value for widths. Preserve the value of 'auto' for backwards compatibility.
    if (lengthTypeAndValueMatch(currentImage.borderSlices(), Auto, 0))
        return;
    {% elif modifier_type == 'Width' and not is_mask_box %}
    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' and is_mask_box %}
    image.setImageSlices(LengthBox({{ (['Length(0, Fixed)']*4) | join(', ') }}));
    image.setFill(true);
    {% elif modifier_type == 'Slice' and not is_mask_box %}
    image.setImageSlices(LengthBox({{ (['Length(100, Percent)']*4) | join(', ') }}));
    image.setFill(false);
    {% elif modifier_type == 'Width' %}
    image.setBorderSlices({{ 'Length(Auto)' if is_mask_box else '1.0' }});
    {% endif %}
    state.style()->{{setter}}(image);
}

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

{{declare_value_function(property_id)}}
{
    NinePieceImage image(state.style()->{{getter}}());
    {% 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()->{{setter}}(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')}}
{{apply_border_image_modifier('CSSPropertyWebkitMaskBoxImageOutset', 'Outset')}}
{{apply_border_image_modifier('CSSPropertyWebkitMaskBoxImageRepeat', 'Repeat')}}
{{apply_border_image_modifier('CSSPropertyWebkitMaskBoxImageSlice', 'Slice')}}
{{apply_border_image_modifier('CSSPropertyWebkitMaskBoxImageWidth', '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')}}
{{apply_value_border_image_source('CSSPropertyWebkitMaskBoxImageSource')}}

{% 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 layer_type = 'Background' if 'Background' in property_id else 'Mask' %}
{% set fill_layer_type = layer_type + 'FillLayer' %}
{% set access_layers = 'access' + layer_type + 'Layers' %}
{% 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}}({{fill_layer_type}}));
    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()->{{layer_type|lower}}Layers();
    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('CSSPropertyMaskSourceType', 'MaskSourceType')}}
{{apply_fill_layer('CSSPropertyWebkitBackgroundComposite', 'Composite')}}
{{apply_fill_layer('CSSPropertyWebkitMaskClip', 'Clip')}}
{{apply_fill_layer('CSSPropertyWebkitMaskComposite', 'Composite')}}
{{apply_fill_layer('CSSPropertyWebkitMaskImage', 'Image')}}
{{apply_fill_layer('CSSPropertyWebkitMaskOrigin', 'Origin')}}
{{apply_fill_layer('CSSPropertyWebkitMaskPositionX', 'XPosition')}}
{{apply_fill_layer('CSSPropertyWebkitMaskPositionY', 'YPosition')}}
{{apply_fill_layer('CSSPropertyWebkitMaskRepeatX', 'RepeatX')}}
{{apply_fill_layer('CSSPropertyWebkitMaskRepeatY', 'RepeatY')}}
{{apply_fill_layer('CSSPropertyWebkitMaskSize', 'Size')}}

{% 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
