#ifndef _RIVE_MAT2D_HPP_
#define _RIVE_MAT2D_HPP_

#include "rive/math/aabb.hpp"
#include "rive/math/math_types.hpp"
#include "rive/math/vec2d.hpp"
#include "rive/span.hpp"
#include <array>
#include <cstddef>

namespace rive
{
class TransformComponents;
class Mat2D
{
public:
  constexpr Mat2D() : m_buffer{{1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f}} {}
  constexpr Mat2D(float x1, float y1, float x2, float y2, float tx, float ty)
      : m_buffer{{x1, y1, x2, y2, tx, ty}}
  {}

  inline const float* values() const { return &m_buffer[0]; }

  float& operator[](std::size_t idx) { return m_buffer[idx]; }
  const float& operator[](std::size_t idx) const { return m_buffer[idx]; }

  static Mat2D fromRotation(float rad);
  static Mat2D fromScale(float sx, float sy) { return {sx, 0, 0, sy, 0, 0}; }
  static Mat2D fromTranslate(float tx, float ty)
  {
    return {1, 0, 0, 1, tx, ty};
  }
  static Mat2D fromTranslation(Vec2D translation)
  {
    return {1, 0, 0, 1, translation.x, translation.y};
  }
  static Mat2D fromScaleAndTranslation(float sx, float sy, float tx, float ty)
  {
    return {sx, 0, 0, sy, tx, ty};
  }

  void scaleByValues(float sx, float sy);

  Mat2D& operator*=(const Mat2D& rhs)
  {
    *this = Mat2D::multiply(*this, rhs);
    return *this;
  }

  // Sets dst[i] = M * pts[i] for i in 0..n-1.
  void mapPoints(Vec2D dst[], const Vec2D pts[], size_t n) const;

  // Computes a bounding box that would tightly contain the given points if
  // they were to all be transformed by this matrix, ignoring NaN values.
  // Returns {0, 0, 0, 0} if the given points are empty or all NaN.
  AABB mapBoundingBox(const Vec2D pts[], size_t n) const;
  AABB mapBoundingBox(const AABB&) const;

  AABB mapBoundingBox(Span<const Vec2D> pts) const
  {
    return mapBoundingBox(pts.data(), pts.count());
  }

  // If returns true, result holds the inverse.
  // If returns false, result is unchnaged.
  bool invert(Mat2D* result) const;

  Mat2D invertOrIdentity() const
  {
    Mat2D inverse;          // initialized to identity
    (void)invert(&inverse); // inverse is unchanged if invert() fails
    return inverse;
  }

  TransformComponents decompose() const;
  static Mat2D compose(const TransformComponents&);
  float findMaxScale() const;
  bool hasUniformScale(float tolerance = math::EPSILON) const;
  Mat2D scale(Vec2D) const;
  Mat2D translate(Vec2D) const;

  static Mat2D multiply(const Mat2D& a, const Mat2D& b);

  float xx() const { return m_buffer[0]; }
  float xy() const { return m_buffer[1]; }
  float yx() const { return m_buffer[2]; }
  float yy() const { return m_buffer[3]; }
  float tx() const { return m_buffer[4]; }
  float ty() const { return m_buffer[5]; }

  Vec2D translation() const { return {m_buffer[4], m_buffer[5]}; }

  void xx(float value) { m_buffer[0] = value; }
  void xy(float value) { m_buffer[1] = value; }
  void yx(float value) { m_buffer[2] = value; }
  void yy(float value) { m_buffer[3] = value; }
  void tx(float value) { m_buffer[4] = value; }
  void ty(float value) { m_buffer[5] = value; }

  float determinant() const
  {
    return m_buffer[0] * m_buffer[3] - m_buffer[2] * m_buffer[1];
  }

private:
  std::array<float, 6> m_buffer;
};
static_assert(
    std::is_trivially_destructible<Mat2D>::value,
    "Mat2D must be trivially destructible");

inline Vec2D operator*(const Mat2D& m, Vec2D v)
{
  return {
      m[0] * v.x + m[2] * v.y + m[4],
      m[1] * v.x + m[3] * v.y + m[5],
  };
}

inline Mat2D operator*(const Mat2D& a, const Mat2D& b)
{
  return Mat2D::multiply(a, b);
}

inline bool operator==(const Mat2D& a, const Mat2D& b)
{
  return a[0] == b[0] && a[1] == b[1] && a[2] == b[2] && a[3] == b[3] &&
         a[4] == b[4] && a[5] == b[5];
}

inline bool operator!=(const Mat2D& a, const Mat2D& b) { return !(a == b); }

} // namespace rive
#endif
