{% from 'macros.tmpl' import license, print_if %}
{{license()}}

#ifndef ComputedStyleBase_h
#define ComputedStyleBase_h

#include "core/ComputedStyleBaseConstants.h"
#include "core/CoreExport.h"
{% for field in fields if field.storage_type_path != None %}
#include "{{field.storage_type_path}}.h"
{% endfor %}

{# Returns the default value for the field, converted to fit in the storage container. #}
{% macro default_value(field) -%}
{# We only support enum fields for now. #}
static_cast<unsigned>({{field.default_value}})
{%- endmacro %}

namespace blink {

// The generated portion of ComputedStyle. For more info, see the header comment
// in ComputedStyle.h.
class CORE_EXPORT ComputedStyleBase {
 public:
  ALWAYS_INLINE ComputedStyleBase() :
  {% for field in fields %}
      {{field.name}}({{default_value(field)}}){{print_if(not loop.last, ',')}}
  {% endfor %}
  {}
  ~ComputedStyleBase() {}

  ALWAYS_INLINE ComputedStyleBase(const ComputedStyleBase& o) :
  {% for field in fields %}
      {{field.name}}(o.{{field.name}}){{print_if(not loop.last, ',')}}
  {% endfor %}
  {}

  bool operator==(const ComputedStyleBase& o) const {
    return true &&
    {% for field in fields %}
        {{field.name}} == o.{{field.name}}{{print_if(not loop.last, ' &&')}}
    {% endfor %}
        ;
  }

  bool operator!=(const ComputedStyleBase& o) const { return !(*this == o); }

  inline bool inheritedEqual(const ComputedStyleBase& o) const {
    return true &&
    {% for field in fields if field.is_property and field.is_inherited %}
        {{field.name}} == o.{{field.name}}{{print_if(not loop.last, ' &&')}}
    {% endfor %}
        ;
  }

  inline bool independentInheritedEqual(const ComputedStyleBase& o) const {
    return true &&
    {% for field in fields if field.is_property and field.is_inherited and field.is_independent %}
        {{field.name}} == o.{{field.name}}{{print_if(not loop.last, ' &&')}}
    {% endfor %}
        ;
  }

  inline bool nonIndependentInheritedEqual(const ComputedStyleBase& o) const {
    return true &&
    {% for field in fields if field.is_property and field.is_inherited and not field.is_independent %}
        {{field.name}} == o.{{field.name}}{{print_if(not loop.last, ' &&')}}
    {% endfor %}
        ;
  }

  inline bool nonInheritedEqual(const ComputedStyleBase& o) const {
    return true &&
    {% for field in fields if field.is_property and not field.is_inherited %}
        {{field.name}} == o.{{field.name}}{{print_if(not loop.last, ' &&')}}
    {% endfor %}
        ;
  }

  void setBitDefaults() {
    {% for field in fields %}
    {{field.resetter_method_name}}();
    {% endfor %}
  }

  enum IsAtShadowBoundary {
    AtShadowBoundary,
    NotAtShadowBoundary,
  };
  void inheritFrom(const ComputedStyleBase& inheritParent,
                   IsAtShadowBoundary isAtShadowBoundary = NotAtShadowBoundary);

  void copyNonInheritedFromCached(const ComputedStyleBase& other);

  // Copies the values of any independent inherited properties from the parent
  // style that are marked as inherited by this style.
  void propagateIndependentInheritedProperties(
      const ComputedStyleBase& parentStyle);

  // Fields.
  // TODO(sashab): Remove initialFoo() static methods and update callers to
  // use resetFoo(), which can be more efficient.
  {% for field in fields %}
  // {{field.property_name}}
  inline static {{field.storage_type}} {{field.initial_method_name}}() { return {{field.default_value}}; }
  {{field.storage_type}} {{field.getter_method_name}}() const { return static_cast<{{field.storage_type}}>({{field.name}}); }
  {% if field.is_nonproperty %}
  void {{field.setter_method_name}}() { {{field.name}} = static_cast<unsigned>(true); }
  {% else %}
  void {{field.setter_method_name}}({{field.storage_type}} v) { {{field.name}} = static_cast<unsigned>(v); }
  {% endif %}
  inline void {{field.resetter_method_name}}() { {{field.name}} = {{default_value(field)}}; }

  {% endfor %}
 protected:
  // Storage.
  {% for field in fields %}
  unsigned {{field.name}} : {{field.size}}; // {{field.storage_type}}
  {% endfor %}
};

} // namespace blink

#endif // ComputedStyleBase_h
