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

#include "gm/gm.h"
#include "include/core/SkColor.h"
#include "include/utils/SkAnimCodecPlayer.h"
#include "modules/skottie/include/Skottie.h"
#include "modules/skottie/include/SkottieProperty.h"
#include "modules/skottie/utils/SkottieUtils.h"
#include "modules/skresources/include/SkResources.h"
#include "tools/Resources.h"

#include <cmath>
#include <vector>

namespace {

static constexpr char kWebFontResource[] = "fonts/Roboto-Regular.ttf";
static constexpr char kSkottieResource[] = "skottie/skottie_sample_webfont.json";

// Dummy web font loader which serves a single local font (checked in under resources/).
class FakeWebFontProvider final : public skresources::ResourceProvider {
public:
    FakeWebFontProvider() : fFontData(GetResourceAsData(kWebFontResource)) {}

    sk_sp<SkData> loadFont(const char[], const char[]) const override {
        return fFontData;
    }

private:
    sk_sp<SkData> fFontData;

    using INHERITED = skresources::ResourceProvider;
};

} // namespace

class SkottieExternalPropsGM : public skiagm::GM {
public:
protected:
    SkString onShortName() override {
        return SkString("skottie_external_props");
    }

    SkISize onISize() override {
        return SkISize::Make(kSize, kSize);
    }

    void onOnceBeforeDraw() override {
        if (auto stream = GetResourceAsStream(kSkottieResource)) {
            fPropManager = std::make_unique<skottie_utils::CustomPropertyManager>();
            fAnimation = skottie::Animation::Builder()
                            .setResourceProvider(sk_make_sp<FakeWebFontProvider>())
                            .setPropertyObserver(fPropManager->getPropertyObserver())
                            .make(stream.get());
        }
    }

    DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
        if (!fAnimation) {
            *errorMsg = "No animation";
            return DrawResult::kFail;
        }

        for (size_t i = 0; i < 4; ++i) {
            this->update_props(i);
            auto dest = SkRect::MakeWH(kSize/2, kSize/2).makeOffset(kSize * (i & 1) / 2,
                                                                    kSize * (i & 2) / 4);
            fAnimation->render(canvas, &dest);
        }
        return DrawResult::kOk;
    }

    bool onAnimate(double nanos) override {
        if (!fAnimation) {
            return false;
        }

        const auto duration = fAnimation->duration();
        fAnimation->seek(std::fmod(1e-9 * nanos, duration) / duration);
        return true;
    }

private:
    void update_props(size_t i) {

        SkASSERT(i < 4);
        if (!i) {
            return;
        }

        static constexpr struct {
            const char* txt_string;
            SkColor     txt_color,
                        solid_color;
            float       transform_scale;
        } gTests[] = {
            { "update #1", SK_ColorRED    , SK_ColorYELLOW, 100.f },
            { "update #2", SK_ColorGREEN  , SK_ColorBLUE  ,  50.f },
            { "update #3", SK_ColorMAGENTA, SK_ColorCYAN  , 150.f },
        };

        SkASSERT(i - 1 < SK_ARRAY_COUNT(gTests));
        const auto& tst = gTests[i - 1];

        for (const auto& prop : fPropManager->getColorProps()) {
            SkAssertResult(fPropManager->setColor(prop, tst.solid_color));
        }

        for (const auto& prop : fPropManager->getTransformProps()) {
            auto t = fPropManager->getTransform(prop);
            t.fScale = {tst.transform_scale, tst.transform_scale};
            SkAssertResult(fPropManager->setTransform(prop, t));
        }

        for (const auto& prop : fPropManager->getTextProps()) {
            auto txt = fPropManager->getText(prop);
            txt.fText.set(tst.txt_string);
            txt.fFillColor = tst.txt_color;
            SkAssertResult(fPropManager->setText(prop, txt));
        }
    }

    static constexpr SkScalar kSize = 800;

    sk_sp<skottie::Animation>                             fAnimation;
    std::unique_ptr<skottie_utils::CustomPropertyManager> fPropManager;

    using INHERITED = skiagm::GM;
};

DEF_GM(return new SkottieExternalPropsGM;)
