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

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#ifndef CORE_FXCRT_INCLUDE_FX_COORDINATES_H_
#define CORE_FXCRT_INCLUDE_FX_COORDINATES_H_

#include "core/fxcrt/include/fx_basic.h"

class CFX_Matrix;

template <class BaseType>
class CFX_PSTemplate {
 public:
  CFX_PSTemplate() : x(0), y(0) {}
  CFX_PSTemplate(BaseType new_x, BaseType new_y) : x(new_x), y(new_y) {}
  CFX_PSTemplate(const CFX_PSTemplate& other) : x(other.x), y(other.y) {}
  void clear() {
    x = 0;
    y = 0;
  }
  CFX_PSTemplate operator=(const CFX_PSTemplate& other) {
    if (this != &other) {
      x = other.x;
      y = other.y;
    }
    return *this;
  }
  bool operator==(const CFX_PSTemplate& other) const {
    return x == other.x && y == other.y;
  }
  bool operator!=(const CFX_PSTemplate& other) const {
    return !(*this == other);
  }
  CFX_PSTemplate& operator+=(const CFX_PSTemplate<BaseType>& obj) {
    x += obj.x;
    y += obj.y;
    return *this;
  }
  CFX_PSTemplate& operator-=(const CFX_PSTemplate<BaseType>& obj) {
    x -= obj.x;
    y -= obj.y;
    return *this;
  }
  CFX_PSTemplate& operator*=(BaseType factor) {
    x *= factor;
    y *= factor;
    return *this;
  }
  CFX_PSTemplate& operator/=(BaseType divisor) {
    x /= divisor;
    y /= divisor;
    return *this;
  }
  CFX_PSTemplate operator+(const CFX_PSTemplate& other) {
    return CFX_PSTemplate(x + other.x, y + other.y);
  }
  CFX_PSTemplate operator-(const CFX_PSTemplate& other) {
    return CFX_PSTemplate(x - other.x, y - other.y);
  }
  CFX_PSTemplate operator*(BaseType factor) {
    return CFX_PSTemplate(x * factor, y * factor);
  }
  CFX_PSTemplate operator/(BaseType divisor) {
    return CFX_PSTemplate(x / divisor, y / divisor);
  }

  BaseType x;
  BaseType y;
};
typedef CFX_PSTemplate<int32_t> CFX_Point;
typedef CFX_PSTemplate<FX_FLOAT> CFX_PointF;
typedef CFX_PSTemplate<int32_t> CFX_Size;
typedef CFX_PSTemplate<FX_FLOAT> CFX_SizeF;
typedef CFX_ArrayTemplate<CFX_Point> CFX_Points;
typedef CFX_ArrayTemplate<CFX_PointF> CFX_PointsF;

template <class BaseType>
class CFX_VTemplate : public CFX_PSTemplate<BaseType> {
 public:
  using CFX_PSTemplate<BaseType>::x;
  using CFX_PSTemplate<BaseType>::y;

  CFX_VTemplate() : CFX_PSTemplate<BaseType>() {}
  CFX_VTemplate(BaseType new_x, BaseType new_y)
      : CFX_PSTemplate<BaseType>(new_x, new_y) {}

  CFX_VTemplate(const CFX_VTemplate& other) : CFX_PSTemplate<BaseType>(other) {}

  CFX_VTemplate(const CFX_PSTemplate<BaseType>& point1,
                const CFX_PSTemplate<BaseType>& point2)
      : CFX_PSTemplate<BaseType>(point2.x - point1.x, point2.y - point1.y) {}

  FX_FLOAT Length() const { return FXSYS_sqrt(x * x + y * y); }
  void Normalize() {
    FX_FLOAT fLen = Length();
    if (fLen < 0.0001f)
      return;

    x /= fLen;
    y /= fLen;
  }
  void Translate(BaseType dx, BaseType dy) {
    x += dx;
    y += dy;
  }
  void Scale(BaseType sx, BaseType sy) {
    x *= sx;
    y *= sy;
  }
  void Rotate(FX_FLOAT fRadian) {
    FX_FLOAT cosValue = FXSYS_cos(fRadian);
    FX_FLOAT sinValue = FXSYS_sin(fRadian);
    x = x * cosValue - y * sinValue;
    y = x * sinValue + y * cosValue;
  }
};
typedef CFX_VTemplate<int32_t> CFX_Vector;
typedef CFX_VTemplate<FX_FLOAT> CFX_VectorF;

// Rectangles.
// TODO(tsepez): Consolidate all these different rectangle classes.

// LTRB rectangles (y-axis runs downwards).
struct FX_SMALL_RECT {
  FX_SMALL_RECT() : FX_SMALL_RECT(kInvalid, kInvalid, kInvalid, kInvalid) {}

  FX_SMALL_RECT(int16_t l, int16_t t, int16_t r, int16_t b)
      : left(l), top(t), right(r), bottom(b) {}

  static const int16_t kInvalid = -1;

  int16_t left;
  int16_t top;
  int16_t right;
  int16_t bottom;
};

struct FX_RECT {
  FX_RECT() : left(0), top(0), right(0), bottom(0) {}

  FX_RECT(int l, int t, int r, int b) : left(l), top(t), right(r), bottom(b) {}

  explicit FX_RECT(const FX_SMALL_RECT& other)
      : FX_RECT(other.left, other.top, other.right, other.bottom) {}

  int Width() const { return right - left; }
  int Height() const { return bottom - top; }
  bool IsEmpty() const { return right <= left || bottom <= top; }

  void Normalize();

  void Intersect(const FX_RECT& src);
  void Intersect(int l, int t, int r, int b) { Intersect(FX_RECT(l, t, r, b)); }

  void Union(const FX_RECT& other_rect);
  void Union(int l, int t, int r, int b) { Union(FX_RECT(l, t, r, b)); }

  void Offset(int dx, int dy) {
    left += dx;
    right += dx;
    top += dy;
    bottom += dy;
  }

  bool operator==(const FX_RECT& src) const {
    return left == src.left && right == src.right && top == src.top &&
           bottom == src.bottom;
  }

  FX_BOOL Contains(const FX_RECT& other_rect) const {
    return other_rect.left >= left && other_rect.right <= right &&
           other_rect.top >= top && other_rect.bottom <= bottom;
  }

  FX_BOOL Contains(int x, int y) const {
    return x >= left && x < right && y >= top && y < bottom;
  }

  FX_SMALL_RECT ToSmallRect() const {
    return FX_SMALL_RECT(
        static_cast<uint16_t>(left), static_cast<uint16_t>(top),
        static_cast<uint16_t>(right), static_cast<uint16_t>(bottom));
  }

  int32_t left;
  int32_t top;
  int32_t right;
  int32_t bottom;
};

// LBRT rectangles (y-axis runs upwards).
class CFX_FloatPoint {
 public:
  CFX_FloatPoint(FX_FLOAT xx, FX_FLOAT yy) : x(xx), y(yy) {}

  FX_FLOAT x;
  FX_FLOAT y;
};

class CFX_FloatRect {
 public:
  CFX_FloatRect() : CFX_FloatRect(0.0f, 0.0f, 0.0f, 0.0f) {}
  CFX_FloatRect(FX_FLOAT l, FX_FLOAT b, FX_FLOAT r, FX_FLOAT t)
      : left(l), bottom(b), right(r), top(t) {}

  explicit CFX_FloatRect(const FX_FLOAT* pArray)
      : CFX_FloatRect(pArray[0], pArray[1], pArray[2], pArray[3]) {}

  explicit CFX_FloatRect(const FX_RECT& rect);

  void Normalize();

  void Reset() {
    left = 0.0f;
    right = 0.0f;
    bottom = 0.0f;
    top = 0.0f;
  }

  bool IsEmpty() const { return left >= right || bottom >= top; }
  bool Contains(const CFX_FloatRect& other_rect) const;
  bool Contains(FX_FLOAT x, FX_FLOAT y) const;

  void Transform(const CFX_Matrix* pMatrix);
  void Intersect(const CFX_FloatRect& other_rect);
  void Union(const CFX_FloatRect& other_rect);

  FX_RECT GetInnerRect() const;
  FX_RECT GetOutterRect() const;
  FX_RECT GetClosestRect() const;

  int Substract4(CFX_FloatRect& substract_rect, CFX_FloatRect* pRects);

  void InitRect(FX_FLOAT x, FX_FLOAT y) {
    left = x;
    right = x;
    bottom = y;
    top = y;
  }
  void UpdateRect(FX_FLOAT x, FX_FLOAT y);

  FX_FLOAT Width() const { return right - left; }
  FX_FLOAT Height() const { return top - bottom; }

  void Inflate(FX_FLOAT x, FX_FLOAT y) {
    Normalize();
    left -= x;
    right += x;
    bottom -= y;
    top += y;
  }

  void Inflate(FX_FLOAT other_left,
               FX_FLOAT other_bottom,
               FX_FLOAT other_right,
               FX_FLOAT other_top) {
    Normalize();
    left -= other_left;
    bottom -= other_bottom;
    right += other_right;
    top += other_top;
  }

  void Inflate(const CFX_FloatRect& rt) {
    Inflate(rt.left, rt.bottom, rt.right, rt.top);
  }

  void Deflate(FX_FLOAT x, FX_FLOAT y) {
    Normalize();
    left += x;
    right -= x;
    bottom += y;
    top -= y;
  }

  void Deflate(FX_FLOAT other_left,
               FX_FLOAT other_bottom,
               FX_FLOAT other_right,
               FX_FLOAT other_top) {
    Normalize();
    left += other_left;
    bottom += other_bottom;
    right -= other_right;
    top -= other_top;
  }

  void Deflate(const CFX_FloatRect& rt) {
    Deflate(rt.left, rt.bottom, rt.right, rt.top);
  }

  void Translate(FX_FLOAT e, FX_FLOAT f) {
    left += e;
    right += e;
    top += f;
    bottom += f;
  }

  static CFX_FloatRect GetBBox(const CFX_PointF* pPoints, int nPoints);

  FX_RECT ToFxRect() const {
    return FX_RECT(static_cast<int32_t>(left), static_cast<int32_t>(top),
                   static_cast<int32_t>(right), static_cast<int32_t>(bottom));
  }

  FX_FLOAT left;
  FX_FLOAT bottom;
  FX_FLOAT right;
  FX_FLOAT top;
};

// LTWH rectangles (y-axis runs downwards).
template <class baseType>
class CFX_RTemplate {
 public:
  typedef CFX_PSTemplate<baseType> FXT_POINT;
  typedef CFX_PSTemplate<baseType> FXT_SIZE;
  typedef CFX_VTemplate<baseType> FXT_VECTOR;
  typedef CFX_RTemplate<baseType> FXT_RECT;
  void Set(baseType left, baseType top, baseType width, baseType height) {
    FXT_RECT::left = left, FXT_RECT::top = top, FXT_RECT::width = width,
    FXT_RECT::height = height;
  }
  void Set(baseType left, baseType top, const FXT_SIZE& size) {
    FXT_RECT::left = left, FXT_RECT::top = top, FXT_RECT::Size(size);
  }
  void Set(const FXT_POINT& p, baseType width, baseType height) {
    TopLeft(p), FXT_RECT::width = width, FXT_RECT::height = height;
  }
  void Set(const FXT_POINT& p1, const FXT_POINT& p2) {
    TopLeft(p1), FXT_RECT::width = p2.x - p1.x, FXT_RECT::height = p2.y - p1.y,
                 FXT_RECT::Normalize();
  }
  void Set(const FXT_POINT& p, const FXT_VECTOR& v) {
    TopLeft(p), FXT_RECT::width = v.x, FXT_RECT::height = v.y,
                FXT_RECT::Normalize();
  }
  void Reset() {
    FXT_RECT::left = FXT_RECT::top = FXT_RECT::width = FXT_RECT::height = 0;
  }
  FXT_RECT& operator+=(const FXT_POINT& p) {
    left += p.x, top += p.y;
    return *this;
  }
  FXT_RECT& operator-=(const FXT_POINT& p) {
    left -= p.x, top -= p.y;
    return *this;
  }
  baseType right() const { return left + width; }
  baseType bottom() const { return top + height; }
  void Normalize() {
    if (width < 0) {
      left += width;
      width = -width;
    }
    if (height < 0) {
      top += height;
      height = -height;
    }
  }
  void Offset(baseType dx, baseType dy) {
    left += dx;
    top += dy;
  }
  void Inflate(baseType x, baseType y) {
    left -= x;
    width += x * 2;
    top -= y;
    height += y * 2;
  }
  void Inflate(const FXT_POINT& p) { Inflate(p.x, p.y); }
  void Inflate(baseType left, baseType top, baseType right, baseType bottom) {
    FXT_RECT::left -= left;
    FXT_RECT::top -= top;
    FXT_RECT::width += left + right;
    FXT_RECT::height += top + bottom;
  }
  void Inflate(const FXT_RECT& rt) {
    Inflate(rt.left, rt.top, rt.left + rt.width, rt.top + rt.height);
  }
  void Deflate(baseType x, baseType y) {
    left += x;
    width -= x * 2;
    top += y;
    height -= y * 2;
  }
  void Deflate(const FXT_POINT& p) { Deflate(p.x, p.y); }
  void Deflate(baseType left, baseType top, baseType right, baseType bottom) {
    FXT_RECT::left += left;
    FXT_RECT::top += top;
    FXT_RECT::width -= left + right;
    FXT_RECT::height -= top + bottom;
  }
  void Deflate(const FXT_RECT& rt) {
    Deflate(rt.left, rt.top, rt.top + rt.width, rt.top + rt.height);
  }
  FX_BOOL IsEmpty() const { return width <= 0 || height <= 0; }
  FX_BOOL IsEmpty(FX_FLOAT fEpsilon) const {
    return width <= fEpsilon || height <= fEpsilon;
  }
  void Empty() { width = height = 0; }
  FX_BOOL Contains(baseType x, baseType y) const {
    return x >= left && x < left + width && y >= top && y < top + height;
  }
  FX_BOOL Contains(const FXT_POINT& p) const { return Contains(p.x, p.y); }
  FX_BOOL Contains(const FXT_RECT& rt) const {
    return rt.left >= left && rt.right() <= right() && rt.top >= top &&
           rt.bottom() <= bottom();
  }
  baseType Width() const { return width; }
  baseType Height() const { return height; }
  FXT_SIZE Size() const {
    FXT_SIZE size;
    size.Set(width, height);
    return size;
  }
  void Size(FXT_SIZE s) { width = s.x, height = s.y; }
  FXT_POINT TopLeft() const {
    FXT_POINT p;
    p.x = left;
    p.y = top;
    return p;
  }
  FXT_POINT TopRight() const {
    FXT_POINT p;
    p.x = left + width;
    p.y = top;
    return p;
  }
  FXT_POINT BottomLeft() const {
    FXT_POINT p;
    p.x = left;
    p.y = top + height;
    return p;
  }
  FXT_POINT BottomRight() const {
    FXT_POINT p;
    p.x = left + width;
    p.y = top + height;
    return p;
  }
  void TopLeft(FXT_POINT tl) {
    left = tl.x;
    top = tl.y;
  }
  void TopRight(FXT_POINT tr) {
    width = tr.x - left;
    top = tr.y;
  }
  void BottomLeft(FXT_POINT bl) {
    left = bl.x;
    height = bl.y - top;
  }
  void BottomRight(FXT_POINT br) {
    width = br.x - left;
    height = br.y - top;
  }
  FXT_POINT Center() const {
    FXT_POINT p;
    p.x = left + width / 2;
    p.y = top + height / 2;
    return p;
  }
  void Union(baseType x, baseType y) {
    baseType r = right(), b = bottom();
    if (left > x) {
      left = x;
    }
    if (r < x) {
      r = x;
    }
    if (top > y) {
      top = y;
    }
    if (b < y) {
      b = y;
    }
    width = r - left;
    height = b - top;
  }
  void Union(const FXT_POINT& p) { Union(p.x, p.y); }
  void Union(const FXT_RECT& rt) {
    baseType r = right(), b = bottom();
    if (left > rt.left) {
      left = rt.left;
    }
    if (r < rt.right()) {
      r = rt.right();
    }
    if (top > rt.top) {
      top = rt.top;
    }
    if (b < rt.bottom()) {
      b = rt.bottom();
    }
    width = r - left;
    height = b - top;
  }
  void Intersect(const FXT_RECT& rt) {
    baseType r = right(), b = bottom();
    if (left < rt.left) {
      left = rt.left;
    }
    if (r > rt.right()) {
      r = rt.right();
    }
    if (top < rt.top) {
      top = rt.top;
    }
    if (b > rt.bottom()) {
      b = rt.bottom();
    }
    width = r - left;
    height = b - top;
  }
  FX_BOOL IntersectWith(const FXT_RECT& rt) const {
    FXT_RECT rect = rt;
    rect.Intersect(*this);
    return !rect.IsEmpty();
  }
  FX_BOOL IntersectWith(const FXT_RECT& rt, FX_FLOAT fEpsilon) const {
    FXT_RECT rect = rt;
    rect.Intersect(*this);
    return !rect.IsEmpty(fEpsilon);
  }
  friend bool operator==(const FXT_RECT& rc1, const FXT_RECT& rc2) {
    return rc1.left == rc2.left && rc1.top == rc2.top &&
           rc1.width == rc2.width && rc1.height == rc2.height;
  }
  friend bool operator!=(const FXT_RECT& rc1, const FXT_RECT& rc2) {
    return !(rc1 == rc2);
  }
  baseType left, top;
  baseType width, height;
};
typedef CFX_RTemplate<int32_t> CFX_Rect;
typedef CFX_RTemplate<FX_FLOAT> CFX_RectF;
typedef CFX_ArrayTemplate<CFX_RectF> CFX_RectFArray;

class CFX_Matrix {
 public:
  CFX_Matrix() { SetIdentity(); }

  CFX_Matrix(FX_FLOAT a1,
             FX_FLOAT b1,
             FX_FLOAT c1,
             FX_FLOAT d1,
             FX_FLOAT e1,
             FX_FLOAT f1) {
    a = a1;
    b = b1;
    c = c1;
    d = d1;
    e = e1;
    f = f1;
  }

  void Set(FX_FLOAT a,
           FX_FLOAT b,
           FX_FLOAT c,
           FX_FLOAT d,
           FX_FLOAT e,
           FX_FLOAT f);
  void Set(const FX_FLOAT n[6]);

  void SetIdentity() {
    a = d = 1;
    b = c = e = f = 0;
  }

  void SetReverse(const CFX_Matrix& m);

  void Concat(FX_FLOAT a,
              FX_FLOAT b,
              FX_FLOAT c,
              FX_FLOAT d,
              FX_FLOAT e,
              FX_FLOAT f,
              FX_BOOL bPrepended = FALSE);
  void Concat(const CFX_Matrix& m, FX_BOOL bPrepended = FALSE);
  void ConcatInverse(const CFX_Matrix& m, FX_BOOL bPrepended = FALSE);

  void Copy(const CFX_Matrix& m) { *this = m; }

  FX_BOOL IsIdentity() const {
    return a == 1 && b == 0 && c == 0 && d == 1 && e == 0 && f == 0;
  }
  FX_BOOL IsInvertible() const;

  FX_BOOL Is90Rotated() const;

  FX_BOOL IsScaled() const;

  void Translate(FX_FLOAT x, FX_FLOAT y, FX_BOOL bPrepended = FALSE);

  void TranslateI(int32_t x, int32_t y, FX_BOOL bPrepended = FALSE) {
    Translate((FX_FLOAT)x, (FX_FLOAT)y, bPrepended);
  }

  void Scale(FX_FLOAT sx, FX_FLOAT sy, FX_BOOL bPrepended = FALSE);

  void Rotate(FX_FLOAT fRadian, FX_BOOL bPrepended = FALSE);

  void RotateAt(FX_FLOAT fRadian,
                FX_FLOAT x,
                FX_FLOAT y,
                FX_BOOL bPrepended = FALSE);

  void Shear(FX_FLOAT fAlphaRadian,
             FX_FLOAT fBetaRadian,
             FX_BOOL bPrepended = FALSE);

  void MatchRect(const CFX_FloatRect& dest, const CFX_FloatRect& src);

  FX_FLOAT GetXUnit() const;

  FX_FLOAT GetYUnit() const;
  void GetUnitRect(CFX_RectF& rect) const;

  CFX_FloatRect GetUnitRect() const;

  FX_FLOAT GetUnitArea() const;
  FX_FLOAT TransformXDistance(FX_FLOAT dx) const;
  int32_t TransformXDistance(int32_t dx) const;
  FX_FLOAT TransformYDistance(FX_FLOAT dy) const;
  int32_t TransformYDistance(int32_t dy) const;
  FX_FLOAT TransformDistance(FX_FLOAT dx, FX_FLOAT dy) const;
  int32_t TransformDistance(int32_t dx, int32_t dy) const;
  FX_FLOAT TransformDistance(FX_FLOAT distance) const;

  void TransformPoint(FX_FLOAT& x, FX_FLOAT& y) const;
  void TransformPoint(int32_t& x, int32_t& y) const;

  void Transform(FX_FLOAT& x, FX_FLOAT& y) const { TransformPoint(x, y); }
  void Transform(FX_FLOAT x, FX_FLOAT y, FX_FLOAT& x1, FX_FLOAT& y1) const {
    x1 = x, y1 = y;
    TransformPoint(x1, y1);
  }

  void TransformVector(CFX_VectorF& v) const;
  void TransformVector(CFX_Vector& v) const;
  void TransformRect(CFX_RectF& rect) const;
  void TransformRect(CFX_Rect& rect) const;

  void TransformRect(FX_FLOAT& left,
                     FX_FLOAT& right,
                     FX_FLOAT& top,
                     FX_FLOAT& bottom) const;
  void TransformRect(CFX_FloatRect& rect) const {
    TransformRect(rect.left, rect.right, rect.top, rect.bottom);
  }

  FX_FLOAT GetA() const { return a; }
  FX_FLOAT GetB() const { return b; }
  FX_FLOAT GetC() const { return c; }
  FX_FLOAT GetD() const { return d; }
  FX_FLOAT GetE() const { return e; }
  FX_FLOAT GetF() const { return f; }

 public:
  FX_FLOAT a;
  FX_FLOAT b;
  FX_FLOAT c;
  FX_FLOAT d;
  FX_FLOAT e;
  FX_FLOAT f;
};

#endif  // CORE_FXCRT_INCLUDE_FX_COORDINATES_H_
