// 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/utils/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 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_
