/*
 * Copyright 2022 Rive
 */

#include <rive/math/aabb.hpp>
#include <rive/math/raw_path.hpp>
#include "no_op_renderer.hpp"

#include <catch.hpp>
#include <cstdio>

using namespace rive;

TEST_CASE("rawpath-basics", "[rawpath]") {
    RawPath path;

    REQUIRE(path.empty());
    REQUIRE(path.bounds() == AABB{0, 0, 0, 0});

    path.move({1, 2});
    REQUIRE(!path.empty());
    REQUIRE(path.bounds() == AABB{1, 2, 1, 2});

    path = RawPath();
    REQUIRE(path.empty());
    REQUIRE(path.bounds() == AABB{0, 0, 0, 0});

    path.move({1, -2});
    path.line({3, 4});
    path.line({-1, 5});
    REQUIRE(!path.empty());
    REQUIRE(path.bounds() == AABB{-1, -2, 3, 5});
}

TEST_CASE("rawpath-add-helpers", "[rawpath]") {
    RawPath path;

    path.addRect({1, 1, 5, 6});
    REQUIRE(!path.empty());
    REQUIRE(path.bounds() == AABB{1, 1, 5, 6});
    REQUIRE(path.points().size() == 4);
    REQUIRE(path.verbs().size() == 5); // move, line, line, line, close

    path = RawPath();
    path.addOval({0, 0, 3, 6});
    REQUIRE(!path.empty());
    REQUIRE(path.bounds() == AABB{0, 0, 3, 6});
    REQUIRE(path.points().size() == 13);
    REQUIRE(path.verbs().size() == 6); // move, cubic, cubic, cubic, cubic, close

    const Vec2D pts[] = {
        {1, 2},
        {4, 5},
        {3, 2},
        {100, -100},
    };
    constexpr auto size = sizeof(pts) / sizeof(pts[0]);

    for (auto isClosed : {false, true}) {
        path = RawPath();
        path.addPoly({pts, size}, isClosed);
        REQUIRE(path.bounds() == AABB{1, -100, 100, 5});
        REQUIRE(path.points().size() == size);
        REQUIRE(path.verbs().size() == size + isClosed);

        for (size_t i = 0; i < size; ++i) {
            REQUIRE(path.points()[i] == pts[i]);
        }
        REQUIRE(path.verbs()[0] == PathVerb::move);
        for (size_t i = 1; i < size; ++i) {
            REQUIRE(path.verbs()[i] == PathVerb::line);
        }
        if (isClosed) {
            REQUIRE(path.verbs()[size] == PathVerb::close);
        }
    }
}

//////////////////////////////////////////////////////////////////////////

static bool is_move(const RawPath::Iter::Rec& rec) {
    if (rec.verb == PathVerb::move) {
        REQUIRE(rec.count == 1);
        return true;
    }
    return false;
}

static bool is_line(const RawPath::Iter::Rec& rec) {
    if (rec.verb == PathVerb::line) {
        REQUIRE(rec.count == 1);
        return true;
    }
    return false;
}

static bool is_quad(const RawPath::Iter::Rec& rec) {
    if (rec.verb == PathVerb::quad) {
        REQUIRE(rec.count == 2);
        return true;
    }
    return false;
}

static bool is_cubic(const RawPath::Iter::Rec& rec) {
    if (rec.verb == PathVerb::cubic) {
        REQUIRE(rec.count == 3);
        return true;
    }
    return false;
}

static bool is_close(const RawPath::Iter::Rec& rec) {
    if (rec.verb == PathVerb::close) {
        REQUIRE(rec.count == 0);
        return true;
    }
    return false;
}

TEST_CASE("rawpath-iter", "[rawpath]") {
    auto eq = [](Vec2D p, float x, float y) { return p.x == x && p.y == y; };

    {
        RawPath rp;
        RawPath::Iter iter(rp);
        REQUIRE(iter.next() == false);
        REQUIRE(iter.next() == false);  // should be safe to call again
    }
    {
        RawPath rp;
        rp.moveTo(1, 2);
        rp.lineTo(3, 4);
        rp.quadTo(5, 6, 7, 8);
        rp.cubicTo(9, 10, 11, 12, 13, 14);
        rp.close();
        RawPath::Iter iter(rp);
        auto rec = iter.next();
        REQUIRE((rec && is_move(rec) && eq(rec.pts[0], 1,2)));
        rec = iter.next();
        REQUIRE((rec && is_line(rec) && eq(rec.pts[0], 3,4)));
        rec = iter.next();
        REQUIRE((rec && is_quad(rec) && eq(rec.pts[0], 5,6) 
                                     && eq(rec.pts[1], 7,8)));
        rec = iter.next();
        REQUIRE((rec && is_cubic(rec) && eq(rec.pts[0], 9,10) 
                                      && eq(rec.pts[1], 11,12)
                                      && eq(rec.pts[2], 13,14)));
        rec = iter.next();
        REQUIRE((rec && is_close(rec)));
        rec = iter.next();
        REQUIRE(rec == false);
        REQUIRE(iter.next() == false);  // should be safe to call again
    }
}
