#include "rive/math/rectangles_to_contour.hpp"
#include <algorithm>
#include <unordered_map>

using namespace rive;
using RectEvent = RectanglesToContour::RectEvent;

class SpanOffset
{
public:
    size_t start;
    size_t size;

    Span<RectEvent> toSpan(Span<RectEvent> base)
    {
        return Span<RectEvent>(base.data() + start, size);
    }
};

// Returns SpanOffset relative to result so it can be called in succession
// (re-allocating) prior to accessing data.
static SpanOffset sortRectEvents(const std::vector<AABB>& rects,
                                 std::vector<RectEvent>& result,
                                 uint8_t axisA,
                                 uint8_t axisB)
{
    size_t index = 0;

    size_t resultStart = result.size();

    for (const AABB& rect : rects)
    {
        for (size_t pointIndex = 0; pointIndex < 2; pointIndex++)
        {
            Vec2D e = rect[pointIndex];
            RectEvent event;
            event.type = (uint8_t)pointIndex;
            event.index = index;
            event.y = axisB == 0 ? e[axisA] : e[axisB];
            event.x = axisB == 0 ? e[axisB] : e[axisA];
            event.size = pointIndex == 0 ? rect[1][axisB] - e[axisB]
                                         : e[axisB] - rect[0][axisB];
            result.push_back(event);
        }
        ++index;
    }

    std::sort(result.begin() + resultStart,
              result.end(),
              [&](const RectEvent& a, const RectEvent& b) {
                  return a.getValue(axisB) < b.getValue(axisB);
              });

    std::sort(result.begin() + resultStart,
              result.end(),
              [&](const RectEvent& a, const RectEvent& b) {
                  return a.getValue(axisA) < b.getValue(axisA);
              });

    return {resultStart, result.size() - resultStart};
}

bool RectanglesToContour::isRectIncluded(size_t rectIndex)
{
    return (m_rectInclusionBitset[rectIndex / 8] & (1 << (rectIndex % 8))) != 0;
}

void RectanglesToContour::markRectIncluded(size_t rectIndex, bool isIt)
{
    if (isIt)
    {
        m_rectInclusionBitset[rectIndex / 8] |= 1 << (rectIndex % 8);
    }
    else
    {
        m_rectInclusionBitset[rectIndex / 8] &= ~(1 << (rectIndex % 8));
    }
}

void RectanglesToContour::subdivideRectangles()
{
    m_subdividedRects.clear();
    m_uniquePoints.clear();
    m_rectEvents.clear();

    if (m_rects.empty())
    {
        return;
    }

    auto evOffset = sortRectEvents(m_rects, m_rectEvents, 0, 1);
    auto ehOffset = sortRectEvents(m_rects, m_rectEvents, 1, 0);

    auto ev = evOffset.toSpan(m_rectEvents);
    auto eh = ehOffset.toSpan(m_rectEvents);

    size_t inclusionByteSize = m_rects.size() / 8 + 1;
    m_rectInclusionBitset.resize(inclusionByteSize);
    memset(m_rectInclusionBitset.data(), 0, inclusionByteSize);
    markRectIncluded(ev[0].index, true);

    int opened = 0;
    float beginY = 0;
    std::vector<AABB> result;

    for (size_t i = 0; i < ev.size() - 1; ++i)
    {
        const auto& eventV = ev[i];
        markRectIncluded(ev[0].index, eventV.type == 0);
        const auto& next = ev[i + 1];
        float beginX = eventV.x;
        float endX = next.x;
        float deltaX = next.x - eventV.x;
        if (deltaX == 0)
        {
            continue;
        }

        for (size_t j = 0; j < eh.size(); ++j)
        {
            const auto& eventH = eh[j];
            if (isRectIncluded(eventH.index))
            {
                if (eventH.type == 0)
                {
                    ++opened;
                    if (opened == 1)
                    {
                        beginY = eventH.y;
                    }
                }
                else
                {
                    --opened;
                    size_t n = 1;
                    while (j + n < eh.size() &&
                           !isRectIncluded(eh[j + n].index))
                    {
                        ++n;
                    }
                    const auto* next =
                        (j + n < eh.size()) ? &eh[j + n] : nullptr;
                    if (!next || (opened == 0 && next->y != eventH.y))
                    {
                        float endY = eventH.y;
                        m_subdividedRects.push_back(
                            AABB(beginX, beginY, endX, endY));
                    }
                }
            }
        }
    }
}

void RectanglesToContour::reset() { m_rects.clear(); }

void RectanglesToContour::addRect(const AABB& rect)
{
    if (!m_rects.empty())
    {
        auto& last = m_rects.back();
        if (last.minY == rect.minY && last.maxY == rect.maxY &&
            last.maxX == rect.minX)
        {
            m_rects.pop_back();
            m_rects.emplace_back(
                AABB(last.minX, last.minY, rect.maxX, last.maxY));
            return;
        }
    }
    m_rects.push_back(rect);
}

template <typename Compare>
std::vector<Vec2D> sortPoints(const std::unordered_set<Vec2D>& points,
                              Compare comp)
{
    std::vector<Vec2D> sortedPoints(points.begin(), points.end());
    std::sort(sortedPoints.begin(), sortedPoints.end(), comp);
    return sortedPoints;
}

// Build contours and append them into contourPoints delineated by
// contourOffsets.
void extractPolygons(std::vector<ContourPoint>& contourPoints,
                     std::vector<size_t>& contourOffsets,
                     std::unordered_map<Vec2D, Vec2D>& edgesH,
                     std::unordered_map<Vec2D, Vec2D>& edgesV)
{

    while (!edgesH.empty())
    {
        size_t contourStartOffset = contourPoints.size();
        Vec2D start = edgesH.begin()->first;
        edgesH.erase(start);

        auto first = ContourPoint(start, 0);
        contourPoints.push_back(first);

        while (true)
        {
            auto& curr = contourPoints.back();
            if (curr.dir == 0)
            {
                if (edgesV.find(curr.vec) != edgesV.end())
                {
                    auto next = edgesV[curr.vec];
                    edgesV.erase(curr.vec);
                    contourPoints.emplace_back(next, 1);
                }
                else
                {
                    break;
                }
            }
            else
            {
                if (edgesH.find(curr.vec) != edgesH.end())
                {
                    auto next = edgesH[curr.vec];
                    edgesH.erase(curr.vec);
                    contourPoints.emplace_back(next, 0);
                }
                else
                {
                    break;
                }
            }

            // Remove the last point if the first and last in the contour are
            // the same.
            if (first == contourPoints.back())
            {
                contourPoints.pop_back();
                break;
            }
        }

        contourOffsets.push_back(contourPoints.size());
        for (size_t index = contourStartOffset; index < contourPoints.size();
             index++)
        {
            Vec2D vertex = contourPoints[index].vec;
            edgesH.erase(vertex);
            edgesV.erase(vertex);
        }
    }
}

void RectanglesToContour::computeContours()
{
    subdivideRectangles();
    for (const auto& rect : m_subdividedRects)
    {
        addUniquePoint(Vec2D(rect.minX, rect.minY));
        addUniquePoint(Vec2D(rect.maxX, rect.minY));
        addUniquePoint(Vec2D(rect.maxX, rect.maxY));
        addUniquePoint(Vec2D(rect.minX, rect.maxY));
    }

    auto sortX = sortPoints(m_uniquePoints, [](const Vec2D& a, const Vec2D& b) {
        return a.x < b.x || (a.x == b.x && a.y < b.y);
    });

    auto sortY = sortPoints(m_uniquePoints, [](const Vec2D& a, const Vec2D& b) {
        return a.y < b.y || (a.y == b.y && a.x < b.x);
    });

    // std::unordered_map isn't guaranteed to reserve memory, so this clear
    // is more in prep for when we allow using allocators. We could also
    // experiment with a simple linear search in a vector as usually there
    // are not a lot of edges to traverse.
    m_edgesH.clear();
    m_edgesV.clear();

    size_t i = 0;
    while (i < sortY.size())
    {
        float currY = sortY[i].y;
        while (i < sortY.size() && sortY[i].y == currY)
        {
            m_edgesH[sortY[i]] = sortY[i + 1];
            m_edgesH[sortY[i + 1]] = sortY[i];
            i += 2;
        }
    }

    i = 0;
    while (i < sortX.size())
    {
        float currX = sortX[i].x;
        while (i < sortX.size() && sortX[i].x == currX)
        {
            m_edgesV[sortX[i]] = sortX[i + 1];
            m_edgesV[sortX[i + 1]] = sortX[i];
            i += 2;
        }
    }

    m_contourPoints.clear();
    m_contourOffsets.clear();
    extractPolygons(m_contourPoints, m_contourOffsets, m_edgesH, m_edgesV);
}

void RectanglesToContour::addUniquePoint(const Vec2D& point)
{
    if (!m_uniquePoints.insert(point).second)
    {
        m_uniquePoints.erase(point);
    }
}

ContourItr& ContourItr::operator++()
{
    m_contourIndex++;
    return *this;
}
Contour ContourItr::operator*() const
{
    return m_rectanglesToContour->contour(m_contourIndex);
}

Contour RectanglesToContour::contour(size_t index) const
{
    assert(index < m_contourOffsets.size());
    size_t end = m_contourOffsets[index];
    size_t start = index == 0 ? 0 : m_contourOffsets[index - 1];
    const ContourPoint* data = m_contourPoints.data() + start;
    size_t size = end - start;
    return Contour(Span<const ContourPoint>(data, size));
}

ContourPointItr& ContourPointItr::operator++()
{
    Vec2D currentPoint = m_pointIndex < m_contour.size() ? *(*this) : Vec2D();
    m_pointIndex++;
    while (m_pointIndex < m_contour.size())
    {
        auto nextPoint = m_contour[m_pointIndex].vec;
        if (nextPoint != currentPoint)
        {
            break;
        }
        m_pointIndex++;
    }
    return *this;
}

Vec2D ContourPointItr::operator*() const { return m_contour[m_pointIndex].vec; }
