// Copyright (c) 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 UI_GFX_TRANSFORM_H_
#define UI_GFX_TRANSFORM_H_

#include <iosfwd>
#include <string>

#include "base/compiler_specific.h"
#include "third_party/skia/include/core/SkMatrix44.h"
#include "ui/gfx/gfx_export.h"
#include "ui/gfx/vector2d_f.h"

namespace gfx {

class BoxF;
class RectF;
class Point;
class Point3F;
class Vector3dF;

// 4x4 transformation matrix. Transform is cheap and explicitly allows
// copy/assign.
class GFX_EXPORT Transform {
 public:
  enum SkipInitialization { kSkipInitialization };

  Transform() : matrix_(SkMatrix44::kIdentity_Constructor) {}

  // Skips initializing this matrix to avoid overhead, when we know it will be
  // initialized before use.
  Transform(SkipInitialization)
      : matrix_(SkMatrix44::kUninitialized_Constructor) {}
  Transform(const Transform& rhs) : matrix_(rhs.matrix_) {}
  // Initialize with the concatenation of lhs * rhs.
  Transform(const Transform& lhs, const Transform& rhs)
      : matrix_(lhs.matrix_, rhs.matrix_) {}
  // Constructs a transform from explicit 16 matrix elements. Elements
  // should be given in row-major order.
  Transform(SkMScalar col1row1,
            SkMScalar col2row1,
            SkMScalar col3row1,
            SkMScalar col4row1,
            SkMScalar col1row2,
            SkMScalar col2row2,
            SkMScalar col3row2,
            SkMScalar col4row2,
            SkMScalar col1row3,
            SkMScalar col2row3,
            SkMScalar col3row3,
            SkMScalar col4row3,
            SkMScalar col1row4,
            SkMScalar col2row4,
            SkMScalar col3row4,
            SkMScalar col4row4);
  // Constructs a transform from explicit 2d elements. All other matrix
  // elements remain the same as the corresponding elements of an identity
  // matrix.
  Transform(SkMScalar col1row1,
            SkMScalar col2row1,
            SkMScalar col1row2,
            SkMScalar col2row2,
            SkMScalar x_translation,
            SkMScalar y_translation);
  ~Transform() {}

  bool operator==(const Transform& rhs) const { return matrix_ == rhs.matrix_; }
  bool operator!=(const Transform& rhs) const { return matrix_ != rhs.matrix_; }

  // Resets this transform to the identity transform.
  void MakeIdentity() { matrix_.setIdentity(); }

  // Applies the current transformation on a 2d rotation and assigns the result
  // to |this|.
  void Rotate(double degrees) { RotateAboutZAxis(degrees); }

  // Applies the current transformation on an axis-angle rotation and assigns
  // the result to |this|.
  void RotateAboutXAxis(double degrees);
  void RotateAboutYAxis(double degrees);
  void RotateAboutZAxis(double degrees);
  void RotateAbout(const Vector3dF& axis, double degrees);

  // Applies the current transformation on a scaling and assigns the result
  // to |this|.
  void Scale(SkMScalar x, SkMScalar y);
  void Scale3d(SkMScalar x, SkMScalar y, SkMScalar z);
  gfx::Vector2dF Scale2d() const {
    return gfx::Vector2dF(matrix_.get(0, 0), matrix_.get(1, 1));
  }

  // Applies the current transformation on a translation and assigns the result
  // to |this|.
  void Translate(SkMScalar x, SkMScalar y);
  void Translate3d(SkMScalar x, SkMScalar y, SkMScalar z);

  // Applies the current transformation on a skew and assigns the result
  // to |this|.
  void SkewX(double angle_x);
  void SkewY(double angle_y);

  // Applies the current transformation on a perspective transform and assigns
  // the result to |this|.
  void ApplyPerspectiveDepth(SkMScalar depth);

  // Applies a transformation on the current transformation
  // (i.e. 'this = this * transform;').
  void PreconcatTransform(const Transform& transform);

  // Applies a transformation on the current transformation
  // (i.e. 'this = transform * this;').
  void ConcatTransform(const Transform& transform);

  // Returns true if this is the identity matrix.
  bool IsIdentity() const { return matrix_.isIdentity(); }

  // Returns true if the matrix is either identity or pure translation.
  bool IsIdentityOrTranslation() const { return matrix_.isTranslate(); }

  // Returns true if the matrix is either the identity or a 2d translation.
  bool IsIdentityOr2DTranslation() const {
    return matrix_.isTranslate() && matrix_.get(2, 3) == 0;
  }

  // Returns true if the matrix is either identity or pure translation,
  // allowing for an amount of inaccuracy as specified by the parameter.
  bool IsApproximatelyIdentityOrTranslation(SkMScalar tolerance) const;

  // Returns true if the matrix is either a positive scale and/or a translation.
  bool IsPositiveScaleOrTranslation() const {
    if (!IsScaleOrTranslation())
      return false;
    return matrix_.get(0, 0) > 0.0 && matrix_.get(1, 1) > 0.0 &&
           matrix_.get(2, 2) > 0.0;
  }

  // Returns true if the matrix is either identity or pure, non-fractional
  // translation.
  bool IsIdentityOrIntegerTranslation() const;

  // Returns true if the matrix had only scaling components.
  bool IsScale2d() const {
    return !(matrix_.getType() & ~SkMatrix44::kScale_Mask);
  }

  // Returns true if the matrix is has only scaling and translation components.
  bool IsScaleOrTranslation() const { return matrix_.isScaleTranslate(); }

  // Returns true if axis-aligned 2d rects will remain axis-aligned after being
  // transformed by this matrix.
  bool Preserves2dAxisAlignment() const;

  // Returns true if the matrix has any perspective component that would
  // change the w-component of a homogeneous point.
  bool HasPerspective() const { return matrix_.hasPerspective(); }

  // Returns true if this transform is non-singular.
  bool IsInvertible() const { return matrix_.invert(NULL); }

  // Returns true if a layer with a forward-facing normal of (0, 0, 1) would
  // have its back side facing frontwards after applying the transform.
  bool IsBackFaceVisible() const;

  // Inverts the transform which is passed in. Returns true if successful.
  bool GetInverse(Transform* transform) const WARN_UNUSED_RESULT;

  // Transposes this transform in place.
  void Transpose();

  // Set 3rd row and 3rd colum to (0, 0, 1, 0). Note that this flattening
  // operation is not quite the same as an orthographic projection and is
  // technically not a linear operation.
  //
  // One useful interpretation of doing this operation:
  //  - For x and y values, the new transform behaves effectively like an
  //    orthographic projection was added to the matrix sequence.
  //  - For z values, the new transform overrides any effect that the transform
  //    had on z, and instead it preserves the z value for any points that are
  //    transformed.
  //  - Because of linearity of transforms, this flattened transform also
  //    preserves the effect that any subsequent (multiplied from the right)
  //    transforms would have on z values.
  //
  void FlattenTo2d();

  // Returns true if the 3rd row and 3rd column are both (0, 0, 1, 0).
  bool IsFlat() const;

  // Returns the x and y translation components of the matrix.
  Vector2dF To2dTranslation() const;

  // Applies the transformation to the point.
  void TransformPoint(Point3F* point) const;

  // Applies the transformation to the point.
  void TransformPoint(Point* point) const;

  // Applies the reverse transformation on the point. Returns true if the
  // transformation can be inverted.
  bool TransformPointReverse(Point3F* point) const;

  // Applies the reverse transformation on the point. Returns true if the
  // transformation can be inverted. Rounds the result to the nearest point.
  bool TransformPointReverse(Point* point) const;

  // Applies transformation on the given rect. After the function completes,
  // |rect| will be the smallest axis aligned bounding rect containing the
  // transformed rect.
  void TransformRect(RectF* rect) const;

  // Applies the reverse transformation on the given rect. After the function
  // completes, |rect| will be the smallest axis aligned bounding rect
  // containing the transformed rect. Returns false if the matrix cannot be
  // inverted.
  bool TransformRectReverse(RectF* rect) const;

  // Applies transformation on the given box. After the function completes,
  // |box| will be the smallest axis aligned bounding box containing the
  // transformed box.
  void TransformBox(BoxF* box) const;

  // Applies the reverse transformation on the given box. After the function
  // completes, |box| will be the smallest axis aligned bounding box
  // containing the transformed box. Returns false if the matrix cannot be
  // inverted.
  bool TransformBoxReverse(BoxF* box) const;

  // Decomposes |this| and |from|, interpolates the decomposed values, and
  // sets |this| to the reconstituted result. Returns false if either matrix
  // can't be decomposed. Uses routines described in this spec:
  // http://www.w3.org/TR/css3-3d-transforms/.
  //
  // Note: this call is expensive since we need to decompose the transform. If
  // you're going to be calling this rapidly (e.g., in an animation) you should
  // decompose once using gfx::DecomposeTransforms and reuse your
  // DecomposedTransform.
  bool Blend(const Transform& from, double progress);

  void RoundTranslationComponents();

  // Returns |this| * |other|.
  Transform operator*(const Transform& other) const {
    return Transform(*this, other);
  }

  // Sets |this| = |this| * |other|
  Transform& operator*=(const Transform& other) {
    PreconcatTransform(other);
    return *this;
  }

  // Returns the underlying matrix.
  const SkMatrix44& matrix() const { return matrix_; }
  SkMatrix44& matrix() { return matrix_; }

  std::string ToString() const;

 private:
  void TransformPointInternal(const SkMatrix44& xform, Point* point) const;

  void TransformPointInternal(const SkMatrix44& xform, Point3F* point) const;

  SkMatrix44 matrix_;

  // copy/assign are allowed.
};

// This is declared here for use in gtest-based unit tests but is defined in
// the gfx_test_support target. Depend on that to use this in your unit test.
// This should not be used in production code - call ToString() instead.
void PrintTo(const Transform& transform, ::std::ostream* os);

}  // namespace gfx

#endif  // UI_GFX_TRANSFORM_H_
