/*
 * (C) 1999-2003 Lars Knoll (knoll@kde.org)
 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
 * Copyright (C) 2013 Intel Corporation. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "config.h"
#include "StylePropertyShorthand.h"
#include "RuntimeEnabledFeatures.h"

#include "wtf/HashMap.h"
#include "wtf/StdLibExtras.h"

namespace WebCore {

{%- for property_id, property in properties.items() %}

const StylePropertyShorthand& {{ property.camel_case_name }}Shorthand()
{
    static const CSSPropertyID {{ property.camel_case_name }}Properties[] = {
        {%- for longhand_id in property.camel_case_longhands %}
        {{ longhand_id }},
        {%- endfor %}
    };
    DEFINE_STATIC_LOCAL(StylePropertyShorthand, {{ property.camel_case_name }}Longhands, ({{ property_id }}, {{ property.camel_case_name }}Properties, WTF_ARRAY_LENGTH({{ property.camel_case_name }}Properties)));
    return {{ property.camel_case_name }}Longhands;
}
{%- endfor %}

// Returns an empty list if the property is not a shorthand
const StylePropertyShorthand& shorthandForProperty(CSSPropertyID propertyID)
{
    DEFINE_STATIC_LOCAL(StylePropertyShorthand, emptyShorthand, ());
    switch (propertyID) {
{%- for property_id, property in properties.items() %}
    {%- if property.camel_case_name not in ["width", "height", "marker"] %}
        case {{ property_id }}:
        {%- if property.runtime_conditional_getter %}
            if (!RuntimeEnabledFeatures::{{ property.runtime_conditional_getter }}())
                return emptyShorthand;
        {%- endif %}
            return {{ property.camel_case_name }}Shorthand();
    {%- endif %}
{%- endfor %}
    default: {
        return emptyShorthand;
    }
    }
}

const Vector<StylePropertyShorthand> matchingShorthandsForLonghand(CSSPropertyID propertyID)
{
    switch (propertyID) {
{%- for longhand_id, shorthands in longhands_dictionary.items() %}
    case {{ longhand_id }}: {
{%- if shorthands|length == 1 %}
    {% for shorthand in shorthands -%}
       return Vector<StylePropertyShorthand>(1, {{ shorthand.camel_case_name }}Shorthand());
    {%- endfor %}
{%- else %}
        Vector<StylePropertyShorthand> vectorShorthands;
        vectorShorthands.reserveInitialCapacity({{ shorthands|length }});
        {% for shorthand in shorthands -%}
        vectorShorthands.uncheckedAppend({{ shorthand.camel_case_name }}Shorthand());
        {% endfor -%}
        return vectorShorthands;
{% endif %}
    }
{%- endfor %}
    default:
        return Vector<StylePropertyShorthand>();
    }
}

} // namespace WebCore
