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

#include "include/core/SkCanvas.h"
#include "include/core/SkStream.h"
#include "include/core/SkSurface.h"
#include "modules/skottie/include/Skottie.h"
#include "tests/Test.h"

using namespace skottie;

DEF_TEST(Skottie_Image_CustomTransform, r) {
    static constexpr char json[] =
        R"({
             "v": "5.2.1",
             "w": 100,
             "h": 100,
             "fr": 10,
             "ip": 0,
             "op": 100,
             "assets": [{
               "id": "img_0",
               "p" : "img_0.png",
               "u" : "images/",
               "w" : 100,
               "h" :  50
             }],
             "layers": [
               {
                 "ip": 0,
                 "op": 100,
                 "ty": 2,
                 "refId": "img_0",
                 "ks": {
                   "p": { "a": 0, "k": [0,25] }
                 }
               }
             ]
           })";

    SkMemoryStream stream(json, strlen(json));

    static const struct TestData {
        float    t;
        SkMatrix m;
        SkColor  c[5]; // expected color samples at center/L/T/R/B
    } tests[] {
        { 0, SkMatrix::I(),
            {0xffff0000, 0xffff0000, 0xff00ff00, 0xffff0000, 0xff00ff00}},
        { 1, SkMatrix::Translate(50,25) * SkMatrix::Scale(.5f,.5f) * SkMatrix::Translate(-50,-25),
            {0xffff0000, 0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00}},
        { 2, SkMatrix::Translate(-50, 0),
            {0xff00ff00, 0xffff0000, 0xff00ff00, 0xff00ff00, 0xff00ff00}},
        { 3, SkMatrix::Translate(0, -25),
            {0xff00ff00, 0xff00ff00, 0xffff0000, 0xff00ff00, 0xff00ff00}},
        { 4, SkMatrix::Translate(50, 0),
            {0xffff0000, 0xff00ff00, 0xff00ff00, 0xffff0000, 0xff00ff00}},
        { 5, SkMatrix::Translate(0, 25),
            {0xffff0000, 0xffff0000, 0xff00ff00, 0xffff0000, 0xffff0000}},
    };

    class TestImageAsset final : public ImageAsset {
    public:
        TestImageAsset(const TestData* tst, skiatest::Reporter* r)
            : fTest(tst)
            , fReporter(r) {
            auto surf = SkSurfaces::Raster(SkImageInfo::MakeN32Premul(200, 100));
            surf->getCanvas()->drawColor(0xffff0000);
            fImage = surf->makeImageSnapshot();
        }

    private:
        bool isMultiFrame() override { return true; }

        FrameData getFrameData(float t) override {
            REPORTER_ASSERT(fReporter, t == fTest->t);

            return { fImage, SkSamplingOptions(), fTest++->m };
        }

        sk_sp<SkImage>      fImage;
        const TestData*     fTest;
        skiatest::Reporter* fReporter;
    };

    class TestResourceProvider final : public ResourceProvider {
    public:
        TestResourceProvider(const TestData* tst, skiatest::Reporter* r)
            : fTest(tst)
            , fReporter(r) {}

    private:
        sk_sp<ImageAsset> loadImageAsset(const char[], const char[], const char[]) const override {
            return sk_make_sp<TestImageAsset>(fTest, fReporter);
        }

        const TestData*      fTest;
        skiatest::Reporter*  fReporter;
    };

    auto anim = Animation::Builder()
                    .setResourceProvider(sk_make_sp<TestResourceProvider>(tests, r))
                    .make(&stream);

    REPORTER_ASSERT(r, anim);

    static constexpr SkSize render_size{100, 100};
    auto surf = SkSurfaces::Raster(
            SkImageInfo::MakeN32Premul(render_size.width(), render_size.height()));
    auto rect = SkRect::MakeSize(render_size);

    SkPixmap pmap;
    surf->peekPixels(&pmap);

    for (const auto& tst : tests) {
        surf->getCanvas()->clear(0xff00ff00);
        anim->seekFrameTime(tst.t);
        anim->render(surf->getCanvas(), &rect);

        REPORTER_ASSERT(r,
            tst.c[0] == pmap.getColor(render_size.width() / 2, render_size.height() / 2));
        REPORTER_ASSERT(r,
            tst.c[1] == pmap.getColor(1                      , render_size.height() / 2));
        REPORTER_ASSERT(r,
            tst.c[2] == pmap.getColor(render_size.width() / 2, 1));
        REPORTER_ASSERT(r,
            tst.c[3] == pmap.getColor(render_size.width() - 1, render_size.height() / 2));
        REPORTER_ASSERT(r,
            tst.c[4] == pmap.getColor(render_size.width() /2 , render_size.height() - 1));
    }
}
