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

#include <limits.h>
#include "../../include/fxcrt/fx_ext.h"
void FX_RECT::Normalize()
{
    if (left > right) {
        int temp = left;
        left = right;
        right = temp;
    }
    if (top > bottom) {
        int temp = top;
        top = bottom;
        bottom = temp;
    }
}
void FX_RECT::Intersect(const FX_RECT& src)
{
    FX_RECT src_n = src;
    src_n.Normalize();
    Normalize();
    left = left > src_n.left ? left : src_n.left;
    top = top > src_n.top ? top : src_n.top;
    right = right < src_n.right ? right : src_n.right;
    bottom = bottom < src_n.bottom ? bottom : src_n.bottom;
    if (left > right || top > bottom) {
        left = top = right = bottom = 0;
    }
}
void FX_RECT::Union(const FX_RECT& other_rect)
{
    Normalize();
    FX_RECT other = other_rect;
    other.Normalize();
    left = left < other.left ? left : other.left;
    right = right > other.right ? right : other.right;
    bottom = bottom > other.bottom ? bottom : other.bottom;
    top = top < other.top ? top : other.top;
}
FX_BOOL GetIntersection(FX_FLOAT low1, FX_FLOAT high1, FX_FLOAT low2, FX_FLOAT high2,
                        FX_FLOAT& interlow, FX_FLOAT& interhigh)
{
    if (low1 >= high2 || low2 >= high1) {
        return FALSE;
    }
    interlow = low1 > low2 ? low1 : low2;
    interhigh = high1 > high2 ? high2 : high1;
    return TRUE;
}
extern "C" int FXSYS_round(FX_FLOAT d)
{
    if (d < (FX_FLOAT)INT_MIN) {
        return INT_MIN;
    }
    if (d > (FX_FLOAT)INT_MAX) {
        return INT_MAX;
    }

    return (int)round(d);
}
CFX_FloatRect::CFX_FloatRect(const FX_RECT& rect)
{
    left = (FX_FLOAT)(rect.left);
    right = (FX_FLOAT)(rect.right);
    bottom = (FX_FLOAT)(rect.top);
    top = (FX_FLOAT)(rect.bottom);
}
void CFX_FloatRect::Normalize()
{
    FX_FLOAT temp;
    if (left > right) {
        temp = left;
        left = right;
        right = temp;
    }
    if (bottom > top) {
        temp = top;
        top = bottom;
        bottom = temp;
    }
}
void CFX_FloatRect::Intersect(const CFX_FloatRect& other_rect)
{
    Normalize();
    CFX_FloatRect other = other_rect;
    other.Normalize();
    left = left > other.left ? left : other.left;
    right = right < other.right ? right : other.right;
    bottom = bottom > other.bottom ? bottom : other.bottom;
    top = top < other.top ? top : other.top;
    if (left > right || bottom > top) {
        left = right = bottom = top = 0;
    }
}
void CFX_FloatRect::Union(const CFX_FloatRect& other_rect)
{
    Normalize();
    CFX_FloatRect other = other_rect;
    other.Normalize();
    left = left < other.left ? left : other.left;
    right = right > other.right ? right : other.right;
    bottom = bottom < other.bottom ? bottom : other.bottom;
    top = top > other.top ? top : other.top;
}
void CFX_FloatRect::Transform(const CFX_Matrix* pMatrix)
{
    pMatrix->TransformRect(left, right, top, bottom);
}
int CFX_FloatRect::Substract4(CFX_FloatRect& s, CFX_FloatRect* pRects)
{
    Normalize();
    s.Normalize();
    int nRects = 0;
    CFX_FloatRect rects[4];
    if (left < s.left) {
        rects[nRects].left = left;
        rects[nRects].right = s.left;
        rects[nRects].bottom = bottom;
        rects[nRects].top = top;
        nRects ++;
    }
    if (s.left < right && s.top < top) {
        rects[nRects].left = s.left;
        rects[nRects].right = right;
        rects[nRects].bottom = s.top;
        rects[nRects].top = top;
        nRects ++;
    }
    if (s.top > bottom && s.right < right) {
        rects[nRects].left = s.right;
        rects[nRects].right = right;
        rects[nRects].bottom = bottom;
        rects[nRects].top = s.top;
        nRects ++;
    }
    if (s.bottom > bottom) {
        rects[nRects].left = s.left;
        rects[nRects].right = s.right;
        rects[nRects].bottom = bottom;
        rects[nRects].top = s.bottom;
        nRects ++;
    }
    if (nRects == 0) {
        return 0;
    }
    for (int i = 0; i < nRects; i ++) {
        pRects[i] = rects[i];
        pRects[i].Intersect(*this);
    }
    return nRects;
}
FX_RECT CFX_FloatRect::GetOutterRect() const
{
    CFX_FloatRect rect1 = *this;
    FX_RECT rect;
    rect.left = (int)FXSYS_floor(rect1.left);
    rect.right = (int)FXSYS_ceil(rect1.right);
    rect.top = (int)FXSYS_floor(rect1.bottom);
    rect.bottom = (int)FXSYS_ceil(rect1.top);
    rect.Normalize();
    return rect;
}
FX_RECT CFX_FloatRect::GetInnerRect() const
{
    CFX_FloatRect rect1 = *this;
    FX_RECT rect;
    rect.left = (int)FXSYS_ceil(rect1.left);
    rect.right = (int)FXSYS_floor(rect1.right);
    rect.top = (int)FXSYS_ceil(rect1.bottom);
    rect.bottom = (int)FXSYS_floor(rect1.top);
    rect.Normalize();
    return rect;
}
static void _MatchFloatRange(FX_FLOAT f1, FX_FLOAT f2, int& i1, int& i2)
{
    int length = (int)FXSYS_ceil(f2 - f1);
    int i1_1 = (int)FXSYS_floor(f1);
    int i1_2 = (int)FXSYS_ceil(f1);
    FX_FLOAT error1 = f1 - i1_1 + (FX_FLOAT)FXSYS_fabs(f2 - i1_1 - length);
    FX_FLOAT error2 = i1_2 - f1 + (FX_FLOAT)FXSYS_fabs(f2 - i1_2 - length);
    i1 = (error1 > error2) ? i1_2 : i1_1;
    i2 = i1 + length;
}
FX_RECT CFX_FloatRect::GetClosestRect() const
{
    CFX_FloatRect rect1 = *this;
    FX_RECT rect;
    _MatchFloatRange(rect1.left, rect1.right, rect.left, rect.right);
    _MatchFloatRange(rect1.bottom, rect1.top, rect.top, rect.bottom);
    rect.Normalize();
    return rect;
}
FX_BOOL CFX_FloatRect::Contains(const CFX_FloatRect& other_rect) const
{
    CFX_FloatRect n1 = *this;
    n1.Normalize();
    CFX_FloatRect n2 = other_rect;
    n2.Normalize();
    if (n2.left >= n1.left && n2.right <= n1.right && n2.bottom >= n1.bottom && n2.top <= n1.top) {
        return TRUE;
    }
    return FALSE;
}
FX_BOOL CFX_FloatRect::Contains(FX_FLOAT x, FX_FLOAT y) const
{
    CFX_FloatRect n1 = *this;
    n1.Normalize();
    return x <= n1.right && x >= n1.left && y <= n1.top && y >= n1.bottom;
}
void CFX_FloatRect::UpdateRect(FX_FLOAT x, FX_FLOAT y)
{
    if (left > x) {
        left = x;
    }
    if (right < x) {
        right = x;
    }
    if (bottom > y) {
        bottom = y;
    }
    if (top < y) {
        top = y;
    }
}
CFX_FloatRect CFX_FloatRect::GetBBox(const CFX_FloatPoint* pPoints, int nPoints)
{
    if (nPoints == 0) {
        return CFX_FloatRect();
    }
    FX_FLOAT min_x = pPoints->x, max_x = pPoints->x, min_y = pPoints->y, max_y = pPoints->y;
    for (int i = 1; i < nPoints; i ++) {
        if (min_x > pPoints[i].x) {
            min_x = pPoints[i].x;
        }
        if (max_x < pPoints[i].x) {
            max_x = pPoints[i].x;
        }
        if (min_y > pPoints[i].y) {
            min_y = pPoints[i].y;
        }
        if (max_y < pPoints[i].y) {
            max_y = pPoints[i].y;
        }
    }
    return CFX_FloatRect(min_x, min_y, max_x, max_y);
}
void CFX_Matrix::Set(FX_FLOAT a, FX_FLOAT b, FX_FLOAT c, FX_FLOAT d, FX_FLOAT e, FX_FLOAT f)
{
    this->a = a;
    this->b = b;
    this->c = c;
    this->d = d;
    this->e = e;
    this->f = f;
}
void CFX_Matrix::Set(const FX_FLOAT n[6])
{
    this->a = n[0];
    this->b = n[1];
    this->c = n[2];
    this->d = n[3];
    this->e = n[4];
    this->f = n[5];
}
void CFX_Matrix::SetReverse(const CFX_Matrix &m)
{
    FX_FLOAT i = m.a * m.d - m.b * m.c;
    if (FXSYS_fabs(i) == 0) {
        return;
    }
    FX_FLOAT j = -i;
    a = m.d / i;
    b = m.b / j;
    c = m.c / j;
    d = m.a / i;
    e = (m.c * m.f - m.d * m.e) / i;
    f = (m.a * m.f - m.b * m.e) / j;
}
static void FXCRT_Matrix_Concat(CFX_Matrix &m, const CFX_Matrix &m1, const CFX_Matrix &m2)
{
    FX_FLOAT aa = m1.a * m2.a + m1.b * m2.c;
    FX_FLOAT bb = m1.a * m2.b + m1.b * m2.d;
    FX_FLOAT cc = m1.c * m2.a + m1.d * m2.c;
    FX_FLOAT dd = m1.c * m2.b + m1.d * m2.d;
    FX_FLOAT ee = m1.e * m2.a + m1.f * m2.c + m2.e;
    FX_FLOAT ff = m1.e * m2.b + m1.f * m2.d + m2.f;
    m.a = aa, m.b = bb, m.c = cc, m.d = dd, m.e = ee, m.f = ff;
}
void CFX_Matrix::Concat(FX_FLOAT a, FX_FLOAT b, FX_FLOAT c, FX_FLOAT d, FX_FLOAT e, FX_FLOAT f, FX_BOOL bPrepended)
{
    CFX_Matrix m;
    m.Set(a, b, c, d, e, f);
    Concat(m, bPrepended);
}
void CFX_Matrix::Concat(const CFX_Matrix &m, FX_BOOL bPrepended)
{
    if (bPrepended) {
        FXCRT_Matrix_Concat(*this, m, *this);
    } else {
        FXCRT_Matrix_Concat(*this, *this, m);
    }
}
void CFX_Matrix::ConcatInverse(const CFX_Matrix& src, FX_BOOL bPrepended)
{
    CFX_Matrix m;
    m.SetReverse(src);
    Concat(m, bPrepended);
}
FX_BOOL CFX_Matrix::IsInvertible() const
{
    return FXSYS_fabs(a * d - b * c) >= 0.0001f;
}
FX_BOOL CFX_Matrix::Is90Rotated() const
{
    return FXSYS_fabs(a * 1000) < FXSYS_fabs(b) && FXSYS_fabs(d * 1000) < FXSYS_fabs(c);
}
FX_BOOL CFX_Matrix::IsScaled() const
{
    return FXSYS_fabs(b * 1000) < FXSYS_fabs(a) && FXSYS_fabs(c * 1000) < FXSYS_fabs(d);
}
void CFX_Matrix::Translate(FX_FLOAT x, FX_FLOAT y, FX_BOOL bPrepended)
{
    if (bPrepended) {
        e += x * a + y * c;
        f += y * d + x * b;
    } else {
        e += x, f += y;
    }
}
void CFX_Matrix::Scale(FX_FLOAT sx, FX_FLOAT sy, FX_BOOL bPrepended)
{
    a *= sx, d *= sy;
    if (bPrepended) {
        b *= sx;
        c *= sy;
    } else {
        b *= sy;
        c *= sx;
        e *= sx;
        f *= sy;
    }
}
void CFX_Matrix::Rotate(FX_FLOAT fRadian, FX_BOOL bPrepended)
{
    FX_FLOAT cosValue = FXSYS_cos(fRadian);
    FX_FLOAT sinValue = FXSYS_sin(fRadian);
    CFX_Matrix m;
    m.Set(cosValue, sinValue, -sinValue, cosValue, 0, 0);
    if (bPrepended) {
        FXCRT_Matrix_Concat(*this, m, *this);
    } else {
        FXCRT_Matrix_Concat(*this, *this, m);
    }
}
void CFX_Matrix::RotateAt(FX_FLOAT fRadian, FX_FLOAT dx, FX_FLOAT dy, FX_BOOL bPrepended)
{
    Translate(dx, dy, bPrepended);
    Rotate(fRadian, bPrepended);
    Translate(-dx, -dy, bPrepended);
}
void CFX_Matrix::Shear(FX_FLOAT fAlphaRadian, FX_FLOAT fBetaRadian, FX_BOOL bPrepended)
{
    CFX_Matrix m;
    m.Set(1, FXSYS_tan(fAlphaRadian), FXSYS_tan(fBetaRadian), 1, 0, 0);
    if (bPrepended) {
        FXCRT_Matrix_Concat(*this, m, *this);
    } else {
        FXCRT_Matrix_Concat(*this, *this, m);
    }
}
void CFX_Matrix::MatchRect(const CFX_FloatRect& dest, const CFX_FloatRect& src)
{
    FX_FLOAT fDiff = src.left - src.right;
    a = FXSYS_fabs(fDiff) < 0.001f ? 1 : (dest.left - dest.right) / fDiff;
    fDiff = src.bottom - src.top;
    d = FXSYS_fabs(fDiff) < 0.001f ? 1 : (dest.bottom - dest.top) / fDiff;
    e = dest.left - src.left * a;
    f = dest.bottom - src.bottom * d;
    b = 0;
    c = 0;
}
FX_FLOAT CFX_Matrix::GetXUnit() const
{
    if (b == 0) {
        return (a > 0 ? a : -a);
    }
    if (a == 0) {
        return (b > 0 ? b : -b);
    }
    return FXSYS_sqrt(a * a + b * b);
}
FX_FLOAT CFX_Matrix::GetYUnit() const
{
    if (c == 0) {
        return (d > 0 ? d : -d);
    }
    if (d == 0) {
        return (c > 0 ? c : -c);
    }
    return FXSYS_sqrt(c * c + d * d);
}
void CFX_Matrix::GetUnitRect(CFX_RectF &rect) const
{
    rect.left = rect.top = 0;
    rect.width = rect.height = 1;
    TransformRect(rect);
}
CFX_FloatRect CFX_Matrix::GetUnitRect() const
{
    CFX_FloatRect rect(0, 0, 1, 1);
    rect.Transform((const CFX_Matrix*)this);
    return rect;
}
FX_FLOAT CFX_Matrix::GetUnitArea() const
{
    FX_FLOAT A = FXSYS_sqrt(a * a + b * b);
    FX_FLOAT B = FXSYS_sqrt(c * c + d * d);
    FX_FLOAT ac = a + c, bd = b + d;
    FX_FLOAT C = FXSYS_sqrt(ac * ac + bd * bd);
    FX_FLOAT P = (A + B + C ) / 2;
    return FXSYS_sqrt(P * (P - A) * (P - B) * (P - C)) * 2;
}
FX_FLOAT CFX_Matrix::TransformXDistance(FX_FLOAT dx) const
{
    FX_FLOAT fx = a * dx, fy = b * dx;
    return FXSYS_sqrt(fx * fx + fy * fy);
}
FX_INT32 CFX_Matrix::TransformXDistance(FX_INT32 dx) const
{
    FX_FLOAT fx = a * dx, fy = b * dx;
    return FXSYS_round(FXSYS_sqrt(fx * fx + fy * fy));
}
FX_FLOAT CFX_Matrix::TransformYDistance(FX_FLOAT dy) const
{
    FX_FLOAT fx = c * dy, fy = d * dy;
    return FXSYS_sqrt(fx * fx + fy * fy);
}
FX_INT32 CFX_Matrix::TransformYDistance(FX_INT32 dy) const
{
    FX_FLOAT fx = c * dy, fy = d * dy;
    return FXSYS_round(FXSYS_sqrt(fx * fx + fy * fy));
}
FX_FLOAT CFX_Matrix::TransformDistance(FX_FLOAT dx, FX_FLOAT dy) const
{
    FX_FLOAT fx = a * dx + c * dy, fy = b * dx + d * dy;
    return FXSYS_sqrt(fx * fx + fy * fy);
}
FX_INT32 CFX_Matrix::TransformDistance(FX_INT32 dx, FX_INT32 dy) const
{
    FX_FLOAT fx = a * dx + c * dy, fy = b * dx + d * dy;
    return FXSYS_round(FXSYS_sqrt(fx * fx + fy * fy));
}
FX_FLOAT CFX_Matrix::TransformDistance(FX_FLOAT distance) const
{
    return distance * (GetXUnit() + GetYUnit()) / 2;
}
void CFX_Matrix::TransformVector(CFX_VectorF &v) const
{
    FX_FLOAT fx = a * v.x + c * v.y;
    FX_FLOAT fy = b * v.x + d * v.y;
    v.x = fx, v.y = fy;
}
void CFX_Matrix::TransformVector(CFX_Vector &v) const
{
    FX_FLOAT fx = a * v.x + c * v.y;
    FX_FLOAT fy = b * v.x + d * v.y;
    v.x = FXSYS_round(fx);
    v.y = FXSYS_round(fy);
}
void CFX_Matrix::TransformPoints(CFX_Point *points, FX_INT32 iCount) const
{
    FXSYS_assert(iCount > 0);
    FX_FLOAT fx, fy;
    for (FX_INT32 i = 0; i < iCount; i ++) {
        fx = a * points->x + c * points->y + e;
        fy = b * points->x + d * points->y + f;
        points->x = FXSYS_round(fx);
        points->y = FXSYS_round(fy);
        points ++;
    }
}
void CFX_Matrix::TransformPoints(CFX_PointF *points, FX_INT32 iCount) const
{
    FXSYS_assert(iCount > 0);
    FX_FLOAT fx, fy;
    for (FX_INT32 i = 0; i < iCount; i ++) {
        fx = a * points->x + c * points->y + e;
        fy = b * points->x + d * points->y + f;
        points->x = fx, points->y = fy;
        points ++;
    }
}
void CFX_Matrix::TransformPoint(FX_FLOAT &x, FX_FLOAT &y) const
{
    FX_FLOAT fx = a * x + c * y + e;
    FX_FLOAT fy = b * x + d * y + f;
    x = fx, y = fy;
}
void CFX_Matrix::TransformPoint(FX_INT32 &x, FX_INT32 &y) const
{
    FX_FLOAT fx = a * x + c * y + e;
    FX_FLOAT fy = b * x + d * y + f;
    x = FXSYS_round(fx);
    y = FXSYS_round(fy);
}
void CFX_Matrix::TransformRect(CFX_RectF &rect) const
{
    FX_FLOAT right = rect.right(), bottom = rect.bottom();
    TransformRect(rect.left, right, bottom, rect.top);
    rect.width = right - rect.left;
    rect.height = bottom - rect.top;
}
void CFX_Matrix::TransformRect(CFX_Rect &rect) const
{
    FX_FLOAT left = (FX_FLOAT)rect.left;
    FX_FLOAT top = (FX_FLOAT)rect.bottom();
    FX_FLOAT right = (FX_FLOAT)rect.right();
    FX_FLOAT bottom = (FX_FLOAT)rect.top;
    TransformRect(left, right, top, bottom);
    rect.left = FXSYS_round(left);
    rect.top = FXSYS_round(bottom);
    rect.width = FXSYS_round(right - left);
    rect.height = FXSYS_round(top - bottom);
}
void CFX_Matrix::TransformRect(FX_FLOAT& left, FX_FLOAT& right, FX_FLOAT& top, FX_FLOAT& bottom) const
{
    FX_FLOAT x[4], y[4];
    x[0] = left;
    y[0] = top;
    x[1] = left;
    y[1] = bottom;
    x[2] = right;
    y[2] = top;
    x[3] = right;
    y[3] = bottom;
    int i;
    for (i = 0; i < 4; i ++) {
        Transform(x[i], y[i], x[i], y[i]);
    }
    right = left = x[0];
    top = bottom = y[0];
    for (i = 1; i < 4; i ++) {
        if (right < x[i]) {
            right = x[i];
        }
        if (left > x[i]) {
            left = x[i];
        }
        if (top < y[i]) {
            top = y[i];
        }
        if (bottom > y[i]) {
            bottom = y[i];
        }
    }
}
