/*
    Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org>
                  2004, 2005 Rob Buis <buis@kde.org>
    Copyright (C) 2005, 2006 Apple Computer, Inc.
    Copyright (C) Research In Motion Limited 2010. 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.
*/

#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_SVG_COMPUTED_STYLE_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_SVG_COMPUTED_STYLE_H_

#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/css/style_color.h"
#include "third_party/blink/renderer/core/style/computed_style_constants.h"
#include "third_party/blink/renderer/core/style/data_ref.h"
#include "third_party/blink/renderer/core/style/svg_computed_style_defs.h"
#include "third_party/blink/renderer/platform/geometry/length.h"
#include "third_party/blink/renderer/platform/graphics/graphics_types.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
#include "third_party/blink/renderer/platform/wtf/ref_counted.h"

namespace blink {

class StyleDifference;

// TODO(sashab): Move this into a private class on ComputedStyle, and remove
// all methods on it, merging them into copy/creation methods on ComputedStyle
// instead. Keep the allocation logic, only allocating a new object if needed.
class SVGComputedStyle : public RefCounted<SVGComputedStyle> {
 public:
  static scoped_refptr<SVGComputedStyle> Create() {
    return base::AdoptRef(new SVGComputedStyle);
  }
  scoped_refptr<SVGComputedStyle> Copy() const {
    return base::AdoptRef(new SVGComputedStyle(*this));
  }
  CORE_EXPORT ~SVGComputedStyle();

  bool InheritedEqual(const SVGComputedStyle&) const;
  bool NonInheritedEqual(const SVGComputedStyle&) const;
  void InheritFrom(const SVGComputedStyle*);
  void CopyNonInheritedFromCached(const SVGComputedStyle*);

  CORE_EXPORT StyleDifference Diff(const SVGComputedStyle*) const;

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

  // Initial values for all the properties
  static EAlignmentBaseline InitialAlignmentBaseline() { return AB_AUTO; }
  static EDominantBaseline InitialDominantBaseline() { return DB_AUTO; }
  static EBaselineShift InitialBaselineShift() { return BS_LENGTH; }
  static Length InitialBaselineShiftValue() { return Length(kFixed); }
  static EVectorEffect InitialVectorEffect() { return VE_NONE; }
  static EBufferedRendering InitialBufferedRendering() { return BR_AUTO; }
  static LineCap InitialCapStyle() { return kButtCap; }
  static WindRule InitialClipRule() { return RULE_NONZERO; }
  static EColorInterpolation InitialColorInterpolation() { return CI_SRGB; }
  static EColorInterpolation InitialColorInterpolationFilters() {
    return CI_LINEARRGB;
  }
  static EColorRendering InitialColorRendering() { return CR_AUTO; }
  static WindRule InitialFillRule() { return RULE_NONZERO; }
  static LineJoin InitialJoinStyle() { return kMiterJoin; }
  static EShapeRendering InitialShapeRendering() { return SR_AUTO; }
  static ETextAnchor InitialTextAnchor() { return TA_START; }
  static float InitialFillOpacity() { return 1; }
  static SVGPaint InitialFillPaint() { return SVGPaint(Color::kBlack); }
  static float InitialStrokeOpacity() { return 1; }
  static SVGPaint InitialStrokePaint() { return SVGPaint(); }
  static scoped_refptr<SVGDashArray> InitialStrokeDashArray();
  static Length InitialStrokeDashOffset() { return Length(kFixed); }
  static float InitialStrokeMiterLimit() { return 4; }
  static UnzoomedLength InitialStrokeWidth() {
    return UnzoomedLength(Length(1, kFixed));
  }
  static float InitialStopOpacity() { return 1; }
  static Color InitialStopColor() { return Color(0, 0, 0); }
  static float InitialFloodOpacity() { return 1; }
  static Color InitialFloodColor() { return Color(0, 0, 0); }
  static Color InitialLightingColor() { return Color(255, 255, 255); }
  static StyleSVGResource* InitialMaskerResource() { return nullptr; }
  static StyleSVGResource* InitialMarkerStartResource() { return nullptr; }
  static StyleSVGResource* InitialMarkerMidResource() { return nullptr; }
  static StyleSVGResource* InitialMarkerEndResource() { return nullptr; }
  static EMaskType InitialMaskType() { return MT_LUMINANCE; }
  static EPaintOrder InitialPaintOrder() { return kPaintOrderNormal; }
  static StylePath* InitialD() { return nullptr; }
  static Length InitialCx() { return Length(kFixed); }
  static Length InitialCy() { return Length(kFixed); }
  static Length InitialX() { return Length(kFixed); }
  static Length InitialY() { return Length(kFixed); }
  static Length InitialR() { return Length(kFixed); }
  static Length InitialRx() { return Length(kAuto); }
  static Length InitialRy() { return Length(kAuto); }

  // SVG CSS Property setters
  void SetAlignmentBaseline(EAlignmentBaseline val) {
    svg_noninherited_flags.f.alignment_baseline = val;
  }
  void SetDominantBaseline(EDominantBaseline val) {
    svg_inherited_flags.dominant_baseline = val;
  }
  void SetBaselineShift(EBaselineShift val) {
    svg_noninherited_flags.f.baseline_shift = val;
  }
  void SetVectorEffect(EVectorEffect val) {
    svg_noninherited_flags.f.vector_effect = val;
  }
  void SetBufferedRendering(EBufferedRendering val) {
    svg_noninherited_flags.f.buffered_rendering = val;
  }
  void SetCapStyle(LineCap val) { svg_inherited_flags.cap_style = val; }
  void SetClipRule(WindRule val) { svg_inherited_flags.clip_rule = val; }
  void SetColorInterpolation(EColorInterpolation val) {
    svg_inherited_flags.color_interpolation = val;
  }
  void SetColorInterpolationFilters(EColorInterpolation val) {
    svg_inherited_flags.color_interpolation_filters = val;
  }
  void SetColorRendering(EColorRendering val) {
    svg_inherited_flags.color_rendering = val;
  }
  void SetFillRule(WindRule val) { svg_inherited_flags.fill_rule = val; }
  void SetJoinStyle(LineJoin val) { svg_inherited_flags.join_style = val; }
  void SetShapeRendering(EShapeRendering val) {
    svg_inherited_flags.shape_rendering = val;
  }
  void SetTextAnchor(ETextAnchor val) { svg_inherited_flags.text_anchor = val; }
  void SetMaskType(EMaskType val) { svg_noninherited_flags.f.mask_type = val; }
  void SetPaintOrder(EPaintOrder val) {
    svg_inherited_flags.paint_order = (int)val;
  }
  void SetD(scoped_refptr<StylePath> d) {
    if (!(geometry->d == d))
      geometry.Access()->d = std::move(d);
  }
  void SetCx(const Length& obj) {
    if (!(geometry->cx == obj))
      geometry.Access()->cx = obj;
  }
  void SetCy(const Length& obj) {
    if (!(geometry->cy == obj))
      geometry.Access()->cy = obj;
  }
  void SetX(const Length& obj) {
    if (!(geometry->x == obj))
      geometry.Access()->x = obj;
  }
  void SetY(const Length& obj) {
    if (!(geometry->y == obj))
      geometry.Access()->y = obj;
  }
  void SetR(const Length& obj) {
    if (!(geometry->r == obj))
      geometry.Access()->r = obj;
  }
  void SetRx(const Length& obj) {
    if (!(geometry->rx == obj))
      geometry.Access()->rx = obj;
  }
  void SetRy(const Length& obj) {
    if (!(geometry->ry == obj))
      geometry.Access()->ry = obj;
  }
  void SetFillOpacity(float obj) {
    if (!(fill->opacity == obj))
      fill.Access()->opacity = obj;
  }

  void SetFillPaint(const SVGPaint& paint) {
    if (!(fill->paint == paint))
      fill.Access()->paint = paint;
  }

  void SetVisitedLinkFillPaint(const SVGPaint& paint) {
    if (!(fill->visited_link_paint == paint))
      fill.Access()->visited_link_paint = paint;
  }

  void SetStrokeOpacity(float obj) {
    if (!(stroke->opacity == obj))
      stroke.Access()->opacity = obj;
  }

  void SetStrokePaint(const SVGPaint& paint) {
    if (!(stroke->paint == paint))
      stroke.Access()->paint = paint;
  }

  void SetVisitedLinkStrokePaint(const SVGPaint& paint) {
    if (!(stroke->visited_link_paint == paint))
      stroke.Access()->visited_link_paint = paint;
  }

  void SetStrokeDashArray(scoped_refptr<SVGDashArray> dash_array) {
    if (*stroke->dash_array != *dash_array)
      stroke.Access()->dash_array = std::move(dash_array);
  }

  void SetStrokeMiterLimit(float obj) {
    if (!(stroke->miter_limit == obj))
      stroke.Access()->miter_limit = obj;
  }

  void SetStrokeWidth(const UnzoomedLength& stroke_width) {
    if (!(stroke->width == stroke_width))
      stroke.Access()->width = stroke_width;
  }

  void SetStrokeDashOffset(const Length& dash_offset) {
    if (!(stroke->dash_offset == dash_offset))
      stroke.Access()->dash_offset = dash_offset;
  }

  void SetStopOpacity(float obj) {
    if (!(stops->opacity == obj))
      stops.Access()->opacity = obj;
  }

  void SetStopColor(const Color& obj) {
    if (!(stops->color == obj))
      stops.Access()->color = obj;
  }

  void SetFloodOpacity(float obj) {
    if (!(misc->flood_opacity == obj))
      misc.Access()->flood_opacity = obj;
  }

  void SetFloodColor(const StyleColor& style_color) {
    if (FloodColor() != style_color) {
      StyleMiscData* mutable_misc = misc.Access();
      mutable_misc->flood_color = style_color.Resolve(Color());
      mutable_misc->flood_color_is_current_color = style_color.IsCurrentColor();
    }
  }

  void SetLightingColor(const StyleColor& style_color) {
    if (LightingColor() != style_color) {
      StyleMiscData* mutable_misc = misc.Access();
      mutable_misc->lighting_color = style_color.Resolve(Color());
      mutable_misc->lighting_color_is_current_color =
          style_color.IsCurrentColor();
    }
  }

  void SetBaselineShiftValue(const Length& baseline_shift_value) {
    if (!(misc->baseline_shift_value == baseline_shift_value))
      misc.Access()->baseline_shift_value = baseline_shift_value;
  }

  // Setters for non-inherited resources
  void SetMaskerResource(scoped_refptr<StyleSVGResource> resource);

  // Setters for inherited resources
  void SetMarkerStartResource(scoped_refptr<StyleSVGResource> resource);

  void SetMarkerMidResource(scoped_refptr<StyleSVGResource> resource);

  void SetMarkerEndResource(scoped_refptr<StyleSVGResource> resource);

  // Read accessors for all the properties
  EAlignmentBaseline AlignmentBaseline() const {
    return (EAlignmentBaseline)svg_noninherited_flags.f.alignment_baseline;
  }
  EDominantBaseline DominantBaseline() const {
    return (EDominantBaseline)svg_inherited_flags.dominant_baseline;
  }
  EBaselineShift BaselineShift() const {
    return (EBaselineShift)svg_noninherited_flags.f.baseline_shift;
  }
  EVectorEffect VectorEffect() const {
    return (EVectorEffect)svg_noninherited_flags.f.vector_effect;
  }
  EBufferedRendering BufferedRendering() const {
    return (EBufferedRendering)svg_noninherited_flags.f.buffered_rendering;
  }
  LineCap CapStyle() const { return (LineCap)svg_inherited_flags.cap_style; }
  WindRule ClipRule() const { return (WindRule)svg_inherited_flags.clip_rule; }
  EColorInterpolation ColorInterpolation() const {
    return (EColorInterpolation)svg_inherited_flags.color_interpolation;
  }
  EColorInterpolation ColorInterpolationFilters() const {
    return (EColorInterpolation)svg_inherited_flags.color_interpolation_filters;
  }
  EColorRendering ColorRendering() const {
    return (EColorRendering)svg_inherited_flags.color_rendering;
  }
  WindRule FillRule() const { return (WindRule)svg_inherited_flags.fill_rule; }
  LineJoin JoinStyle() const {
    return (LineJoin)svg_inherited_flags.join_style;
  }
  EShapeRendering ShapeRendering() const {
    return (EShapeRendering)svg_inherited_flags.shape_rendering;
  }
  ETextAnchor TextAnchor() const {
    return (ETextAnchor)svg_inherited_flags.text_anchor;
  }
  float FillOpacity() const { return fill->opacity; }
  const SVGPaint& FillPaint() const { return fill->paint; }
  float StrokeOpacity() const { return stroke->opacity; }
  const SVGPaint& StrokePaint() const { return stroke->paint; }
  SVGDashArray* StrokeDashArray() const { return stroke->dash_array.get(); }
  float StrokeMiterLimit() const { return stroke->miter_limit; }
  const UnzoomedLength& StrokeWidth() const { return stroke->width; }
  const Length& StrokeDashOffset() const { return stroke->dash_offset; }
  float StopOpacity() const { return stops->opacity; }
  const Color& StopColor() const { return stops->color; }
  float FloodOpacity() const { return misc->flood_opacity; }
  StyleColor FloodColor() const {
    return misc->flood_color_is_current_color ? StyleColor::CurrentColor()
                                              : StyleColor(misc->flood_color);
  }
  StyleColor LightingColor() const {
    return misc->lighting_color_is_current_color
               ? StyleColor::CurrentColor()
               : StyleColor(misc->lighting_color);
  }
  const Length& BaselineShiftValue() const {
    return misc->baseline_shift_value;
  }
  StylePath* D() const { return geometry->d.get(); }
  const Length& Cx() const { return geometry->cx; }
  const Length& Cy() const { return geometry->cy; }
  const Length& X() const { return geometry->x; }
  const Length& Y() const { return geometry->y; }
  const Length& R() const { return geometry->r; }
  const Length& Rx() const { return geometry->rx; }
  const Length& Ry() const { return geometry->ry; }
  StyleSVGResource* MaskerResource() const { return resources->masker.get(); }
  StyleSVGResource* MarkerStartResource() const {
    return inherited_resources->marker_start.get();
  }
  StyleSVGResource* MarkerMidResource() const {
    return inherited_resources->marker_mid.get();
  }
  StyleSVGResource* MarkerEndResource() const {
    return inherited_resources->marker_end.get();
  }
  EMaskType MaskType() const {
    return (EMaskType)svg_noninherited_flags.f.mask_type;
  }
  EPaintOrder PaintOrder() const {
    return (EPaintOrder)svg_inherited_flags.paint_order;
  }
  EPaintOrderType PaintOrderType(unsigned index) const;

  const SVGPaint& VisitedLinkFillPaint() const {
    return fill->visited_link_paint;
  }
  const SVGPaint& VisitedLinkStrokePaint() const {
    return stroke->visited_link_paint;
  }

  bool IsFillColorCurrentColor() const {
    return FillPaint().HasCurrentColor() ||
           VisitedLinkFillPaint().HasCurrentColor();
  }

  bool IsStrokeColorCurrentColor() const {
    return StrokePaint().HasCurrentColor() ||
           VisitedLinkStrokePaint().HasCurrentColor();
  }

  // convenience
  bool HasMasker() const { return MaskerResource(); }
  bool HasMarkers() const {
    return MarkerStartResource() || MarkerMidResource() || MarkerEndResource();
  }
  bool HasStroke() const { return !StrokePaint().IsNone(); }
  bool HasVisibleStroke() const {
    return HasStroke() && !StrokeWidth().IsZero();
  }
  bool HasFill() const { return !FillPaint().IsNone(); }

 protected:
  // inherit
  struct InheritedFlags {
    bool operator==(const InheritedFlags& other) const {
      return (color_rendering == other.color_rendering) &&
             (shape_rendering == other.shape_rendering) &&
             (clip_rule == other.clip_rule) && (fill_rule == other.fill_rule) &&
             (cap_style == other.cap_style) &&
             (join_style == other.join_style) &&
             (text_anchor == other.text_anchor) &&
             (color_interpolation == other.color_interpolation) &&
             (color_interpolation_filters ==
              other.color_interpolation_filters) &&
             (paint_order == other.paint_order) &&
             (dominant_baseline == other.dominant_baseline);
    }

    bool operator!=(const InheritedFlags& other) const {
      return !(*this == other);
    }

    unsigned color_rendering : 2;              // EColorRendering
    unsigned shape_rendering : 2;              // EShapeRendering
    unsigned clip_rule : 1;                    // WindRule
    unsigned fill_rule : 1;                    // WindRule
    unsigned cap_style : 2;                    // LineCap
    unsigned join_style : 2;                   // LineJoin
    unsigned text_anchor : 2;                  // ETextAnchor
    unsigned color_interpolation : 2;          // EColorInterpolation
    unsigned color_interpolation_filters : 2;  // EColorInterpolation_
    unsigned paint_order : 3;                  // EPaintOrder
    unsigned dominant_baseline : 4;            // EDominantBaseline
  } svg_inherited_flags;

  // don't inherit
  struct NonInheritedFlags {
    // 32 bit non-inherited, don't add to the struct, or the operator will
    // break.
    bool operator==(const NonInheritedFlags& other) const {
      return niflags == other.niflags;
    }
    bool operator!=(const NonInheritedFlags& other) const {
      return niflags != other.niflags;
    }

    union {
      struct {
        unsigned alignment_baseline : 4;  // EAlignmentBaseline
        unsigned baseline_shift : 2;      // EBaselineShift
        unsigned vector_effect : 1;       // EVectorEffect
        unsigned buffered_rendering : 2;  // EBufferedRendering
        unsigned mask_type : 1;           // EMaskType
                                          // 18 bits unused
      } f;
      uint32_t niflags;
    };
  } svg_noninherited_flags;

  // inherited attributes
  DataRef<StyleFillData> fill;
  DataRef<StyleStrokeData> stroke;
  DataRef<StyleInheritedResourceData> inherited_resources;

  // non-inherited attributes
  DataRef<StyleStopData> stops;
  DataRef<StyleMiscData> misc;
  DataRef<StyleGeometryData> geometry;
  DataRef<StyleResourceData> resources;

 private:
  enum CreateInitialType { kCreateInitial };

  CORE_EXPORT SVGComputedStyle();
  SVGComputedStyle(const SVGComputedStyle&);
  SVGComputedStyle(
      CreateInitialType);  // Used to create the initial style singleton.

  bool DiffNeedsLayoutAndPaintInvalidation(const SVGComputedStyle* other) const;
  bool DiffNeedsPaintInvalidation(const SVGComputedStyle* other) const;

  void SetBitDefaults() {
    svg_inherited_flags.clip_rule = InitialClipRule();
    svg_inherited_flags.color_rendering = InitialColorRendering();
    svg_inherited_flags.fill_rule = InitialFillRule();
    svg_inherited_flags.shape_rendering = InitialShapeRendering();
    svg_inherited_flags.text_anchor = InitialTextAnchor();
    svg_inherited_flags.cap_style = InitialCapStyle();
    svg_inherited_flags.join_style = InitialJoinStyle();
    svg_inherited_flags.color_interpolation = InitialColorInterpolation();
    svg_inherited_flags.color_interpolation_filters =
        InitialColorInterpolationFilters();
    svg_inherited_flags.paint_order = InitialPaintOrder();
    svg_inherited_flags.dominant_baseline = InitialDominantBaseline();

    svg_noninherited_flags.niflags = 0;
    svg_noninherited_flags.f.alignment_baseline = InitialAlignmentBaseline();
    svg_noninherited_flags.f.baseline_shift = InitialBaselineShift();
    svg_noninherited_flags.f.vector_effect = InitialVectorEffect();
    svg_noninherited_flags.f.buffered_rendering = InitialBufferedRendering();
    svg_noninherited_flags.f.mask_type = InitialMaskType();
  }
};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_SVG_COMPUTED_STYLE_H_
