// Copyright 2014 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef COBALT_RENDER_TREE_BRUSH_H_
#define COBALT_RENDER_TREE_BRUSH_H_

#include <cmath>
#include <memory>
#include <utility>
#include <vector>

#include "base/compiler_specific.h"
#include "cobalt/base/type_id.h"
#include "cobalt/math/point_f.h"
#include "cobalt/math/size_f.h"
#include "cobalt/render_tree/brush_visitor.h"
#include "cobalt/render_tree/color_rgba.h"

namespace cobalt {
namespace render_tree {

// A base class of all render tree brushes.
class Brush {
 public:
  virtual ~Brush() {}

  // A type-safe branching.
  virtual void Accept(BrushVisitor* visitor) const = 0;

  // Returns an ID that is unique to the brush type.  This can be used to
  // polymorphically identify what type a brush is.
  virtual base::TypeId GetTypeId() const = 0;
};

class SolidColorBrush : public Brush {
 public:
  explicit SolidColorBrush(const ColorRGBA& color) : color_(color) {}

  bool operator==(const SolidColorBrush& other) const {
    return color_ == other.color_;
  }

  // A type-safe branching.
  void Accept(BrushVisitor* visitor) const override;

  base::TypeId GetTypeId() const override {
    return base::GetTypeId<SolidColorBrush>();
  }

  const ColorRGBA& color() const { return color_; }

 private:
  ColorRGBA color_;
};

// ColorStops are used to describe linear and radial gradients.  For linear
// gradients, |position| represents the faction between the source and
// destination points that |color| should be applied.  For radial gradients,
// it represents the fraction between the center point and radius at which
// |color| should apply.  In both cases, 0 <= |position| <= 1.
struct ColorStop {
  ColorStop() : position(-1) {}
  ColorStop(float position, const ColorRGBA& color)
      : position(position), color(color) {}

  bool operator==(const ColorStop& other) const {
    return position == other.position && color == other.color;
  }

  float position;
  ColorRGBA color;
};

// Returns true if and only if two color stops are very close to each other.
inline bool IsNear(const render_tree::ColorStop& lhs,
                   const render_tree::ColorStop& rhs, float epsilon) {
  if (std::fabs(lhs.position - rhs.position) > epsilon) return false;
  return lhs.color == rhs.color;
}

typedef std::vector<ColorStop> ColorStopList;

bool IsNear(const render_tree::ColorStopList& lhs,
            const render_tree::ColorStopList& rhs, float epsilon);

// Calculate the source and destination points to use for a linear gradient
// of the specified angle to cover the given frame.
//
// The method of defining the source and destination points for the linear
// gradient are defined here:
//   https://www.w3.org/TR/2012/CR-css3-images-20120417/#linear-gradients
//
// "Starting from the center of the gradient box, extend a line at the
//  specified angle in both directions. The ending point is the point on the
//  gradient line where a line drawn perpendicular to the gradient line would
//  intersect the corner of the gradient box in the specified direction. The
//  starting point is determined identically, but in the opposite direction."
std::pair<math::PointF, math::PointF> LinearGradientPointsFromAngle(
    float ccw_radians_from_right, const math::SizeF& frame_size);

// Linear gradient brushes can be used to fill a shape with a linear color
// gradient with arbitrary many color stops.  It is specified by a source
// and destination point, which define a line segment along which the color
// stops apply, each having a position between 0 and 1 representing the
// position of the stop along that line.  Interpolation occurs in premultiplied
// alpha space.
// NOTE: The source and destination points may lie inside or outside the shape
// which uses the gradient brush. Always consider the shape as a mask over the
// gradient whose first and last color stops extend infinitely in their
// respective directions.
class LinearGradientBrush : public Brush {
 public:
  // The ColorStopList passed into LienarGradientBrush must have at least two
  // stops and they must be sorted in order of increasing position.
  LinearGradientBrush(const math::PointF& source, const math::PointF& dest,
                      const ColorStopList& color_stops);
  LinearGradientBrush(const std::pair<math::PointF, math::PointF>& source_dest,
                      const ColorStopList& color_stops)
      : LinearGradientBrush(source_dest.first, source_dest.second,
                            color_stops) {}

  // Creates a 2-stop linear gradient from source to dest.
  LinearGradientBrush(const math::PointF& source, const math::PointF& dest,
                      const ColorRGBA& source_color,
                      const ColorRGBA& dest_color);
  LinearGradientBrush(const std::pair<math::PointF, math::PointF>& source_dest,
                      const ColorRGBA& source_color,
                      const ColorRGBA& dest_color)
      : LinearGradientBrush(source_dest.first, source_dest.second, source_color,
                            dest_color) {}

  bool operator==(const LinearGradientBrush& other) const {
    return data_ == other.data_;
  }

  struct Data {
    Data();
    Data(const math::PointF& source, const math::PointF& dest,
         const ColorStopList& color_stops);
    Data(const math::PointF& source, const math::PointF& dest);

    bool operator==(const Data& other) const {
      return source_ == other.source_ && dest_ == other.dest_ &&
             color_stops_ == other.color_stops_;
    }
    math::PointF source_;
    math::PointF dest_;

    ColorStopList color_stops_;
  };

  // A type-safe branching.
  void Accept(BrushVisitor* visitor) const override;

  base::TypeId GetTypeId() const override {
    return base::GetTypeId<LinearGradientBrush>();
  }

  // Returns the source and destination points of the linear gradient.
  const math::PointF& source() const { return data_.source_; }
  const math::PointF& dest() const { return data_.dest_; }

  // Returns the list of color stops along the line segment between the source
  // and destination points.
  const ColorStopList& color_stops() const { return data_.color_stops_; }

  // Returns true if, and only if the brush is horizontal.
  bool IsHorizontal(float epsilon = 0.001f) const {
    return std::abs(data_.source_.y() - data_.dest_.y()) < epsilon;
  }

  // Returns true if, and only if the brush is vertical.
  bool IsVertical(float epsilon = 0.001f) const {
    return std::abs(data_.source_.x() - data_.dest_.x()) < epsilon;
  }

  const Data& data() const { return data_; }

 private:
  Data data_;
};

// A radial gradient brush can be used to fill a shape with a color gradient
// that expands from a given center point up to a specified radius.  The list
// of color stops have position values between 0 and 1 which represent the
// distance between the center point and the specified x-axis radius that the
// color should apply to.  Interpolation occurs in premultiplied alpha space.
class RadialGradientBrush : public Brush {
 public:
  // The ColorStopList passed into RadialGradientBrush must have at least two
  // stops and they must be sorted in order of increasing position.
  RadialGradientBrush(const math::PointF& center, float radius,
                      const ColorStopList& color_stops);

  // Constructor that allows for ellipses instead of circles.
  RadialGradientBrush(const math::PointF& center, float radius_x,
                      float radius_y, const ColorStopList& color_stops);

  // Creates a 2-stop radial gradient.
  RadialGradientBrush(const math::PointF& center, float radius,
                      const ColorRGBA& source_color,
                      const ColorRGBA& dest_color);

  // Constructor for ellipses instead of circles.
  RadialGradientBrush(const math::PointF& center, float radius_x,
                      float radius_y, const ColorRGBA& source_color,
                      const ColorRGBA& dest_color);

  bool operator==(const RadialGradientBrush& other) const {
    return center_ == other.center_ && radius_x_ == other.radius_x_ &&
           radius_y_ == other.radius_y_ && color_stops_ == other.color_stops_;
  }

  // A type-safe branching.
  void Accept(BrushVisitor* visitor) const override;

  base::TypeId GetTypeId() const override {
    return base::GetTypeId<RadialGradientBrush>();
  }

  // Returns the source and destination points of the linear gradient.
  const math::PointF& center() const { return center_; }
  float radius_x() const { return radius_x_; }
  float radius_y() const { return radius_y_; }

  // Returns the list of color stops from the center point to the radius.
  const ColorStopList& color_stops() const { return color_stops_; }

 private:
  math::PointF center_;
  float radius_x_;
  float radius_y_;

  ColorStopList color_stops_;
};

std::unique_ptr<Brush> CloneBrush(const Brush* brush);

class EqualsBrushVisitor : public BrushVisitor {
 public:
  explicit EqualsBrushVisitor(Brush* brush_a)
      : brush_a_(brush_a), result_(false) {}

  bool result() const { return result_; }

  void Visit(const SolidColorBrush* solid_color_brush) override {
    result_ =
        brush_a_->GetTypeId() == base::GetTypeId<SolidColorBrush>() &&
        *static_cast<const SolidColorBrush*>(brush_a_) == *solid_color_brush;
  }

  void Visit(const LinearGradientBrush* linear_gradient_brush) override {
    result_ = brush_a_->GetTypeId() == base::GetTypeId<LinearGradientBrush>() &&
              *static_cast<const LinearGradientBrush*>(brush_a_) ==
                  *linear_gradient_brush;
  }

  void Visit(const RadialGradientBrush* radial_gradient_brush) override {
    result_ = brush_a_->GetTypeId() == base::GetTypeId<RadialGradientBrush>() &&
              *static_cast<const RadialGradientBrush*>(brush_a_) ==
                  *radial_gradient_brush;
  }

 private:
  Brush* brush_a_;
  bool result_;
};

}  // namespace render_tree
}  // namespace cobalt

#endif  // COBALT_RENDER_TREE_BRUSH_H_
