/*
 * Copyright 2020 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "include/core/SkPath.h"
#include "include/core/SkPathTypes.h"
#include "include/core/SkPoint.h"
#include "src/base/SkRandom.h"
#include "src/core/SkPathPriv.h"
#include "tests/Test.h"

SkPoint next_point(SkRandom& rand) { return {rand.nextF(), rand.nextF()}; }

DEF_TEST(SkPath_RangeIter, r) {
    enum class Verb {
        kMove = (int)SkPathVerb::kMove,
        kLine = (int)SkPathVerb::kLine,
        kQuad = (int)SkPathVerb::kQuad,
        kConic = (int)SkPathVerb::kConic,
        kCubic = (int)SkPathVerb::kCubic,
        kClose = (int)SkPathVerb::kClose,
        kImplicitMove
    };

    Verb verbs[] = {
        Verb::kImplicitMove,
        Verb::kLine,
        Verb::kConic,
        Verb::kClose,
        Verb::kImplicitMove,
        Verb::kCubic,
        Verb::kMove,
        Verb::kConic,
        Verb::kLine,
        Verb::kClose,
        Verb::kMove
    };

    class : SkRandom {
    public:
        SkPoint p() { return {this->SkRandom::nextF(), this->SkRandom::nextF()}; }
        float w() { return this->SkRandom::nextF(); }
    } genData, testData;

    for (int i = 0; i < 10; ++i) {
        if (genData.p() != testData.p() || genData.w() != testData.w()) {
            ERRORF(r, "genData and testData not in sync.");
            return;
        }
    }

    // Build the path.
    SkPathBuilder builder;
    for (Verb verb : verbs) {
        switch (verb) {
            case Verb::kImplicitMove:
                break;
            case Verb::kMove:
                builder.moveTo(genData.p());
                break;
            case Verb::kLine:
                builder.lineTo(genData.p());
                break;
            case Verb::kQuad: {
                auto a = genData.p();
                auto b = genData.p();
                builder.quadTo(a, b);
                break;
            }
            case Verb::kCubic: {
                auto a = genData.p();
                auto b = genData.p();
                auto c = genData.p();
                builder.cubicTo(a, b, c);
                break;
            }
            case Verb::kConic: {
                auto a = genData.p();
                auto b = genData.p();
                builder.conicTo(a, b, genData.w());
                break;
            }
            case Verb::kClose:
                builder.close();
                break;
        }
    }
    SkPath path = builder.detach();

    // Verify sure the RangeIter works as expected.
    SkPathPriv::Iterate iterate(path);
    auto iter = iterate.begin();
    SkPoint startPt = {0,0};
    SkPoint lastPt = {0,0};
    for (Verb verb : verbs) {
        auto [pathVerb, pathPts, pathWt] = *iter++;
        switch (verb) {
            case Verb::kImplicitMove:
                REPORTER_ASSERT(r, pathPts[0] == startPt);
                lastPt = pathPts[0];
                break;
            case Verb::kMove:
                REPORTER_ASSERT(r, pathPts[0] == testData.p());
                startPt = lastPt = pathPts[0];
                break;
            case Verb::kLine:
                REPORTER_ASSERT(r, pathPts[0] == lastPt);
                REPORTER_ASSERT(r, pathPts[1] == testData.p());
                lastPt = pathPts[1];
                break;
            case Verb::kQuad:
                REPORTER_ASSERT(r, pathPts[0] == lastPt);
                REPORTER_ASSERT(r, pathPts[1] == testData.p());
                REPORTER_ASSERT(r, pathPts[2] == testData.p());
                lastPt = pathPts[2];
                break;
            case Verb::kCubic:
                REPORTER_ASSERT(r, pathPts[0] == lastPt);
                REPORTER_ASSERT(r, pathPts[1] == testData.p());
                REPORTER_ASSERT(r, pathPts[2] == testData.p());
                REPORTER_ASSERT(r, pathPts[3] == testData.p());
                lastPt = pathPts[3];
                break;
            case Verb::kConic:
                REPORTER_ASSERT(r, pathPts[0] == lastPt);
                REPORTER_ASSERT(r, pathPts[1] == testData.p());
                REPORTER_ASSERT(r, pathPts[2] == testData.p());
                REPORTER_ASSERT(r, *pathWt == testData.w());
                lastPt = pathPts[2];
                break;
            case Verb::kClose:
                REPORTER_ASSERT(r, pathPts[0] == lastPt);
                break;
        }
    }
    REPORTER_ASSERT(r, iter == iterate.end());
}
