/*
 * Copyright 2022 Rive
 */

#include "rive/math/raw_path.hpp"
#include <cmath>

using namespace rive;

AABB RawPath::bounds() const {
    if (this->empty()) {
        return {0, 0, 0, 0};
    }
    
    float l, t, r, b;
    l = r = m_Points[0].x();
    t = b = m_Points[0].y();
    for (size_t i = 1; i < m_Points.size(); ++i) {
        const float x = m_Points[i].x();
        const float y = m_Points[i].y();
        l = std::min(l, x);
        r = std::max(r, x);
        t = std::min(t, y);
        b = std::max(b, y);
    }
    return {l, t, r, b};
}

void RawPath::move(Vec2D a) {
    const auto n = m_Verbs.size();
    if (n > 0 && m_Verbs[n-1] == PathVerb::move) {
        m_Points[n-1] = a;  // replace previous move position
    } else {
        m_Points.push_back(a);
        m_Verbs.push_back(PathVerb::move);
    }
}

void RawPath::line(Vec2D a) {
    m_Points.push_back(a);
    m_Verbs.push_back(PathVerb::line);
}

void RawPath::quad(Vec2D a, Vec2D b) {
    m_Points.push_back(a);
    m_Points.push_back(b);
    m_Verbs.push_back(PathVerb::quad);
}

void RawPath::cubic(Vec2D a, Vec2D b, Vec2D c) {
    m_Points.push_back(a);
    m_Points.push_back(b);
    m_Points.push_back(c);
    m_Verbs.push_back(PathVerb::cubic);
}

void RawPath::close() {
    const auto n = m_Verbs.size();
    if (n > 0 && m_Verbs[n-1] != PathVerb::close) {
        m_Verbs.push_back(PathVerb::close);
    }
}

RawPath RawPath::transform(const Mat2D& m) const {
    RawPath path;

    path.m_Verbs = m_Verbs;

    path.m_Points.resize(m_Points.size());
    for (size_t i = 0; i < m_Points.size(); ++i) {
        const float x = m_Points[i].x();
        const float y = m_Points[i].y();
        path.m_Points[i] = {
            m[0] * x + m[2] * y + m[4],
            m[1] * x + m[3] * y + m[5],
        };
    }
    return path;
}

void RawPath::transformInPlace(const Mat2D& m) {
    for (auto& p : m_Points) {
        const float x = p.x();
        const float y = p.y();
        p = {
            m[0] * x + m[2] * y + m[4],
            m[1] * x + m[3] * y + m[5],
        };
    }
}

void RawPath::addRect(const AABB& r, PathDirection dir) {
    // We manually close the rectangle, in case we want to stroke
    // this path. We also call close() so we get proper joins
    // (and not caps).

    m_Points.reserve(5);
    m_Verbs.reserve(6);

    moveTo(r.left(), r.top());
    if (dir == PathDirection::clockwise) {
        lineTo(r.right(), r.top());
        lineTo(r.right(), r.bottom());
        lineTo(r.left(), r.bottom());
    } else {
        lineTo(r.left(), r.bottom());
        lineTo(r.right(), r.bottom());
        lineTo(r.right(), r.top());
    }
    close();
}

void RawPath::addOval(const AABB& r, PathDirection dir) {
    // see https://spencermortensen.com/articles/bezier-circle/
    constexpr float C = 0.5519150244935105707435627f;
    // precompute clockwise unit circle, starting and ending at {1, 0}
    constexpr rive::Vec2D unit[] = {
        { 1,  0}, { 1,  C}, { C,  1}, // quadrant 1 ( 4:30)
        { 0,  1}, {-C,  1}, {-1,  C}, // quadrant 2 ( 7:30)
        {-1,  0}, {-1, -C}, {-C, -1}, // quadrant 3 (10:30)
        { 0, -1}, { C, -1}, { 1, -C}, // quadrant 4 ( 1:30)
        { 1,  0},
    };

    const auto center = r.center();
    const float dx = center.x();
    const float dy = center.y();
    const float sx = r.width() * 0.5f;
    const float sy = r.height() * 0.5f;

    auto map = [dx, dy, sx, sy](rive::Vec2D p) {
        return rive::Vec2D(p.x() * sx + dx, p.y() * sy + dy);
    };

    m_Points.reserve(13);
    m_Verbs.reserve(6);

    if (dir == PathDirection::clockwise) {
        move(map(unit[0]));
        for (int i = 1; i <= 12; i += 3) {
            cubic(map(unit[i+0]), map(unit[i+1]), map(unit[i+2]));
        }
    } else {
        move(map(unit[12]));
        for (int i = 11; i >= 0; i -= 3) {
            cubic(map(unit[i-0]), map(unit[i-1]), map(unit[i-2]));
        }
    }
    close();
}

void RawPath::addPoly(Span<const Vec2D> span, bool isClosed) {
    if (span.size() == 0) {
        return;
    }
    
    // should we permit must moveTo() or just moveTo()/close() ?

    m_Points.reserve(span.size() + isClosed);
    m_Verbs.reserve(span.size() + isClosed);

    move(span[0]);
    for (size_t i = 1; i < span.size(); ++i) {
        line(span[i]);
    }
    if (isClosed) {
        close();
    }
}
