// 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_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) {}

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

  bool Valid() const {
    pdfium::base::CheckedNumeric<int> w = right;
    pdfium::base::CheckedNumeric<int> h = bottom;
    w -= left;
    h -= top;
    return w.IsValid() && h.IsValid();
  }

  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;
  }

  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;
  }

  bool Contains(int x, int y) const {
    return x >= left && x < right && y >= top && y < 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() : x(0.0f), y(0.0f) {}
  CFX_FloatPoint(FX_FLOAT xx, FX_FLOAT yy) : x(xx), y(yy) {}

  bool operator==(const CFX_FloatPoint& that) const {
    return x == that.x && y == that.y;
  }
  bool operator!=(const CFX_FloatPoint& that) const { return !(*this == that); }

  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 GetOuterRect() 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 dst_left,
           baseType dst_top,
           baseType dst_width,
           baseType dst_height) {
    left = dst_left;
    top = dst_top;
    width = dst_width;
    height = dst_height;
  }
  void Set(baseType dst_left, baseType dst_top, const FXT_SIZE& dst_size) {
    left = dst_left;
    top = dst_top;
    Size(dst_size);
  }
  void Set(const FXT_POINT& p, baseType dst_width, baseType dst_height) {
    TopLeft(p);
    width = dst_width;
    height = dst_height;
  }
  void Set(const FXT_POINT& p1, const FXT_POINT& p2) {
    TopLeft(p1);
    width = p2.x - p1.x;
    height = p2.y - p1.y;
    Normalize();
  }
  void Set(const FXT_POINT& p, const FXT_VECTOR& v) {
    TopLeft(p);
    width = v.x;
    height = v.y;
    Normalize();
  }
  void Reset() {
    left = 0;
    top = 0;
    width = 0;
    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 off_left,
               baseType off_top,
               baseType off_right,
               baseType off_bottom) {
    left -= off_left;
    top -= off_top;
    width += off_left + off_right;
    height += off_top + off_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 off_left,
               baseType off_top,
               baseType off_right,
               baseType off_bottom) {
    left += off_left;
    top += off_top;
    width -= off_left + off_right;
    height -= off_top + off_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; }
  bool Contains(baseType x, baseType y) const {
    return x >= left && x < left + width && y >= top && y < top + height;
  }
  bool Contains(const FXT_POINT& p) const { return Contains(p.x, p.y); }
  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();
    baseType 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();
    baseType 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();
    baseType 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);

  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_
