/*
 * Copyright 2022 Rive
 */

#include "gm.hpp"
#include "gmutils.hpp"
#include "rive/math/math_types.hpp"

#include "assets/batdude.png.hpp"
#include "assets/nomoon.png.hpp"

using namespace rivegm;

class ImagePaintGM : public GM
{
public:
    ImagePaintGM() : GM(512, 512) {}

    void onDraw(rive::Renderer* ren) override
    {
        rive::Span<uint8_t> images[] = {
            assets::batdude_png(),
            assets::nomoon_png(),
        };

        rive::AABB r = {0, 0, 250, 250};

        {
            Paint p;
            p->color(0xFF2f2f2f);
            draw_rect(ren, {0, 0, 512, 512}, p);
        }

        rive::Factory* factory = TestingWindow::Get()->factory();

        ren->save();
        ren->translate(256, 256);

        auto img0 = LoadImage(images[0]);
        auto img1 = LoadImage(images[1]);
        if (img0 == nullptr || img1 == nullptr)
        {
            ren->restore();
            Paint p;
            p->color(0xFFFF0000);
            draw_rect(ren, {0, 0, 530, 310}, p);
            return;
        }

        {
            Paint p;
            p->color(0xFFB299FF);
            rive::ColorInt gradientColors[] = {
                0xFFFF9B9Bu,
                0xFFC5FF8Cu,
                0xFF70A6FFu,
            };

            float gradientStops[] = {0.0f, 0.5f, 1.0f};
            static_assert(std::size(gradientColors) ==
                          std::size(gradientStops));
            p->modulatedImage(
                img0.get(),
                {
                    .wrapX = rive::ImageWrap::mirror,
                    .wrapY = rive::ImageWrap::repeat,
                    .filter = rive::ImageFilter::bilinear,
                },
                rive::Mat2D::fromScale(128.0f, 128.0f) *
                    rive::Mat2D::fromTranslate(0.5f, 0.5f) *
                    rive::Mat2D::fromRotation(45.0f * rive::math::PI / 180.0f));

            p->shader(factory->makeLinearGradient(0.0f,
                                                  -100.0f,
                                                  0.0f,
                                                  100.0f,
                                                  gradientColors,
                                                  gradientStops,
                                                  std::size(gradientColors)));

            draw_oval(ren, {-220.0f, -220.0f, 220.0f, 220.0f}, p);

            p->modulatedImage(img1.get(),
                              {
                                  .wrapX = rive::ImageWrap::repeat,
                                  .wrapY = rive::ImageWrap::mirror,
                                  .filter = rive::ImageFilter::bilinear,
                              },
                              rive::Mat2D::fromScale(128.0f, 128.0f));
            p->color(0xFFFFA5F3);
            p->style(rive::RenderPaintStyle::stroke);
            p->thickness(30.0f);
            p->feather(30.0f);
            draw_oval(ren, {-220.0f, -220.0f, 220.0f, 220.0f}, p);
        }
        ren->restore();
    }
};
GMREGISTER(image_paint, return new ImagePaintGM)
