#include "rive/shapes/path.hpp"
#include "rive/shapes/points_path.hpp"
#include "rive/renderer.hpp"
#include "rive/shapes/cubic_vertex.hpp"
#include "rive/shapes/cubic_detached_vertex.hpp"
#include "rive/shapes/deformer.hpp"
#include "rive/shapes/path_vertex.hpp"
#include "rive/shapes/shape.hpp"
#include "rive/shapes/straight_vertex.hpp"
#include "rive/math/math_types.hpp"
#include <algorithm>
#include <cassert>

using namespace rive;

/// Compute an ideal control point distance to create a curve of the given
/// radius. Based on "natural rounding"
/// https://observablehq.com/@daformat/rounding-polygon-corners
float Path::computeIdealControlPointDistance(
    const Vec2D& toPrev,
    const Vec2D& toNext,
    float radius)
{
  // Get the angle between next and prev
  float angle = fabs(
      std::atan2(Vec2D::cross(toPrev, toNext), Vec2D::dot(toPrev, toNext)));

  return fmin(
      radius,
      (4.0f / 3.0f) *
          std::tan(math::PI / (2.0f * ((2.0f * math::PI) / angle))) * radius *
          (angle < math::PI / 2 ? 1 + std::cos(angle)
                                : 2.0f - std::sin(angle)));
}

static void rotatePoints(
    const Vec2D& nextPoint,
    const Vec2D& prevPoint,
    const Vec2D& point,
    Vec2D& outPoint,
    Vec2D& inPoint)
{
  // Calculate angle between original pos and new positions
  auto v1 = prevPoint - nextPoint;
  auto v2 = point - nextPoint;
  float angle = std::atan2(Vec2D::cross(v1, v2), Vec2D::dot(v1, v2));
  {
    // Rotate outPoint around prevPoint twice the angle
    float s = std::sin(angle * 2);
    float c = std::cos(angle * 2);
    outPoint.x -= prevPoint.x;
    outPoint.y -= prevPoint.y;
    float xNew = outPoint.x * c - outPoint.y * s;
    float yNew = outPoint.x * s + outPoint.y * c;
    outPoint.x = xNew + prevPoint.x;
    outPoint.y = yNew + prevPoint.y;
  }
  {
    // Rotate inPoint around nextPoint twice the angle
    float s = std::sin(-angle * 2);
    float c = std::cos(-angle * 2);
    inPoint.x -= nextPoint.x;
    inPoint.y -= nextPoint.y;
    float xNew = inPoint.x * c - inPoint.y * s;
    float yNew = inPoint.x * s + inPoint.y * c;
    inPoint.x = xNew + nextPoint.x;
    inPoint.y = yNew + nextPoint.y;
  }
}

RenderPathDeformer* Path::deformer() const
{
  if (m_Shape != nullptr)
  {
    return m_Shape->deformer();
  }
  return nullptr;
}

StatusCode Path::onAddedClean(CoreContext* context)
{
  StatusCode code = Super::onAddedClean(context);
  if (code != StatusCode::Ok)
  {
    return code;
  }

  // Find the shape.
  for (auto currentParent = parent(); currentParent != nullptr;
       currentParent = currentParent->parent())
  {
    if (currentParent->is<Shape>())
    {
      m_Shape = currentParent->as<Shape>();
      m_Shape->addPath(this);
      return StatusCode::Ok;
    }
  }

  return StatusCode::MissingObject;
}

void Path::buildDependencies() { Super::buildDependencies(); }

void Path::addVertex(PathVertex* vertex) { m_Vertices.push_back(vertex); }

void Path::popVertex() { m_Vertices.pop_back(); }

#ifdef WITH_RIVE_EDITOR
void Path::sortVerticesForEditor()
{
  auto byChildOrder = [](const PathVertex* a, const PathVertex* b) {
    return a->childOrder().compareTo(b->childOrder()) < 0;
  };
  if (std::is_sorted(m_Vertices.begin(), m_Vertices.end(), byChildOrder))
  {
    return;
  }
  std::sort(m_Vertices.begin(), m_Vertices.end(), byChildOrder);
  // A reorder after the path has built leaves m_rawPath on the old
  // vertex sequence.
  markPathDirty();
}
#endif

void Path::addFlags(PathFlags flags) { m_pathFlags |= flags; }
bool Path::isFlagged(PathFlags flags) const
{
  return (int)(m_pathFlags & flags) != 0x00;
}

bool Path::canDeferPathUpdate()
{
  if (m_Shape == nullptr)
  {
    return false;
  }
  // A path cannot defer its update if the shapes requires an update. Note the
  // nuance here where we track that the shape may be marked for follow path
  // (meaning all child paths need to follow path). This doesn't mean the
  // Shape is necessarily forced to update put the paths are, which is why we
  // explicitly also check the shape's path space.

  return m_Shape->canDeferPathUpdate() &&
         !m_Shape->isFlagged(PathFlags::followPath) &&
         !isFlagged(PathFlags::followPath | PathFlags::clipping);
}

const Mat2D& Path::pathTransform() const { return worldTransform(); }

AABB Path::localBounds() const { return m_rawPath.preciseBounds(); }

void Path::addRoundedRect(
    RawPath& rawPath,
    const AABB& bounds,
    float topLeft,
    float topRight,
    float bottomRight,
    float bottomLeft)
{
  struct Corner
  {
    Vec2D pos;
    Vec2D toPrev;
    Vec2D toNext;
    float radius;
  };
  // toPrev/toNext are the unit vectors buildPath derives from the adjacent
  // vertices; for a rectangle they are the axes.
  const Corner corners[4] = {
      {{bounds.left(), bounds.top()}, {0.0f, 1.0f}, {1.0f, 0.0f}, topLeft},
      {{bounds.right(), bounds.top()}, {-1.0f, 0.0f}, {0.0f, 1.0f}, topRight},
      {{bounds.right(), bounds.bottom()},
       {0.0f, -1.0f},
       {-1.0f, 0.0f},
       bottomRight},
      {{bounds.left(), bounds.bottom()},
       {1.0f, 0.0f},
       {0.0f, -1.0f},
       bottomLeft},
  };
  // buildPath clamps a corner to half of each adjacent edge; a rectangle's
  // adjacent edges are its full width and height, so every corner shares one
  // limit.
  const float maxRadius = std::min(bounds.width(), bounds.height()) * 0.5f;

  Vec2D start;
  for (int i = 0; i < 4; i++)
  {
    const Corner& corner = corners[i];
    // Branch on the authored radius, as buildPath does: a radius under the
    // clamp still rounds, it just rounds by very little.
    if (corner.radius != 0.0f)
    {
      const float radius = std::min(std::abs(corner.radius), maxRadius);
      const float idealDistance = computeIdealControlPointDistance(
          corner.toPrev,
          corner.toNext,
          radius);
      const Vec2D enter = Vec2D::scaleAndAdd(corner.pos, corner.toPrev, radius);
      if (i == 0)
      {
        start = enter;
        rawPath.move(enter);
      }
      else
      {
        rawPath.line(enter);
      }
      Vec2D outPoint = Vec2D::scaleAndAdd(
          corner.pos,
          corner.toPrev,
          radius - idealDistance);
      Vec2D inPoint = Vec2D::scaleAndAdd(
          corner.pos,
          corner.toNext,
          radius - idealDistance);
      const Vec2D exit = Vec2D::scaleAndAdd(corner.pos, corner.toNext, radius);
      if (corner.radius < 0.0f)
      {
        rotatePoints(exit, enter, corner.pos, outPoint, inPoint);
      }
      rawPath.cubic(outPoint, inPoint, exit);
    }
    else if (i == 0)
    {
      start = corner.pos;
      rawPath.move(corner.pos);
    }
    else
    {
      rawPath.line(corner.pos);
    }
  }
  rawPath.line(start);
  rawPath.close();
}

void Path::buildPath(RawPath& rawPath) const
{
  const bool isClosed = isPathClosed();
  const std::vector<PathVertex*>& vertices = m_Vertices;

  auto length = vertices.size();
  if (length < 2)
  {
    return;
  }
  auto firstPoint = vertices[0];

  // Init out to translation
  Vec2D out;
  bool prevIsCubic;

  Vec2D start, startIn;
  bool startIsCubic;

  if (firstPoint->is<CubicVertex>())
  {
    auto cubic = firstPoint->as<CubicVertex>();
    startIsCubic = prevIsCubic = true;
    startIn = cubic->renderIn();
    out = cubic->renderOut();
    start = cubic->renderTranslation();
    rawPath.move(start);
  }
  else
  {
    startIsCubic = prevIsCubic = false;
    auto& point = *firstPoint->as<StraightVertex>();
    auto radius = point.radius();
    if (radius != 0.0f)
    {
      auto prev = vertices[length - 1];

      Vec2D pos = point.renderTranslation();

      Vec2D toPrev = (prev->is<CubicVertex>()
                          ? prev->as<CubicVertex>()->renderOut()
                          : prev->renderTranslation()) -
                     pos;

      auto toPrevLength = toPrev.normalizeLength();

      auto next = vertices[1];

      Vec2D toNext = (next->is<CubicVertex>()
                          ? next->as<CubicVertex>()->renderIn()
                          : next->renderTranslation()) -
                     pos;
      auto toNextLength = toNext.normalizeLength();

      float renderRadius = std::min(
          toPrevLength / 2.0f,
          std::min(toNextLength / 2.0f, radius > 0 ? radius : -radius));
      float idealDistance = Path::computeIdealControlPointDistance(
          toPrev,
          toNext,
          renderRadius);

      startIn = start = Vec2D::scaleAndAdd(pos, toPrev, renderRadius);
      rawPath.move(startIn);

      Vec2D outPoint = Vec2D::scaleAndAdd(
          pos,
          toPrev,
          renderRadius - idealDistance);
      Vec2D inPoint = Vec2D::scaleAndAdd(
          pos,
          toNext,
          renderRadius - idealDistance);
      out = Vec2D::scaleAndAdd(pos, toNext, renderRadius);

      if (radius < 0)
      {
        rotatePoints(out, startIn, pos, outPoint, inPoint);
      }
      rawPath.cubic(outPoint, inPoint, out);
      prevIsCubic = false;
    }
    else
    {
      startIn = start = out = point.renderTranslation();
      rawPath.move(out);
    }
  }

  for (size_t i = 1; i < length; i++)
  {
    auto vertex = vertices[i];

    if (vertex->is<CubicVertex>())
    {
      auto cubic = vertex->as<CubicVertex>();
      auto inPoint = cubic->renderIn();
      auto translation = cubic->renderTranslation();

      rawPath.cubic(out, inPoint, translation);

      prevIsCubic = true;
      out = cubic->renderOut();
    }
    else
    {
      auto& point = *vertex->as<StraightVertex>();
      Vec2D pos = point.renderTranslation();
      auto radius = point.radius();
      if (radius != 0.0f)
      {
        auto prev = vertices[i - 1];
        Vec2D toPrev = (prev->is<CubicVertex>()
                            ? prev->as<CubicVertex>()->renderOut()
                            : prev->renderTranslation()) -
                       pos;
        auto toPrevLength = toPrev.normalizeLength();

        auto next = vertices[(i + 1) % length];

        Vec2D toNext = (next->is<CubicVertex>()
                            ? next->as<CubicVertex>()->renderIn()
                            : next->renderTranslation()) -
                       pos;
        auto toNextLength = toNext.normalizeLength();

        float renderRadius = std::min(
            toPrevLength / 2.0f,
            std::min(toNextLength / 2.0f, radius > 0 ? radius : -radius));
        float idealDistance = computeIdealControlPointDistance(
            toPrev,
            toNext,
            renderRadius);

        Vec2D translation = Vec2D::scaleAndAdd(pos, toPrev, renderRadius);
        if (prevIsCubic)
        {
          rawPath.cubic(out, translation, translation);
        }
        else
        {
          rawPath.line(translation);
        }

        Vec2D outPoint = Vec2D::scaleAndAdd(
            pos,
            toPrev,
            renderRadius - idealDistance);
        Vec2D inPoint = Vec2D::scaleAndAdd(
            pos,
            toNext,
            renderRadius - idealDistance);
        out = Vec2D::scaleAndAdd(pos, toNext, renderRadius);

        if (radius < 0)
        {
          rotatePoints(out, translation, pos, outPoint, inPoint);
        }
        rawPath.cubic(outPoint, inPoint, out);
        prevIsCubic = false;
      }
      else if (prevIsCubic)
      {
        rawPath.cubic(out, pos, pos);

        prevIsCubic = false;
        out = pos;
      }
      else
      {
        out = pos;
        rawPath.line(out);
      }
    }
  }
  if (isClosed)
  {
    if (prevIsCubic || startIsCubic)
    {
      rawPath.cubic(out, startIn, start);
    }
    else
    {
      rawPath.line(start);
    }
    rawPath.close();
  }

  RenderPathDeformer* pathDeformer = deformer();
  if (pathDeformer != nullptr)
  {
    Mat2D transform = pathTransform();
    Mat2D inverse = transform.invertOrIdentity();
    pathDeformer->deformLocalRenderPath(rawPath, transform, inverse);
  }
}

void Path::markPathDirty(bool sendToLayout)
{
  addDirt(ComponentDirt::Path);
  shapePathChanged();
}

// Dirt accumulates until update, so the shape only needs telling once per
// cycle.
void Path::shapePathChanged()
{
  if (m_shapeNotified || m_Shape == nullptr)
  {
    return;
  }
  m_shapeNotified = true;
  m_Shape->pathChanged();
}

void Path::onDirty(ComponentDirt value)
{
  if (hasDirt(value, ComponentDirt::WorldTransform | ComponentDirt::NSlicer))
  {
    shapePathChanged();
  }
  if (m_deferredPathDirt)
  {
    addDirt(ComponentDirt::Path);
  }
}

void Path::update(ComponentDirt value)
{
  m_shapeNotified = false;
  Super::update(value);

  bool pathChanged = hasDirt(value, ComponentDirt::Path);
  bool worldTransformChanged = hasDirt(value, ComponentDirt::WorldTransform);
  bool deformerChanged = hasDirt(value, ComponentDirt::NSlicer);

  if (pathChanged || deformerChanged ||
      (deformer() != nullptr && worldTransformChanged))
  {
    if (canDeferPathUpdate())
    {
      m_deferredPathDirt = true;
      return;
    }
    m_deferredPathDirt = false;
    // Build path doesn't explicitly rewind because we use it to concatenate
    // multiple built paths into a single command path (like the hit
    // tester).
    m_rawPath.rewind();
    buildPath(m_rawPath);
    m_geometryVersion++;
  }
  // if (hasDirt(value, ComponentDirt::WorldTransform) && m_Shape != nullptr)
  // {
  // 	// Make sure the path composer has an opportunity to rebuild the path
  // 	// (this is why the composer depends on the shape and all its paths,
  // 	// ascertaning it updates after both)
  // 	m_Shape->pathChanged();
  // }
}

void Path::isHoleChanged() { markPathDirty(); }

bool Path::collapse(bool value)
{
  bool changed = Super::collapse(value);
  if (changed && m_Shape != nullptr)
  {
    m_Shape->pathCollapseChanged();
  }

  return changed;
}

#ifdef ENABLE_QUERY_FLAT_VERTICES

class DisplayCubicVertex : public CubicVertex
{
public:
  DisplayCubicVertex(
      const Vec2D& in,
      const Vec2D& out,
      const Vec2D& translation)

  {
    m_InPoint = in;
    m_OutPoint = out;
    m_InValid = true;
    m_OutValid = true;
    x(translation.x);
    y(translation.y);
  }

  void computeIn() override {}
  void computeOut() override {}
};

FlattenedPath* Path::makeFlat(bool transformToParent)
{
  if (m_Vertices.empty())
  {
    return nullptr;
  }

  // Path transform always puts the path into world space.
  auto transform = pathTransform();

  if (transformToParent && parent()->is<TransformComponent>())
  {
    // Put the transform in parent space.
    auto world = parent()->as<TransformComponent>()->worldTransform();
    transform = world.invertOrIdentity() * transform;
  }

  FlattenedPath* flat = new FlattenedPath();
  auto length = m_Vertices.size();
  PathVertex* previous = isPathClosed() ? m_Vertices[length - 1] : nullptr;
  bool deletePrevious = false;
  for (size_t i = 0; i < length; i++)
  {
    auto vertex = m_Vertices[i];

    switch (vertex->coreType())
    {
      case StraightVertex::typeKey:
      {
        auto& point = *vertex->as<StraightVertex>();
        if (point.radius() > 0.0f &&
            (isPathClosed() || (i != 0 && i != length - 1)))
        {
          auto next = m_Vertices[(i + 1) % length];

          Vec2D prevPoint = previous->is<CubicVertex>()
                                ? previous->as<CubicVertex>()->renderOut()
                                : previous->renderTranslation();
          Vec2D nextPoint = next->is<CubicVertex>()
                                ? next->as<CubicVertex>()->renderIn()
                                : next->renderTranslation();

          Vec2D pos = point.renderTranslation();

          Vec2D toPrev = prevPoint - pos;
          auto toPrevLength = toPrev.normalizeLength();

          Vec2D toNext = nextPoint - pos;
          auto toNextLength = toNext.normalizeLength();

          auto renderRadius = std::min(
              toPrevLength / 2.0f,
              std::min(toNextLength / 2.0f, point.radius()));
          float idealDistance = computeIdealControlPointDistance(
              toPrev,
              toNext,
              renderRadius);
          Vec2D translation = Vec2D::scaleAndAdd(pos, toPrev, renderRadius);

          Vec2D out = Vec2D::scaleAndAdd(
              pos,
              toPrev,
              renderRadius - idealDistance);
          {
            auto v1 = new DisplayCubicVertex(translation, out, translation);
            flat->addVertex(v1, transform);
            delete v1;
          }

          translation = Vec2D::scaleAndAdd(pos, toNext, renderRadius);

          Vec2D in = Vec2D::scaleAndAdd(
              pos,
              toNext,
              renderRadius - idealDistance);
          auto v2 = new DisplayCubicVertex(in, translation, translation);

          flat->addVertex(v2, transform);
          if (deletePrevious)
          {
            delete previous;
          }
          previous = v2;
          deletePrevious = true;
          break;
        }
        RIVE_FALLTHROUGH;
      }
      default:
        if (deletePrevious)
        {
          delete previous;
        }
        previous = vertex;
        deletePrevious = false;
        flat->addVertex(previous, transform);
        break;
    }
  }
  if (deletePrevious)
  {
    delete previous;
  }
  return flat;
}

void FlattenedPath::addVertex(PathVertex* vertex, const Mat2D& transform)
{
  // To make this easy and relatively clean we just transform the vertices.
  // Requires the vertex to be passed in as a clone.
  if (vertex->is<CubicVertex>())
  {
    auto cubic = vertex->as<CubicVertex>();

    // Cubics need to be transformed so we create a Display version which
    // has set in/out values.
    const auto in = transform * cubic->renderIn();
    const auto out = transform * cubic->renderOut();
    const auto translation = transform * cubic->renderTranslation();

    auto displayCubic = new DisplayCubicVertex(in, out, translation);
    m_Vertices.push_back(displayCubic);
  }
  else
  {
    auto point = new PathVertex();
    Vec2D translation = transform * vertex->renderTranslation();
    point->x(translation.x);
    point->y(translation.y);
    m_Vertices.push_back(point);
  }
}

FlattenedPath::~FlattenedPath()
{
  for (auto vertex : m_Vertices)
  {
    delete vertex;
  }
}

#endif
