{% from "macros.tmpl" import lower_first -%}

{#
    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"
#include "core/platform/animation/CSSAnimationDataList.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 %}

// FIXME: This is duplicated in StyleBuilder.cpp.tmpl, but we'll move the
// function definitions there over to here later.
{%- macro set_value(property) %}
{%- if property.svg -%}
    state.style()->accessSVGStyle()->{{property.setter}}
{%- else -%}
    state.style()->{{property.setter}}
{%- endif -%}
{%- endmacro %}

namespace WebCore {

{%- macro apply_animation(property_id, attribute, animation) %}
{{ declare_initial_function(property_id) }}
{
    CSSAnimationDataList* list = state.style()->access{{animation}}();
    if (list->isEmpty())
        list->append(CSSAnimationData::create());
    list->animation(0)->set{{attribute}}(CSSAnimationData::initialAnimation{{attribute}}());
    {%- if property_id == "CSSPropertyWebkitTransitionProperty" %}
        list->animation(0)->setAnimationMode(CSSAnimationData::AnimateAll);
    {%- endif %}
    for (size_t i = 1; i < list->size(); ++i)
        list->animation(i)->clear{{attribute}}();
}

{{ declare_inherit_function(property_id) }}
{
    CSSAnimationDataList* list = state.style()->access{{animation}}();
    const CSSAnimationDataList* parentList = state.parentStyle()->{{animation|lower}}();
    size_t i = 0, parentSize = parentList ? parentList->size() : 0;
    for ( ; i < parentSize && parentList->animation(i)->is{{attribute}}Set(); ++i) {
        ASSERT(list->size() >= i);
        if (list->size() == i)
            list->append(CSSAnimationData::create());
        list->animation(i)->set{{attribute}}(parentList->animation(i)->{{lower_first(attribute)}}());
        list->animation(i)->setAnimationMode(parentList->animation(i)->animationMode());
    }

    // Reset any remaining animations to not have the property set.
    for ( ; i < list->size(); ++i)
        list->animation(i)->clear{{attribute}}();
}

{{ declare_value_function(property_id) }}
{
    CSSAnimationDataList* list = state.style()->access{{animation}}();
    size_t childIndex = 0;
    if (value->isValueList()) {
        // Walk each value and put it into an animation, creating new animations as needed.
        for (CSSValueListIterator i = value; i.hasMore(); i.advance()) {
            ASSERT(list->size() >= childIndex);
            if (list->size() == childIndex)
                list->append(CSSAnimationData::create());
            state.styleMap().mapAnimation{{attribute}}(list->animation(childIndex), i.value());
            ++childIndex;
        }
    } else {
        if (list->isEmpty())
            list->append(CSSAnimationData::create());
        state.styleMap().mapAnimation{{attribute}}(list->animation(childIndex), value);
        childIndex = 1;
    }
    for ( ; childIndex < list->size(); ++childIndex) {
        // Reset all remaining animations to not have the property set.
        list->animation(childIndex)->clear{{attribute}}();
    }
}
{%- endmacro %}

{{ apply_animation("CSSPropertyWebkitAnimationDelay", "Delay", "Animations") }}
{{ apply_animation("CSSPropertyWebkitAnimationDirection", "Direction", "Animations") }}
{{ apply_animation("CSSPropertyWebkitAnimationDuration", "Duration", "Animations") }}
{{ apply_animation("CSSPropertyWebkitAnimationFillMode", "FillMode", "Animations") }}
{{ apply_animation("CSSPropertyWebkitAnimationIterationCount", "IterationCount", "Animations") }}
{{ apply_animation("CSSPropertyWebkitAnimationName", "Name", "Animations") }}
{{ apply_animation("CSSPropertyWebkitAnimationPlayState", "PlayState", "Animations") }}
{{ apply_animation("CSSPropertyWebkitAnimationTimingFunction", "TimingFunction", "Animations") }}
{{ apply_animation("CSSPropertyWebkitTransitionDelay", "Delay", "Transitions") }}
{{ apply_animation("CSSPropertyWebkitTransitionDuration", "Duration", "Transitions") }}
{{ apply_animation("CSSPropertyWebkitTransitionProperty", "Property", "Transitions") }}
{{ apply_animation("CSSPropertyWebkitTransitionTimingFunction", "TimingFunction", "Transitions") }}

{%- macro apply_auto(property_id, auto_getter=none, auto_setter=none, auto_identity="CSSValueAuto", compute_length=false) %}
{%- set property = properties[property_id] %}
{%- set auto_getter = auto_getter or "hasAuto" + property.camel_case_name %}
{%- set auto_setter = auto_setter or "setHasAuto" + property.camel_case_name %}
{{ 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
    {%- if compute_length %}
        {{ set_value(property) }}(primitiveValue->computeLength<{{property.type_name}}>(state.style(), state.rootElementStyle(), state.style()->effectiveZoom()));
    {%- else %}
        {{ set_value(property) }}(*primitiveValue);
    {%- endif %}
}
{%- endmacro %}

{{ apply_auto("CSSPropertyOrphans") }}
{{ apply_auto("CSSPropertyWebkitColumnCount") }}
{{ apply_auto("CSSPropertyWebkitColumnGap", auto_getter="hasNormalColumnGap", auto_setter="setHasNormalColumnGap", auto_identity="CSSValueNormal", compute_length=true) }}
{{ apply_auto("CSSPropertyWebkitColumnWidth", compute_length=true) }}
{{ apply_auto("CSSPropertyWidows") }}
{{ apply_auto("CSSPropertyZIndex") }}

{%- macro apply_value_border_image(property_id) %}
{{ declare_value_function(property_id) }}
{
    {%- set property = properties[property_id] %}
    NinePieceImage image;
    {%- if property_id == "CSSPropertyWebkitMaskBoxImage" %}
    image.setMaskDefaults();
    {%- endif %}
    state.styleMap().mapNinePieceImage(state.style(), {{property_id}}, value, image);
    {{ set_value(property) }}(image);
}
{%- endmacro %}

{{ apply_value_border_image("CSSPropertyWebkitBorderImage") }}
{{ apply_value_border_image("CSSPropertyWebkitMaskBoxImage") }}

{%- 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) }}
{
    NinePieceImage image(state.style()->{{getter}}());
    {%- if modifier_type == "Outset" %}
    image.setOutset(LengthBox(0));
    {%- elif modifier_type == "Repeat" %}
    image.setHorizontalRule(StretchImageRule);
    image.setVerticalRule(StretchImageRule);
    {%- elif modifier_type == "Slice" %}
    // Masks have a different initial value for slices. Preserve the value of 0 for backwards compatibility.
    image.setImageSlices(LengthBox({{ (["Length(100, Percent)"]*4) | join(", ") if not is_mask_box }}));
    image.setFill(false);
    {%- elif modifier_type == "Width" %}
    // Masks have a different initial value for widths. Preserve the value of 0 for backwards compatibility.
    image.setBorderSlices(LengthBox({{ (["Length(1, Relative)"]*4) | join(", ") if not is_mask_box }}));
    {%- 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, default_getter="color", initial_color=none, inherit_color=false) %}
{%- set property = properties[property_id] %}
{%- set visited_link_setter = "setVisitedLink" + property.camel_case_name %}
{{ declare_initial_function(property_id) }}
{
    Color color = {{ initial_color or "Color" -}}();
    if (state.applyPropertyToRegularStyle())
        {{ set_value(property) }}(color);
    if (state.applyPropertyToVisitedLinkStyle())
        state.style()->{{visited_link_setter}}(color);
}

{{ declare_inherit_function(property_id) }}
{
    // Visited link style can never explicitly inherit from parent visited link style so no separate getters are needed.
    Color color = state.parentStyle()->{{property.getter}}();
    if (!color.isValid())
        color = state.parentStyle()->{{default_getter}}();
    if (state.applyPropertyToRegularStyle())
        {{ set_value(property) }}(color);
    if (state.applyPropertyToVisitedLinkStyle())
        state.style()->{{visited_link_setter}}(color);
}

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

    CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);

{%- if inherit_color %}
    if (primitiveValue->getValueID() == CSSValueCurrentcolor) {
        applyInherit{{property_id}}(state);
        return;
    }
{%- endif %}

    if (state.applyPropertyToRegularStyle())
        {{ set_value(property) }}(state.document().textLinkColors().colorFromPrimitiveValue(primitiveValue, state.style()->visitedDependentColor(CSSPropertyColor)));
    if (state.applyPropertyToVisitedLinkStyle())
        state.style()->{{visited_link_setter}}(state.document().textLinkColors().colorFromPrimitiveValue(primitiveValue, state.style()->visitedDependentColor(CSSPropertyColor), state.element()->isLink() /* forVisitedLink */));
}
{%- endmacro %}

{{ apply_color("CSSPropertyBackgroundColor", default_getter="invalidColor") }}
{{ apply_color("CSSPropertyBorderBottomColor") }}
{{ apply_color("CSSPropertyBorderLeftColor") }}
{{ apply_color("CSSPropertyBorderRightColor") }}
{{ apply_color("CSSPropertyBorderTopColor") }}
{{ apply_color("CSSPropertyColor", inherit_color=true, default_getter="invalidColor", initial_color="RenderStyle::initialColor") }}
{{ apply_color("CSSPropertyOutlineColor") }}
{{ apply_color("CSSPropertyTextDecorationColor") }}
{{ apply_color("CSSPropertyWebkitColumnRuleColor") }}
{{ 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()).iterator->value;
        directives.inherit{{action}}(it->value);
    }
}

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

    CSSValueList* list = toCSSValueList(value);

    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}}();

    int length = list ? list->length() : 0;
    for (int i = 0; i < length; ++i) {
        CSSValue* currValue = list->itemWithoutBoundsCheck(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()).iterator->value;
        {%- if action == "Reset" %}
        directives.setResetValue(value);
        {%- else %}
        directives.addIncrementValue(value);
        {%- endif %}
    }
}
{%- endmacro %}

{{ apply_counter("CSSPropertyCounterIncrement", "Increment") }}
{{ apply_counter("CSSPropertyCounterReset", "Reset") }}

{%- 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) {
            /* Need to make a new layer.*/
            currChild = new FillLayer({{fill_layer_type}});
            prevChild->setNext(currChild);
        }
        currChild->set{{fill_type}}(currParent->{{lower_first(fill_type)}}());
        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) {
                /* Need to make a new layer to hold this value */
                currChild = new FillLayer({{fill_layer_type}});
                prevChild->setNext(currChild);
            }
            state.styleMap().{{map_fill}}({{property_id}}, currChild, valueList->itemWithoutBoundsCheck(i));
            prevChild = currChild;
            currChild = currChild->next();
        }
    } else {
        state.styleMap().{{map_fill}}({{property_id}}, 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("CSSPropertyBackgroundBlendMode", "BlendMode") }}
{{ 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_font(property_id, name_for_methods, initial, type_name) %}
{#- We specify the getters/setters here since they are on FontDescription
        and not RenderStyle #}
{%- set getter = lower_first(name_for_methods) %}
{%- set setter = "set" + name_for_methods %}
{{ declare_initial_function(property_id) }}
{
    state.fontBuilder().{{setter}}({{initial}});
}

{{ declare_inherit_function(property_id) }}
{
    state.fontBuilder().{{setter}}(state.parentFontDescription().{{getter}}());
}

{{ declare_value_function(property_id) }}
{
    if (!value->isPrimitiveValue())
        return;
    CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
    state.fontBuilder().{{setter}}(static_cast<{{type_name}}>(*primitiveValue));
}
{%- endmacro %}

{{ apply_font("CSSPropertyFontStyle", "Italic", "FontItalicOff", "FontItalic") }}
{{ apply_font("CSSPropertyFontVariant", "SmallCaps", "FontSmallCapsOff", "FontSmallCaps") }}
{{ apply_font("CSSPropertyTextRendering", "TextRenderingMode", "AutoTextRendering", "TextRenderingMode") }}
{{ apply_font("CSSPropertyWebkitFontKerning", "Kerning", "FontDescription::AutoKerning", "FontDescription::Kerning") }}
{{ apply_font("CSSPropertyWebkitFontSmoothing", "FontSmoothing", "AutoSmoothing", "FontSmoothingMode") }}

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

{{ apply_value_number("CSSPropertyInternalMarqueeRepetition", "CSSValueInfinite") }}

{%- macro apply_value_shape(property_id) %}
{{ declare_value_function(property_id) }}
{
    {%- set property = properties[property_id] %}
    if (value->isPrimitiveValue()) {
        CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
        if (primitiveValue->getValueID() == CSSValueAuto)
            {{ set_value(property) }}(0);
        else if (primitiveValue->getValueID() == CSSValueOutsideShape)
            {{ set_value(property) }}(ShapeValue::createOutsideValue());
        else if (primitiveValue->isShape()) {
            {{ set_value(property) }}(ShapeValue::createShapeValue(basicShapeForValue(state, primitiveValue->getShapeValue())));
        }
    } else if (value->isImageValue()) {
        {{ set_value(property) }}(ShapeValue::createImageValue(state.styleImage({{property_id}}, value)));
    }
}
{%- endmacro %}

{{ apply_value_shape("CSSPropertyWebkitShapeInside") }}
{{ apply_value_shape("CSSPropertyWebkitShapeOutside") }}

} // namespace WebCore
