// Copyright 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CC_BASE_MATH_UTIL_H_
#define CC_BASE_MATH_UTIL_H_

#include <limits>
#include <memory>
#include <vector>

#include "base/logging.h"
#include "build/build_config.h"
#include "cc/base/base_export.h"
#include "ui/gfx/geometry/box_f.h"
#include "ui/gfx/geometry/point3_f.h"
#include "ui/gfx/geometry/point_f.h"
#include "ui/gfx/geometry/scroll_offset.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/transform.h"

namespace base {
class Value;
namespace trace_event {
class TracedValue;
}
}  // namespace base

namespace gfx {
class QuadF;
class Rect;
class RectF;
class SizeF;
class Transform;
class Vector2dF;
class Vector2d;
class Vector3dF;
}

namespace cc {

struct HomogeneousCoordinate {
  HomogeneousCoordinate(SkMScalar x, SkMScalar y, SkMScalar z, SkMScalar w) {
    vec[0] = x;
    vec[1] = y;
    vec[2] = z;
    vec[3] = w;
  }

  bool ShouldBeClipped() const { return w() <= 0.0; }

  gfx::PointF CartesianPoint2d() const {
    if (w() == SK_MScalar1)
      return gfx::PointF(x(), y());

    // For now, because this code is used privately only by MathUtil, it should
    // never be called when w == 0, and we do not yet need to handle that case.
    DCHECK(w());
    SkMScalar inv_w = SK_MScalar1 / w();
    return gfx::PointF(x() * inv_w, y() * inv_w);
  }

  gfx::Point3F CartesianPoint3d() const {
    if (w() == SK_MScalar1)
      return gfx::Point3F(x(), y(), z());

    // For now, because this code is used privately only by MathUtil, it should
    // never be called when w == 0, and we do not yet need to handle that case.
    DCHECK(w());
    SkMScalar inv_w = SK_MScalar1 / w();
    return gfx::Point3F(x() * inv_w, y() * inv_w, z() * inv_w);
  }

  SkMScalar x() const { return vec[0]; }
  SkMScalar y() const { return vec[1]; }
  SkMScalar z() const { return vec[2]; }
  SkMScalar w() const { return vec[3]; }

  SkMScalar vec[4];
};

class CC_BASE_EXPORT MathUtil {
 public:
  // Returns true if rounded up value does not overflow, false otherwise.
  template <typename T>
  static bool VerifyRoundup(T n, T mul) {
    return mul && (n <= (std::numeric_limits<T>::max() -
                         (std::numeric_limits<T>::max() % mul)));
  }

  // Rounds up a given |n| to be a multiple of |mul|, but may overflow.
  // Examples:
  //    - RoundUp(123, 50) returns 150.
  //    - RoundUp(-123, 50) returns -100.
  template <typename T>
  static T UncheckedRoundUp(T n, T mul) {
    static_assert(std::numeric_limits<T>::is_integer,
                  "T must be an integer type");
    return RoundUpInternal(n, mul);
  }

  // Similar to UncheckedRoundUp(), but dies with a CRASH() if rounding up a
  // given |n| overflows T.
  template <typename T>
  static T CheckedRoundUp(T n, T mul) {
    static_assert(std::numeric_limits<T>::is_integer,
                  "T must be an integer type");
    CHECK(VerifyRoundup(n, mul));
    return RoundUpInternal(n, mul);
  }

  // Returns true if rounded down value does not underflow, false otherwise.
  template <typename T>
  static bool VerifyRoundDown(T n, T mul) {
    return mul && (n >= (std::numeric_limits<T>::min() -
                         (std::numeric_limits<T>::min() % mul)));
  }

  // Rounds down a given |n| to be a multiple of |mul|, but may underflow.
  // Examples:
  //    - RoundDown(123, 50) returns 100.
  //    - RoundDown(-123, 50) returns -150.
  template <typename T>
  static T UncheckedRoundDown(T n, T mul) {
    static_assert(std::numeric_limits<T>::is_integer,
                  "T must be an integer type");
    return RoundDownInternal(n, mul);
  }

  // Similar to UncheckedRoundDown(), but dies with a CRASH() if rounding down a
  // given |n| underflows T.
  template <typename T>
  static T CheckedRoundDown(T n, T mul) {
    static_assert(std::numeric_limits<T>::is_integer,
                  "T must be an integer type");
    CHECK(VerifyRoundDown(n, mul));
    return RoundDownInternal(n, mul);
  }

  template <typename T>
  static bool IsWithinEpsilon(T a, T b) {
    return std::abs(a - b) < std::numeric_limits<T>::epsilon();
  }

  // Background: Existing transform code does not do the right thing in
  // MapRect / MapQuad / ProjectQuad when there is a perspective projection that
  // causes one of the transformed vertices to go to w < 0. In those cases, it
  // is necessary to perform clipping in homogeneous coordinates, after applying
  // the transform, before dividing-by-w to convert to cartesian coordinates.
  //
  // These functions return the axis-aligned rect that encloses the correctly
  // clipped, transformed polygon.
  static gfx::Rect MapEnclosingClippedRect(const gfx::Transform& transform,
                                           const gfx::Rect& rect);
  static gfx::RectF MapClippedRect(const gfx::Transform& transform,
                                   const gfx::RectF& rect);
  static gfx::Rect ProjectEnclosingClippedRect(const gfx::Transform& transform,
                                               const gfx::Rect& rect);
  static gfx::RectF ProjectClippedRect(const gfx::Transform& transform,
                                       const gfx::RectF& rect);

  // Map device space quad to local space. Device_transform has no 3d
  // component since it was flattened, so we don't need to project.  We should
  // have already checked that the transform was invertible before this call.
  static gfx::QuadF InverseMapQuadToLocalSpace(
      const gfx::Transform& device_transform,
      const gfx::QuadF& device_quad);

  // This function is only valid when the transform preserves 2d axis
  // alignment and the resulting rect will not be clipped.
  static gfx::Rect MapEnclosedRectWith2dAxisAlignedTransform(
      const gfx::Transform& transform,
      const gfx::Rect& rect);

  // Returns an array of vertices that represent the clipped polygon. After
  // returning, indexes from 0 to num_vertices_in_clipped_quad are valid in the
  // clipped_quad array. Note that num_vertices_in_clipped_quad may be zero,
  // which means the entire quad was clipped, and none of the vertices in the
  // array are valid.
  static bool MapClippedQuad3d(const gfx::Transform& transform,
                               const gfx::QuadF& src_quad,
                               gfx::Point3F clipped_quad[6],
                               int* num_vertices_in_clipped_quad);

  static gfx::RectF ComputeEnclosingRectOfVertices(const gfx::PointF vertices[],
                                                   int num_vertices);
  static gfx::RectF ComputeEnclosingClippedRect(
      const HomogeneousCoordinate& h1,
      const HomogeneousCoordinate& h2,
      const HomogeneousCoordinate& h3,
      const HomogeneousCoordinate& h4);

  // NOTE: These functions do not do correct clipping against w = 0 plane, but
  // they correctly detect the clipped condition via the boolean clipped.
  static gfx::QuadF MapQuad(const gfx::Transform& transform,
                            const gfx::QuadF& quad,
                            bool* clipped);
  static gfx::PointF MapPoint(const gfx::Transform& transform,
                              const gfx::PointF& point,
                              bool* clipped);
  static gfx::PointF ProjectPoint(const gfx::Transform& transform,
                                  const gfx::PointF& point,
                                  bool* clipped);
  // Identical to the above function, but coerces the homogeneous coordinate to
  // a 3d rather than a 2d point.
  static gfx::Point3F ProjectPoint3D(const gfx::Transform& transform,
                                     const gfx::PointF& point,
                                     bool* clipped);

  static gfx::Vector2dF ComputeTransform2dScaleComponents(const gfx::Transform&,
                                                          float fallbackValue);
  // Returns an approximate max scale value of the transform even if it has
  // perspective. Prefer to use ComputeTransform2dScaleComponents if there is no
  // perspective, since it can produce more accurate results.
  static float ComputeApproximateMaxScale(const gfx::Transform& transform);

  // Makes a rect that has the same relationship to input_outer_rect as
  // scale_inner_rect has to scale_outer_rect. scale_inner_rect should be
  // contained within scale_outer_rect, and likewise the rectangle that is
  // returned will be within input_outer_rect at a similar relative, scaled
  // position.
  static gfx::RectF ScaleRectProportional(const gfx::RectF& input_outer_rect,
                                          const gfx::RectF& scale_outer_rect,
                                          const gfx::RectF& scale_inner_rect);

  // Returns the smallest angle between the given two vectors in degrees.
  // Neither vector is assumed to be normalized.
  static float SmallestAngleBetweenVectors(const gfx::Vector2dF& v1,
                                           const gfx::Vector2dF& v2);

  // Projects the |source| vector onto |destination|. Neither vector is assumed
  // to be normalized.
  static gfx::Vector2dF ProjectVector(const gfx::Vector2dF& source,
                                      const gfx::Vector2dF& destination);

  // Conversion to value.
  static std::unique_ptr<base::Value> AsValue(const gfx::Size& s);
  static std::unique_ptr<base::Value> AsValue(const gfx::Rect& r);
  static bool FromValue(const base::Value*, gfx::Rect* out_rect);
  static std::unique_ptr<base::Value> AsValue(const gfx::PointF& q);

  static void AddToTracedValue(const char* name,
                               const gfx::Size& s,
                               base::trace_event::TracedValue* res);
  static void AddToTracedValue(const char* name,
                               const gfx::SizeF& s,
                               base::trace_event::TracedValue* res);
  static void AddToTracedValue(const char* name,
                               const gfx::Rect& r,
                               base::trace_event::TracedValue* res);
  static void AddToTracedValue(const char* name,
                               const gfx::Point& q,
                               base::trace_event::TracedValue* res);
  static void AddToTracedValue(const char* name,
                               const gfx::PointF& q,
                               base::trace_event::TracedValue* res);
  static void AddToTracedValue(const char* name,
                               const gfx::Point3F&,
                               base::trace_event::TracedValue* res);
  static void AddToTracedValue(const char* name,
                               const gfx::Vector2d& v,
                               base::trace_event::TracedValue* res);
  static void AddToTracedValue(const char* name,
                               const gfx::Vector2dF& v,
                               base::trace_event::TracedValue* res);
  static void AddToTracedValue(const char* name,
                               const gfx::ScrollOffset& v,
                               base::trace_event::TracedValue* res);
  static void AddToTracedValue(const char* name,
                               const gfx::QuadF& q,
                               base::trace_event::TracedValue* res);
  static void AddToTracedValue(const char* name,
                               const gfx::RectF& rect,
                               base::trace_event::TracedValue* res);
  static void AddToTracedValue(const char* name,
                               const gfx::Transform& transform,
                               base::trace_event::TracedValue* res);
  static void AddToTracedValue(const char* name,
                               const gfx::BoxF& box,
                               base::trace_event::TracedValue* res);

  // Returns a base::Value representation of the floating point value.
  // If the value is inf, returns max double/float representation.
  static double AsDoubleSafely(double value);
  static float AsFloatSafely(float value);

  // Returns vector that x axis (1,0,0) transforms to under given transform.
  static gfx::Vector3dF GetXAxis(const gfx::Transform& transform);

  // Returns vector that y axis (0,1,0) transforms to under given transform.
  static gfx::Vector3dF GetYAxis(const gfx::Transform& transform);

  static bool IsFloatNearlyTheSame(float left, float right);
  static bool IsNearlyTheSameForTesting(const gfx::PointF& l,
                                        const gfx::PointF& r);
  static bool IsNearlyTheSameForTesting(const gfx::Point3F& l,
                                        const gfx::Point3F& r);

 private:
  template <typename T>
  static T RoundUpInternal(T n, T mul) {
    return (n > 0) ? ((n + mul - 1) / mul) * mul : (n / mul) * mul;
  }

  template <typename T>
  static T RoundDownInternal(T n, T mul) {
    return (n > 0) ? (n / mul) * mul : (n == 0) ? 0
                                                : ((n - mul + 1) / mul) * mul;
  }
};

class CC_BASE_EXPORT ScopedSubnormalFloatDisabler {
 public:
  ScopedSubnormalFloatDisabler();
  ~ScopedSubnormalFloatDisabler();

 private:
#if defined(ARCH_CPU_X86_FAMILY)
  unsigned int orig_state_;
#endif
  DISALLOW_COPY_AND_ASSIGN(ScopedSubnormalFloatDisabler);
};

}  // namespace cc

#endif  // CC_BASE_MATH_UTIL_H_
