// Copyright 2016 The PDFium Authors
// 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 "core/fxge/cfx_path.h"

#include <math.h>

#include <algorithm>
#include <iterator>

#include "core/fxcrt/check_op.h"
#include "core/fxcrt/fx_system.h"

namespace {

bool IsRectPreTransform(const std::vector<CFX_Path::Point>& points) {
  if (points.size() != 5 && points.size() != 4)
    return false;

  if (points.size() == 5 && points[0].m_Point != points[4].m_Point)
    return false;

  if (points[0].m_Point == points[2].m_Point ||
      points[1].m_Point == points[3].m_Point) {
    return false;
  }

  for (size_t i = 1; i < points.size(); ++i) {
    if (points[i].m_Type != CFX_Path::Point::Type::kLine)
      return false;
  }
  return true;
}

bool XYBothNotEqual(const CFX_PointF& p1, const CFX_PointF& p2) {
  return p1.x != p2.x && p1.y != p2.y;
}

bool IsRectImpl(const std::vector<CFX_Path::Point>& points) {
  if (!IsRectPreTransform(points))
    return false;

  for (int i = 1; i < 4; i++) {
    if (XYBothNotEqual(points[i].m_Point, points[i - 1].m_Point))
      return false;
  }

  if (XYBothNotEqual(points[0].m_Point, points[3].m_Point))
    return false;

  return true;
}

CFX_FloatRect CreateRectFromPoints(const CFX_PointF& p1, const CFX_PointF& p2) {
  CFX_FloatRect rect(p1.x, p1.y, p2.x, p2.y);
  rect.Normalize();
  return rect;
}

bool PathPointsNeedNormalization(const std::vector<CFX_Path::Point>& points) {
  return points.size() > 5;
}

std::vector<CFX_Path::Point> GetNormalizedPoints(
    const std::vector<CFX_Path::Point>& points) {
  DCHECK(PathPointsNeedNormalization(points));

  if (points[0].m_Point != points.back().m_Point)
    return {};

  std::vector<CFX_Path::Point> normalized;
  normalized.reserve(6);
  normalized.push_back(points[0]);
  for (auto it = points.begin() + 1; it != points.end(); ++it) {
    // Exactly 5 points left. Stop normalizing and take what is left.
    if (normalized.size() + std::distance(it, points.end()) == 5) {
      std::copy(it, points.end(), std::back_inserter(normalized));
      break;
    }

    // If the line does not move, skip this point.
    const auto& point = *it;
    if (point.m_Type == CFX_Path::Point::Type::kLine && !point.m_CloseFigure &&
        !normalized.back().m_CloseFigure &&
        point.m_Point == normalized.back().m_Point) {
      continue;
    }

    normalized.push_back(point);

    // Too many points. Not considered as a rectangle.
    if (normalized.size() > 5)
      return {};
  }

  DCHECK_EQ(5u, normalized.size());
  return normalized;
}

void UpdateLineEndPoints(CFX_FloatRect* rect,
                         const CFX_PointF& start_pos,
                         const CFX_PointF& end_pos,
                         float hw) {
  if (start_pos.x == end_pos.x) {
    if (start_pos.y == end_pos.y) {
      rect->UpdateRect(end_pos + CFX_PointF(hw, hw));
      rect->UpdateRect(end_pos - CFX_PointF(hw, hw));
      return;
    }

    float point_y;
    if (end_pos.y < start_pos.y)
      point_y = end_pos.y - hw;
    else
      point_y = end_pos.y + hw;

    rect->UpdateRect(CFX_PointF(end_pos.x + hw, point_y));
    rect->UpdateRect(CFX_PointF(end_pos.x - hw, point_y));
    return;
  }

  if (start_pos.y == end_pos.y) {
    float point_x;
    if (end_pos.x < start_pos.x)
      point_x = end_pos.x - hw;
    else
      point_x = end_pos.x + hw;

    rect->UpdateRect(CFX_PointF(point_x, end_pos.y + hw));
    rect->UpdateRect(CFX_PointF(point_x, end_pos.y - hw));
    return;
  }

  CFX_PointF diff = end_pos - start_pos;
  float ll = FXSYS_sqrt2(diff.x, diff.y);
  float mx = end_pos.x + hw * diff.x / ll;
  float my = end_pos.y + hw * diff.y / ll;
  float dx1 = hw * diff.y / ll;
  float dy1 = hw * diff.x / ll;
  rect->UpdateRect(CFX_PointF(mx - dx1, my + dy1));
  rect->UpdateRect(CFX_PointF(mx + dx1, my - dy1));
}

void UpdateLineJoinPoints(CFX_FloatRect* rect,
                          const CFX_PointF& start_pos,
                          const CFX_PointF& mid_pos,
                          const CFX_PointF& end_pos,
                          float half_width,
                          float miter_limit) {
  float start_k = 0;
  float start_c = 0;
  float end_k = 0;
  float end_c = 0;
  float start_len = 0;
  float start_dc = 0;
  float end_len = 0;
  float end_dc = 0;
  float one_twentieth = 1.0f / 20;

  bool bStartVert = fabs(start_pos.x - mid_pos.x) < one_twentieth;
  bool bEndVert = fabs(mid_pos.x - end_pos.x) < one_twentieth;
  if (bStartVert && bEndVert) {
    int start_dir = mid_pos.y > start_pos.y ? 1 : -1;
    float point_y = mid_pos.y + half_width * start_dir;
    rect->UpdateRect(CFX_PointF(mid_pos.x + half_width, point_y));
    rect->UpdateRect(CFX_PointF(mid_pos.x - half_width, point_y));
    return;
  }

  if (!bStartVert) {
    CFX_PointF start_to_mid = start_pos - mid_pos;
    start_k = (mid_pos.y - start_pos.y) / (mid_pos.x - start_pos.x);
    start_c = mid_pos.y - (start_k * mid_pos.x);
    start_len = FXSYS_sqrt2(start_to_mid.x, start_to_mid.y);
    start_dc = fabsf(half_width * start_len / start_to_mid.x);
  }
  if (!bEndVert) {
    CFX_PointF end_to_mid = end_pos - mid_pos;
    end_k = end_to_mid.y / end_to_mid.x;
    end_c = mid_pos.y - (end_k * mid_pos.x);
    end_len = FXSYS_sqrt2(end_to_mid.x, end_to_mid.y);
    end_dc = fabs(half_width * end_len / end_to_mid.x);
  }
  if (bStartVert) {
    CFX_PointF outside(start_pos.x, 0);
    if (end_pos.x < start_pos.x)
      outside.x += half_width;
    else
      outside.x -= half_width;

    if (start_pos.y < (end_k * start_pos.x) + end_c)
      outside.y = (end_k * outside.x) + end_c + end_dc;
    else
      outside.y = (end_k * outside.x) + end_c - end_dc;

    rect->UpdateRect(outside);
    return;
  }

  if (bEndVert) {
    CFX_PointF outside(end_pos.x, 0);
    if (start_pos.x < end_pos.x)
      outside.x += half_width;
    else
      outside.x -= half_width;

    if (end_pos.y < (start_k * end_pos.x) + start_c)
      outside.y = (start_k * outside.x) + start_c + start_dc;
    else
      outside.y = (start_k * outside.x) + start_c - start_dc;

    rect->UpdateRect(outside);
    return;
  }

  if (fabs(start_k - end_k) < one_twentieth) {
    int start_dir = mid_pos.x > start_pos.x ? 1 : -1;
    int end_dir = end_pos.x > mid_pos.x ? 1 : -1;
    if (start_dir == end_dir)
      UpdateLineEndPoints(rect, mid_pos, end_pos, half_width);
    else
      UpdateLineEndPoints(rect, start_pos, mid_pos, half_width);
    return;
  }

  float start_outside_c = start_c;
  if (end_pos.y < (start_k * end_pos.x) + start_c)
    start_outside_c += start_dc;
  else
    start_outside_c -= start_dc;

  float end_outside_c = end_c;
  if (start_pos.y < (end_k * start_pos.x) + end_c)
    end_outside_c += end_dc;
  else
    end_outside_c -= end_dc;

  float join_x = (end_outside_c - start_outside_c) / (start_k - end_k);
  float join_y = start_k * join_x + start_outside_c;
  rect->UpdateRect(CFX_PointF(join_x, join_y));
}

}  // namespace

CFX_Path::Point::Point() = default;

CFX_Path::Point::Point(const CFX_PointF& point, Type type, bool close)
    : m_Point(point), m_Type(type), m_CloseFigure(close) {}

CFX_Path::Point::Point(const Point& other) = default;

CFX_Path::Point::~Point() = default;

CFX_Path::CFX_Path() = default;

CFX_Path::CFX_Path(const CFX_Path& src) = default;

CFX_Path::CFX_Path(CFX_Path&& src) noexcept = default;

CFX_Path::~CFX_Path() = default;

void CFX_Path::Clear() {
  m_Points.clear();
}

void CFX_Path::ClosePath() {
  if (m_Points.empty())
    return;
  m_Points.back().m_CloseFigure = true;
}

void CFX_Path::Append(const CFX_Path& src, const CFX_Matrix* matrix) {
  if (src.m_Points.empty())
    return;

  size_t cur_size = m_Points.size();
  m_Points.insert(m_Points.end(), src.m_Points.begin(), src.m_Points.end());

  if (!matrix)
    return;

  for (size_t i = cur_size; i < m_Points.size(); i++)
    m_Points[i].m_Point = matrix->Transform(m_Points[i].m_Point);
}

void CFX_Path::AppendPoint(const CFX_PointF& point, Point::Type type) {
  m_Points.emplace_back(point, type, /*close=*/false);
}

void CFX_Path::AppendPointAndClose(const CFX_PointF& point, Point::Type type) {
  m_Points.emplace_back(point, type, /*close=*/true);
}

void CFX_Path::AppendLine(const CFX_PointF& pt1, const CFX_PointF& pt2) {
  if (m_Points.empty() || fabs(m_Points.back().m_Point.x - pt1.x) > 0.001 ||
      fabs(m_Points.back().m_Point.y - pt1.y) > 0.001) {
    AppendPoint(pt1, CFX_Path::Point::Type::kMove);
  }
  AppendPoint(pt2, CFX_Path::Point::Type::kLine);
}

void CFX_Path::AppendFloatRect(const CFX_FloatRect& rect) {
  return AppendRect(rect.left, rect.bottom, rect.right, rect.top);
}

void CFX_Path::AppendRect(float left, float bottom, float right, float top) {
  CFX_PointF left_bottom(left, bottom);
  CFX_PointF left_top(left, top);
  CFX_PointF right_top(right, top);
  CFX_PointF right_bottom(right, bottom);

  AppendLine(left_bottom, left_top);
  AppendLine(left_top, right_top);
  AppendLine(right_top, right_bottom);
  AppendLine(right_bottom, left_bottom);
  ClosePath();
}

CFX_FloatRect CFX_Path::GetBoundingBox() const {
  if (m_Points.empty())
    return CFX_FloatRect();

  CFX_FloatRect rect(m_Points[0].m_Point);
  for (size_t i = 1; i < m_Points.size(); ++i)
    rect.UpdateRect(m_Points[i].m_Point);
  return rect;
}

CFX_FloatRect CFX_Path::GetBoundingBoxForStrokePath(float line_width,
                                                    float miter_limit) const {
  CFX_FloatRect rect(100000.0f, 100000.0f, -100000.0f, -100000.0f);
  size_t iPoint = 0;
  float half_width = line_width;
  size_t iStartPoint = 0;
  size_t iEndPoint = 0;
  size_t iMiddlePoint = 0;
  bool bJoin;
  while (iPoint < m_Points.size()) {
    if (m_Points[iPoint].m_Type == CFX_Path::Point::Type::kMove) {
      if (iPoint + 1 == m_Points.size()) {
        if (m_Points[iPoint].m_CloseFigure) {
          // Update `rect` right away since this is the final point to be drawn.
          rect.UpdateRect(m_Points[iPoint].m_Point);
        }
        break;
      }

      iStartPoint = iPoint + 1;
      iEndPoint = iPoint;
      bJoin = false;
    } else {
      if (m_Points[iPoint].IsTypeAndOpen(CFX_Path::Point::Type::kBezier)) {
        // Callers are responsible for adding Beziers in sets of 3.
        CHECK_LT(iPoint + 2, m_Points.size());
        DCHECK_EQ(m_Points[iPoint + 1].m_Type, CFX_Path::Point::Type::kBezier);
        DCHECK_EQ(m_Points[iPoint + 2].m_Type, CFX_Path::Point::Type::kBezier);
        rect.UpdateRect(m_Points[iPoint].m_Point);
        rect.UpdateRect(m_Points[iPoint + 1].m_Point);
        iPoint += 2;
      }
      if (iPoint + 1 == m_Points.size() ||
          m_Points[iPoint + 1].m_Type == CFX_Path::Point::Type::kMove) {
        iStartPoint = iPoint - 1;
        iEndPoint = iPoint;
        bJoin = false;
      } else {
        iStartPoint = iPoint - 1;
        iMiddlePoint = iPoint;
        iEndPoint = iPoint + 1;
        bJoin = true;
      }
    }
    CHECK_LT(iStartPoint, m_Points.size());
    CHECK_LT(iEndPoint, m_Points.size());
    if (bJoin) {
      CHECK_LT(iMiddlePoint, m_Points.size());
      UpdateLineJoinPoints(
          &rect, m_Points[iStartPoint].m_Point, m_Points[iMiddlePoint].m_Point,
          m_Points[iEndPoint].m_Point, half_width, miter_limit);
    } else {
      UpdateLineEndPoints(&rect, m_Points[iStartPoint].m_Point,
                          m_Points[iEndPoint].m_Point, half_width);
    }
    ++iPoint;
  }
  return rect;
}

void CFX_Path::Transform(const CFX_Matrix& matrix) {
  for (auto& point : m_Points)
    point.m_Point = matrix.Transform(point.m_Point);
}

bool CFX_Path::IsRect() const {
  if (PathPointsNeedNormalization(m_Points))
    return IsRectImpl(GetNormalizedPoints(m_Points));
  return IsRectImpl(m_Points);
}

std::optional<CFX_FloatRect> CFX_Path::GetRect(const CFX_Matrix* matrix) const {
  bool do_normalize = PathPointsNeedNormalization(m_Points);
  std::vector<Point> normalized;
  if (do_normalize)
    normalized = GetNormalizedPoints(m_Points);
  const std::vector<Point>& path_points = do_normalize ? normalized : m_Points;

  if (!matrix) {
    if (!IsRectImpl(path_points))
      return std::nullopt;

    return CreateRectFromPoints(path_points[0].m_Point, path_points[2].m_Point);
  }

  if (!IsRectPreTransform(path_points))
    return std::nullopt;

  CFX_PointF points[5];
  for (size_t i = 0; i < path_points.size(); ++i) {
    points[i] = matrix->Transform(path_points[i].m_Point);

    if (i == 0)
      continue;
    if (XYBothNotEqual(points[i], points[i - 1]))
      return std::nullopt;
  }

  if (XYBothNotEqual(points[0], points[3]))
    return std::nullopt;

  return CreateRectFromPoints(points[0], points[2]);
}

CFX_RetainablePath::CFX_RetainablePath() = default;

// Note: can't default the copy constructor since Retainable<> has a deleted
// copy constructor (as it should). Instead, we want the default Retainable<>
// constructor to be invoked so as to create a copy with a ref-count of 1 as
// of the time it is created, then populate the remainder of the members from
// the |src| object.
CFX_RetainablePath::CFX_RetainablePath(const CFX_RetainablePath& src)
    : CFX_Path(src) {}

CFX_RetainablePath::~CFX_RetainablePath() = default;

RetainPtr<CFX_RetainablePath> CFX_RetainablePath::Clone() const {
  return pdfium::MakeRetain<CFX_RetainablePath>(*this);
}
