#include "fiddle_context.hpp"

#include "rive/math/simd.hpp"
#include "rive/artboard.hpp"
#include "rive/file.hpp"
#include "rive/refcnt.hpp"
#include "rive/layout.hpp"
#include "rive/animation/state_machine_instance.hpp"
#include "rive/static_scene.hpp"
#include "rive/profiler/profiler_macros.h"

#include <filesystem>
#include <fstream>
#include <iterator>
#include <vector>
#include <sstream>

#ifdef _WIN32
#include <windows.h>
#endif

#define GLFW_INCLUDE_NONE
#include "GLFW/glfw3.h"

#ifdef __EMSCRIPTEN__
#include <emscripten/emscripten.h>
#include <emscripten/html5.h>
#include <sstream>
#endif

using namespace rive;

constexpr static char kMoltenVKICD[] =
    "dependencies/MoltenVK/Package/Release/MoltenVK/dynamic/dylib/macOS/"
    "MoltenVK_icd.json";

constexpr static char kSwiftShaderICD[] = "dependencies/SwiftShader/build/"
#ifdef __APPLE__
                                          "Darwin"
#elif defined(_WIN32)
                                          "Windows"
#else
                                          "Linux"
#endif
                                          "/vk_swiftshader_icd.json";

#ifdef _WIN32
extern "C"
{
    // https://stackoverflow.com/questions/68469954/how-to-choose-specific-gpu-when-create-opengl-context:
    //
    //   OpenGL, or rather the Win32 GDI integration of it, doesn't offer means
    //   to explicitly select the desired device. However the drivers of Nvidia
    //   and AMD offer a workaround to have programs select, that they prefer to
    //   execute on the discrete GPU rather than the CPU integrated one.
    //
    // These also appear to select the discrete "Arc" GPU on an Intel system,
    // and to influence the GPU selection on D3D11.
    __declspec(dllexport) uint32_t NvOptimusEnablement = 1;
    __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
}
#endif

static FiddleContextOptions options;
static GLFWwindow* window = nullptr;
static int msaa = 0;
static bool forceAtomicMode = false;
static bool wireframe = false;
static bool disableFill = false;
static bool disableStroke = false;
static bool clockwiseFill = false;
static bool hotloadShaders = false;

static std::unique_ptr<FiddleContext> fiddleContext;

static float2 pts[] = {{260 + 2 * 100, 60 + 2 * 500},
                       {260 + 2 * 257, 60 + 2 * 233},
                       {260 + 2 * -100, 60 + 2 * 300},
                       {260 + 2 * 100, 60 + 2 * 200},
                       {260 + 2 * 250, 60 + 2 * 0},
                       {260 + 2 * 400, 60 + 2 * 200},
                       {260 + 2 * 213, 60 + 2 * 200},
                       {260 + 2 * 213, 60 + 2 * 300},
                       {260 + 2 * 391, 60 + 2 * 480},
                       {1400, 1400}}; // Feather control.
constexpr static int NUM_INTERACTIVE_PTS = sizeof(pts) / sizeof(*pts);

static float strokeWidth = 70;

static float2 translate;
static float scale = 1;

static StrokeJoin join = StrokeJoin::round;
static StrokeCap cap = StrokeCap::round;

static bool doClose = false;
static bool paused = false;
static bool unlockedLogic = true;

static int dragIdx = -1;
static float2 dragLastPos;

static int animation = -1;
static int stateMachine = -1;
static int horzRepeat = 0;
static int upRepeat = 0;
static int downRepeat = 0;

rcp<File> rivFile;
std::vector<std::unique_ptr<Artboard>> artboards;
std::vector<std::unique_ptr<Scene>> scenes;
std::vector<rive::rcp<rive::ViewModelInstance>> viewModelInstances;

static void clear_scenes()
{
    artboards.clear();
    scenes.clear();
    viewModelInstances.clear();
}

static void make_scenes(size_t count)
{
    clear_scenes();
    for (size_t i = 0; i < count; ++i)
    {
        // Tip: you can change the artboard shown here
        // auto artboard = rivFile->artboardAt(2);
        auto artboard = rivFile->artboardDefault();
        std::unique_ptr<Scene> scene;
        if (stateMachine >= 0)
        {
            scene = artboard->stateMachineAt(stateMachine);
        }
        else if (animation >= 0)
        {
            scene = artboard->animationAt(animation);
        }
        else
        {
            scene = artboard->animationAt(0);
        }
        if (scene == nullptr)
        {
            // This is a riv without any animations or state machines. Just draw
            // the artboard.
            scene = std::make_unique<StaticScene>(artboard.get());
        }

        int viewModelId = artboard.get()->viewModelId();
        viewModelInstances.push_back(
            viewModelId == -1
                ? rivFile->createViewModelInstance(artboard.get())
                : rivFile->createViewModelInstance(viewModelId, 0));
        artboard->bindViewModelInstance(viewModelInstances.back());
        if (viewModelInstances.back() != nullptr)
        {
            scene->bindViewModelInstance(viewModelInstances.back());
        }

        scene->advanceAndApply(scene->durationSeconds() * i / count);
        artboards.push_back(std::move(artboard));
        scenes.push_back(std::move(scene));
    }
}

#ifdef __EMSCRIPTEN__
EM_JS(int, window_inner_width, (), { return window["innerWidth"]; });
EM_JS(int, window_inner_height, (), { return window["innerHeight"]; });
EM_JS(char*, get_location_hash_str, (), {
    var jsString = window.location.hash.substring(1);
    var lengthBytes = lengthBytesUTF8(jsString) + 1;
    var stringOnWasmHeap = _malloc(lengthBytes);
    stringToUTF8(jsString, stringOnWasmHeap, lengthBytes);
    return stringOnWasmHeap;
});
#endif

static void mouse_button_callback(GLFWwindow* window,
                                  int button,
                                  int action,
                                  int mods)
{
    double x, y;
    glfwGetCursorPos(window, &x, &y);
    float dpiScale = fiddleContext->dpiScale(window);
    x *= dpiScale;
    y *= dpiScale;
    dragLastPos = float2{(float)x, (float)y};
    if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS)
    {
        dragIdx = -1;
        if (!rivFile)
        {
            for (int i = 0; i < NUM_INTERACTIVE_PTS; ++i)
            {
                if (simd::all(simd::abs(dragLastPos - (pts[i] + translate)) <
                              100))
                {
                    dragIdx = i;
                    break;
                }
            }
        }
    }
}

static void mousemove_callback(GLFWwindow* window, double x, double y)
{
    float dpiScale = fiddleContext->dpiScale(window);
    x *= dpiScale;
    y *= dpiScale;
    if (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS)
    {
        float2 pos = float2{(float)x, (float)y};
        if (dragIdx >= 0)
        {
            pts[dragIdx] += (pos - dragLastPos);
        }
        else
        {
            translate += (pos - dragLastPos);
        }
        dragLastPos = pos;
    }
}

int lastWidth = 0, lastHeight = 0;
double fpsLastTime = 0;
double fpsLastTimeLogic = 0;
int fpsFrames = 0;
static bool needsTitleUpdate = false;

enum class API
{
    gl,
    metal,
    d3d,
    d3d12,
    dawn,
    vulkan,
};

API api =
#if defined(__APPLE__)
    API::metal
#elif defined(_WIN32)
    API::d3d
#else
    API::gl
#endif
    ;

bool angle = false;
bool skia = false;

static void key_callback(GLFWwindow* window,
                         int key,
                         int scancode,
                         int action,
                         int mods)
{
    bool shift = mods & GLFW_MOD_SHIFT;
    if (action == GLFW_PRESS)
    {
        switch (key)
        {
            case GLFW_KEY_ESCAPE:
                glfwSetWindowShouldClose(window, 1);
                break;
            case GLFW_KEY_GRAVE_ACCENT: // ` key, backtick
                hotloadShaders = true;
                break;
            case GLFW_KEY_A:
                forceAtomicMode = !forceAtomicMode;
                fpsLastTime = 0;
                fpsFrames = 0;
                needsTitleUpdate = true;
                break;
            case GLFW_KEY_D:
                printf("static float scale = %f;\n", scale);
                printf("static float2 translate = {%f, %f};\n",
                       translate.x,
                       translate.y);
                printf("static float2 pts[] = {");
                for (int i = 0; i < NUM_INTERACTIVE_PTS; i++)
                {
                    printf("{%g, %g}", pts[i].x, pts[i].y);
                    if (i < NUM_INTERACTIVE_PTS - 1)
                    {
                        printf(", ");
                    }
                    else
                    {
                        printf("};\n");
                    }
                }
                fflush(stdout);
                break;
            case GLFW_KEY_Z:
                fiddleContext->toggleZoomWindow();
                break;
            case GLFW_KEY_MINUS:
                strokeWidth /= 1.5f;
                break;
            case GLFW_KEY_EQUAL:
                strokeWidth *= 1.5f;
                break;
            case GLFW_KEY_W:
                wireframe = !wireframe;
                break;
            case GLFW_KEY_C:
                cap = static_cast<StrokeCap>((static_cast<int>(cap) + 1) % 3);
                break;
            case GLFW_KEY_O:
                doClose = !doClose;
                break;
            case GLFW_KEY_S:
                if (shift)
                {
                    // Toggle Skia.
                    clear_scenes();
                    rivFile = nullptr;
                    skia = !skia;
                    fiddleContext = skia ? FiddleContext::MakeGLSkia()
                                         : FiddleContext::MakeGLPLS();
                    lastWidth = 0;
                    lastHeight = 0;
                    fpsLastTime = 0;
                    fpsFrames = 0;
                    needsTitleUpdate = true;
                }
                else
                {
                    disableStroke = !disableStroke;
                }
                break;
            case GLFW_KEY_F:
                disableFill = !disableFill;
                break;
            case GLFW_KEY_X:
                clockwiseFill = !clockwiseFill;
                break;
            case GLFW_KEY_P:
                paused = !paused;
                break;
            case GLFW_KEY_H:
                if (!shift)
                    ++horzRepeat;
                else if (horzRepeat > 0)
                    --horzRepeat;
                break;
            case GLFW_KEY_K:
                if (!shift)
                    ++upRepeat;
                else if (upRepeat > 0)
                    --upRepeat;
                break;
            case GLFW_KEY_J:
                if (!rivFile)
                    join = static_cast<StrokeJoin>(
                        (static_cast<int>(join) + 1) % 3);
                else if (!shift)
                    ++downRepeat;
                else if (downRepeat > 0)
                    --downRepeat;
                break;
            case GLFW_KEY_UP:
            {
                float oldScale = scale;
                scale *= 1.25;
                double x = 0, y = 0;
                glfwGetCursorPos(window, &x, &y);
                float2 cursorPos = float2{(float)x, (float)y} *
                                   fiddleContext->dpiScale(window);
                translate =
                    cursorPos + (translate - cursorPos) * scale / oldScale;
                break;
            }
            case GLFW_KEY_DOWN:
            {
                float oldScale = scale;
                scale /= 1.25;
                double x = 0, y = 0;
                glfwGetCursorPos(window, &x, &y);
                float2 cursorPos = float2{(float)x, (float)y} *
                                   fiddleContext->dpiScale(window);
                translate =
                    cursorPos + (translate - cursorPos) * scale / oldScale;
                break;
            }
            case GLFW_KEY_U:
                unlockedLogic = !unlockedLogic;
        }
    }
}

static void glfw_error_callback(int code, const char* message)
{
    printf("GLFW error: %i - %s\n", code, message);
}

static void set_environment_variable(const char* name, const char* value)
{
    if (const char* existingValue = getenv(name))
    {
        printf("warning: %s=%s already set. Overriding with %s=%s\n",
               name,
               existingValue,
               name,
               value);
    }
#ifdef _WIN32
    SetEnvironmentVariableA(name, value);
#else
    setenv(name, value, /*overwrite=*/true);
#endif
}

std::unique_ptr<Renderer> renderer;
std::string rivName;

void riveMainLoop();

int main(int argc, const char** argv)
{
    // Cause stdout and stderr to print immediately without buffering.
    setvbuf(stdout, NULL, _IONBF, 0);
    setvbuf(stderr, NULL, _IONBF, 0);

#ifdef DEBUG
    options.enableVulkanValidationLayers = true;
#endif

#ifdef __EMSCRIPTEN__
    emscripten_set_main_loop(riveMainLoop, 0, false);

    // Override argc/argv with the window location hash string.
    char* hash = get_location_hash_str();
    std::stringstream ss(hash);
    std::vector<std::string> hashStrs;
    std::vector<const char*> hashArgs;
    std::string arg;

    hashStrs.push_back("index.html");
    while (std::getline(ss, arg, ':'))
    {
        hashStrs.push_back(std::move(arg));
    }
    for (const std::string& str : hashStrs)
    {
        hashArgs.push_back(str.c_str());
    }

    argc = hashArgs.size();
    argv = hashArgs.data();
    free(hash);
#endif

    for (int i = 1; i < argc; i++)
    {
        if (!strcmp(argv[i], "--gl"))
        {
            api = API::gl;
        }
        else if (!strcmp(argv[i], "--glatomic"))
        {
            api = API::gl;
            forceAtomicMode = true;
        }
        else if (!strcmp(argv[i], "--glcw"))
        {
            api = API::gl;
            forceAtomicMode = true;
            clockwiseFill = true;
        }
        else if (!strcmp(argv[i], "--metal"))
        {
            api = API::metal;
        }
        else if (!strcmp(argv[i], "--metalcw"))
        {
            api = API::metal;
            clockwiseFill = true;
        }
        else if (!strcmp(argv[i], "--metalatomic"))
        {
            api = API::metal;
            forceAtomicMode = true;
        }
        else if (!strcmp(argv[i], "--mvk") || !strcmp(argv[i], "--moltenvk"))
        {
            set_environment_variable("VK_ICD_FILENAMES", kMoltenVKICD);
            api = API::vulkan;
        }
        else if (!strcmp(argv[i], "--mvkatomic") ||
                 !strcmp(argv[i], "--moltenvkatomic"))
        {
            set_environment_variable("VK_ICD_FILENAMES", kMoltenVKICD);
            api = API::vulkan;
            forceAtomicMode = true;
        }
        else if (!strcmp(argv[i], "--sw") || !strcmp(argv[i], "--swiftshader"))
        {
            // Use the swiftshader built by
            // packages/runtime/renderer/make_swiftshader.sh
            set_environment_variable("VK_ICD_FILENAMES", kSwiftShaderICD);
            api = API::vulkan;
        }
        else if (!strcmp(argv[i], "--swatomic") ||
                 !strcmp(argv[i], "--swiftshaderatomic"))
        {
            // Use the swiftshader built by
            // packages/runtime/renderer/make_swiftshader.sh
            set_environment_variable("VK_ICD_FILENAMES", kSwiftShaderICD);
            api = API::vulkan;
            forceAtomicMode = true;
        }
        else if (!strcmp(argv[i], "--dawn"))
        {
            api = API::dawn;
        }
        else if (!strcmp(argv[i], "--d3d"))
        {
            api = API::d3d;
        }
        else if (!strcmp(argv[i], "--d3d12"))
        {
            api = API::d3d12;
        }
        else if (!strcmp(argv[i], "--d3datomic"))
        {
            api = API::d3d;
            forceAtomicMode = true;
        }
        else if (!strcmp(argv[i], "--d3d12atomic"))
        {
            api = API::d3d12;
            forceAtomicMode = true;
        }
        else if (!strcmp(argv[i], "--vulkan") || !strcmp(argv[i], "--vk"))
        {
            api = API::vulkan;
        }
        else if (!strcmp(argv[i], "--vkcw"))
        {
            api = API::vulkan;
            clockwiseFill = true;
        }
        else if (!strcmp(argv[i], "--vulkanatomic") ||
                 !strcmp(argv[i], "--vkatomic"))
        {
            api = API::vulkan;
            forceAtomicMode = true;
        }
#ifdef RIVE_DESKTOP_GL
        else if (!strcmp(argv[i], "--angle_gl"))
        {
            api = API::gl;
            glfwInitHint(GLFW_ANGLE_PLATFORM_TYPE,
                         GLFW_ANGLE_PLATFORM_TYPE_OPENGL);
            angle = true;
        }
        else if (!strcmp(argv[i], "--angle_d3d"))
        {
            api = API::gl;
            glfwInitHint(GLFW_ANGLE_PLATFORM_TYPE,
                         GLFW_ANGLE_PLATFORM_TYPE_D3D11);
            angle = true;
        }
        else if (!strcmp(argv[i], "--angle_vk"))
        {
            api = API::gl;
            glfwInitHint(GLFW_ANGLE_PLATFORM_TYPE,
                         GLFW_ANGLE_PLATFORM_TYPE_VULKAN);
            angle = true;
        }
        else if (!strcmp(argv[i], "--angle_mtl"))
        {
            api = API::gl;
            glfwInitHint(GLFW_ANGLE_PLATFORM_TYPE,
                         GLFW_ANGLE_PLATFORM_TYPE_METAL);
            angle = true;
        }
#endif
        else if (!strcmp(argv[i], "--skia"))
        {
            skia = true;
        }
        else if (sscanf(argv[i], "-a%i", &animation) == 1)
        {
            // Already updated animation.
        }
        else if (sscanf(argv[i], "-s%i", &stateMachine) == 1)
        {
            // Already updated stateMachine.
        }
        else if (sscanf(argv[i], "-h%i", &horzRepeat) == 1)
        {
            // Already updated horzRepeat.
        }
        else if (sscanf(argv[i], "-j%i", &downRepeat) == 1)
        {
            // Already updated downRepeat.
        }
        else if (sscanf(argv[i], "-k%i", &upRepeat) == 1)
        {
            // Already updated upRepeat.
        }
        else if (!strcmp(argv[i], "-p"))
        {
            paused = true;
        }
        else if (!strcmp(argv[i], "--d3d12Warp"))
        {
            options.d3d12UseWarpDevice = true;
        }
        else if (!strcmp(argv[i], "--atomic"))
        {
            forceAtomicMode = true;
        }
        else if (sscanf(argv[i], "--msaa%i", &msaa) == 1)
        {
            // Already updated msaa
        }
        else if (!strcmp(argv[i], "--core"))
        {
            options.coreFeaturesOnly = true;
        }
        else if (!strcmp(argv[i], "--validation"))
        {
            options.enableVulkanValidationLayers = true;
        }
        else if (!strcmp(argv[i], "--gpu") || !strcmp(argv[i], "-g"))
        {
            options.gpuNameFilter = argv[++i];
        }
        else if (!strcmp(argv[i], "--integrated") || !strcmp(argv[i], "-i"))
        {
            options.gpuNameFilter = "integrated";
        }
        else if (!strncmp(argv[i], "--", 2))
        {
            fprintf(stderr, "Unknown command-line option %s\n", argv[i]);
            return 1;
        }
        else
        {
            rivName = argv[i];
        }
    }

#ifdef _WIN32
    // Set our backdoor GPU selection variables in case the API doesn't allow us
    // to select explicitly.
    if (options.gpuNameFilter != nullptr)
    {
        // "i" and "integrated" are special-case gpuNameFilters that mean "use
        // the integrated GPU".
        bool wantIntegratedGPU = static_cast<uint32_t>(
            strcmp(options.gpuNameFilter, "integrated") == 0 ||
            strcmp(options.gpuNameFilter, "i") == 0);
        NvOptimusEnablement = !wantIntegratedGPU;
        AmdPowerXpressRequestHighPerformance = !wantIntegratedGPU;
    }
#endif

    glfwSetErrorCallback(glfw_error_callback);

    if (!glfwInit())
    {
        fprintf(stderr, "Failed to initialize glfw.\n");
        return 1;
    }

    if (msaa > 0)
    {
        if (msaa > 1)
        {
            glfwWindowHint(GLFW_SAMPLES, msaa);
        }
        glfwWindowHint(GLFW_STENCIL_BITS, 8);
        glfwWindowHint(GLFW_DEPTH_BITS, 16);
    }
    glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
    switch (api)
    {
        case API::metal:
        case API::d3d:
        case API::d3d12:
        case API::dawn:
            glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
            glfwWindowHint(GLFW_COCOA_RETINA_FRAMEBUFFER, GLFW_TRUE);
            break;
        case API::vulkan:
            glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
            break;
        case API::gl:
            if (angle)
            {
                glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_EGL_CONTEXT_API);
                glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
                glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
                glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
                glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
            }
            else
            {
                glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API);
                glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
                glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
            }
            break;
    }
    glfwWindowHint(GLFW_FOCUS_ON_SHOW, GLFW_TRUE);
    // glfwWindowHint(GLFW_FLOATING, GLFW_TRUE);
    window = glfwCreateWindow(1600, 1600, "Rive Renderer", nullptr, nullptr);
    if (!window)
    {
        glfwTerminate();
        fprintf(stderr, "Failed to create window.\n");
        return -1;
    }

    glfwSetMouseButtonCallback(window, mouse_button_callback);
    glfwSetCursorPosCallback(window, mousemove_callback);
    glfwSetKeyCallback(window, key_callback);
    if (api == API::gl)
    {
        glfwMakeContextCurrent(window);
    }
    glfwShowWindow(window);

    switch (api)
    {
        case API::metal:
            fiddleContext = FiddleContext::MakeMetalPLS(options);
            break;
        case API::d3d:
            fiddleContext = FiddleContext::MakeD3DPLS(options);
            break;
        case API::d3d12:
            fiddleContext = FiddleContext::MakeD3D12PLS(options);
            break;
        case API::dawn:
            fiddleContext = FiddleContext::MakeDawnPLS(options);
            break;
        case API::vulkan:
            fiddleContext = FiddleContext::MakeVulkanPLS(options);
            break;
        case API::gl:
            fiddleContext =
                skia ? FiddleContext::MakeGLSkia() : FiddleContext::MakeGLPLS();
            break;
    }
    if (!fiddleContext)
    {
        fprintf(stderr, "Failed to create a fiddle context.\n");
        abort();
    }

#ifndef __EMSCRIPTEN__
    if (api == API::gl)
    {
        glfwSwapInterval(0);
    }
    while (!glfwWindowShouldClose(window))
    {
        riveMainLoop();
        fiddleContext->tick();
        if (api == API::gl)
        {
            glfwSwapBuffers(window);
        }
        if (!rivName.empty())
        {
            glfwPollEvents();
        }
        else
        {
            glfwWaitEvents();
        }
    }

    // We need to clear the riv scene (which can be holding on to render
    // resources) before releasing the fiddle context
    clear_scenes();
    rivFile = nullptr;

    fiddleContext = nullptr;
    glfwTerminate();
#endif

    return 0;
}

static void update_window_title(double fps,
                                int instances,
                                int width,
                                int height)
{
    std::ostringstream title;
    if (fps != 0)
    {
        title << '[' << fps << " FPS]";
    }
    if (instances > 1)
    {
        title << " (x" << instances << " instances)";
    }
    if (skia)
    {
        title << " | SKIA Renderer";
    }
    else
    {
        title << " | RIVE Renderer";
    }
    if (msaa)
    {
        title << " (msaa" << msaa << ')';
    }
    else if (forceAtomicMode)
    {
        title << " (atomic)";
    }
    title << " | " << width << " x " << height;
    glfwSetWindowTitle(window, title.str().c_str());
}

void riveMainLoop()
{
    RIVE_PROF_FRAME()
    RIVE_PROF_SCOPE()

#ifdef __EMSCRIPTEN__
    {
        // Fit the canvas to the browser window size.
        int windowWidth = window_inner_width();
        int windowHeight = window_inner_height();
        double devicePixelRatio = emscripten_get_device_pixel_ratio();
        int canvasExpectedWidth = windowWidth * devicePixelRatio;
        int canvasExpectedHeight = windowHeight * devicePixelRatio;
        int canvasWidth, canvasHeight;
        glfwGetFramebufferSize(window, &canvasWidth, &canvasHeight);
        if (canvasWidth != canvasExpectedWidth ||
            canvasHeight != canvasExpectedHeight)
        {
            glfwSetWindowSize(window,
                              canvasExpectedWidth,
                              canvasExpectedHeight);
            emscripten_set_element_css_size("#canvas",
                                            windowWidth,
                                            windowHeight);
        }
    }
#endif

    int width = 0, height = 0;
    glfwGetFramebufferSize(window, &width, &height);
    if (lastWidth != width || lastHeight != height)
    {
        printf("size changed to %ix%i\n", width, height);
        lastWidth = width;
        lastHeight = height;
        fiddleContext->onSizeChanged(window, width, height, msaa);
        renderer = fiddleContext->makeRenderer(width, height);
        needsTitleUpdate = true;
    }
    if (needsTitleUpdate)
    {
        update_window_title(0, 1, width, height);
        needsTitleUpdate = false;
    }

    if (!rivName.empty() && !rivFile)
    {
        std::ifstream rivStream(rivName, std::ios::binary);
        std::vector<uint8_t> rivBytes(std::istreambuf_iterator<char>(rivStream),
                                      {});
        rivFile = File::import(rivBytes, fiddleContext->factory());
    }

    // Call right before begin()
    if (hotloadShaders)
    {
        hotloadShaders = false;

#ifndef RIVE_BUILD_FOR_IOS
        // We want to build to /tmp/rive (or the correct equivalent)
        std::filesystem::path tempRiveDir =
            std::filesystem::temp_directory_path() / "rive";

        // Get the u8 version of the path (this is especially necessary on
        // windows where the native path character type is wchar_t, then
        // reinterpret_cast the char8_t pointer to char so we can append it to
        // our string.
        // Store the u8string result to extend its lifetime (need to
        // reinterpret_cast through a const char * pointer because u8string
        // returns a std::u8string in C++20 and newer, but we need it as a
        // "char" string)
        std::string tempRiveDirStr =
            reinterpret_cast<const char*>(tempRiveDir.u8string().c_str());

        std::string rebuildCommand = "sh rebuild_shaders.sh " + tempRiveDirStr;
        std::system(rebuildCommand.c_str());
#endif
        fiddleContext->hotloadShaders();
    }
    fiddleContext->begin({
        .renderTargetWidth = static_cast<uint32_t>(width),
        .renderTargetHeight = static_cast<uint32_t>(height),
        .clearColor = 0xff303030,
        .msaaSampleCount = msaa,
        .disableRasterOrdering = forceAtomicMode,
        .wireframe = wireframe,
        .fillsDisabled = disableFill,
        .strokesDisabled = disableStroke,
        .clockwiseFillOverride = clockwiseFill,
    });

    int instances = 1;
    if (rivFile)
    {
        instances = (1 + horzRepeat * 2) * (1 + upRepeat + downRepeat);
        if (artboards.size() != instances || scenes.size() != instances)
        {
            make_scenes(instances);
        }
        else if (!paused)
        {
            float dT = 1 / 120.f;

            if (!unlockedLogic)
            {
                double time = glfwGetTime();
                dT = time - fpsLastTimeLogic;
                fpsLastTimeLogic = time;
            }

            for (const auto& scene : scenes)
            {
                scene->advanceAndApply(dT);
            }
        }
        Mat2D m = computeAlignment(rive::Fit::contain,
                                   rive::Alignment::center,
                                   rive::AABB(0, 0, width, height),
                                   artboards.front()->bounds());
        renderer->save();
        m = Mat2D(scale, 0, 0, scale, translate.x, translate.y) * m;
        renderer->transform(m);
        float spacing = 200 / m.findMaxScale();
        auto scene = scenes.begin();
        for (int j = 0; j < upRepeat + 1 + downRepeat; ++j)
        {
            renderer->save();
            renderer->transform(Mat2D::fromTranslate(-spacing * horzRepeat,
                                                     (j - upRepeat) * spacing));
            for (int i = 0; i < horzRepeat * 2 + 1; ++i)
            {

                (*scene++)->draw(renderer.get());
                renderer->transform(Mat2D::fromTranslate(spacing, 0));
            }
            renderer->restore();
        }
        renderer->restore();
    }
    else
    {
        float2 p[9];
        for (int i = 0; i < 9; ++i)
        {
            p[i] = pts[i] + translate;
        }
        RawPath rawPath;
        rawPath.moveTo(p[0].x, p[0].y);
        rawPath.cubicTo(p[1].x, p[1].y, p[2].x, p[2].y, p[3].x, p[3].y);
        float2 c0 = simd::mix(p[3], p[4], float2(2 / 3.f));
        float2 c1 = simd::mix(p[5], p[4], float2(2 / 3.f));
        rawPath.cubicTo(c0.x, c0.y, c1.x, c1.y, p[5].x, p[5].y);
        rawPath.cubicTo(p[6].x, p[6].y, p[7].x, p[7].y, p[8].x, p[8].y);
        if (doClose)
        {
            rawPath.close();
        }

        Factory* factory = fiddleContext->factory();
        auto path = factory->makeRenderPath(rawPath, FillRule::clockwise);

        auto fillPaint = factory->makeRenderPaint();
        float feather = powf(1.5f, (1400 - pts[std::size(pts) - 1].y) / 75);
        if (feather > 1)
        {
            fillPaint->feather(feather);
        }
        fillPaint->color(0xd0ffffff);

        renderer->drawPath(path.get(), fillPaint.get());

        if (!disableStroke)
        {
            auto strokePaint = factory->makeRenderPaint();
            strokePaint->style(RenderPaintStyle::stroke);
            strokePaint->color(0x8000ffff);
            strokePaint->thickness(strokeWidth);
            if (feather > 1)
            {
                strokePaint->feather(feather);
            }

            strokePaint->join(join);
            strokePaint->cap(cap);
            renderer->drawPath(path.get(), strokePaint.get());

            // Draw the interactive points.
            auto pointPaint = factory->makeRenderPaint();
            pointPaint->style(RenderPaintStyle::stroke);
            pointPaint->color(0xff0000ff);
            pointPaint->thickness(14);
            pointPaint->cap(StrokeCap::round);
            pointPaint->join(StrokeJoin::round);

            auto pointPath = factory->makeEmptyRenderPath();
            for (int i : {1, 2, 4, 6, 7})
            {
                float2 pt = pts[i] + translate;
                pointPath->moveTo(pt.x, pt.y);
                pointPath->close();
            }
            renderer->drawPath(pointPath.get(), pointPaint.get());

            // Draw the feather control point.
            pointPaint->color(0xffff0000);
            pointPath = factory->makeEmptyRenderPath();
            float2 pt = pts[std::size(pts) - 1] + translate;
            pointPath->moveTo(pt.x, pt.y);
            renderer->drawPath(pointPath.get(), pointPaint.get());
        }
    }

    fiddleContext->end(window);

    if (rivFile)
    {
        // Count FPS.
        ++fpsFrames;
        double time = glfwGetTime();
        double fpsElapsed = time - fpsLastTime;
        if (fpsElapsed > 2)
        {
            int instances = (1 + horzRepeat * 2) * (1 + upRepeat + downRepeat);
            double fps = fpsLastTime == 0 ? 0 : fpsFrames / fpsElapsed;
            update_window_title(fps, instances, width, height);
            fpsFrames = 0;
            fpsLastTime = time;
        }
    }
}
