#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
#ifdef _WIN32
#define GLFW_EXPOSE_NATIVE_WIN32
#endif
#include "GLFW/glfw3.h"
#ifdef _WIN32
#include <GLFW/glfw3native.h>
#endif

#ifdef _WIN32
// Windows only lets a process take the foreground if it already owns it,
// or was started by whoever does. Launching from a terminal usually
// satisfies neither, so SetForegroundWindow() is silently ignored and the
// window opens behind the shell. AttachThreadInput() makes the two threads
// share a single input state, which is the attachment SetForegroundWindow()
// looks for. The sharing is mutual, so the argument order is immaterial --
// what matters is that the detach repeats the attach.
static void forceWindowToForeground(GLFWwindow* window)
{
  HWND hwnd = glfwGetWin32Window(window);
  HWND foreground = GetForegroundWindow();
  DWORD foregroundThread = foreground
                               ? GetWindowThreadProcessId(foreground, nullptr)
                               : 0;
  DWORD thisThread = GetCurrentThreadId();
  bool attached = foregroundThread != 0 && foregroundThread != thisThread &&
                  AttachThreadInput(foregroundThread, thisThread, TRUE);
  BringWindowToTop(hwnd);
  SetForegroundWindow(hwnd);
  SetFocus(hwnd);
  if (attached)
  {
    AttachThreadInput(foregroundThread, thisThread, FALSE);
  }
}
#endif

#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 uint32_t msaa = 0;
static bool forceAtomicMode = false;
static bool inkbleed = 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 StrokePosition strokePosition = StrokePosition::center;

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;

void makeContext()
{
  lastWidth = 0;
  lastHeight = 0;

  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;
  }
}

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_R:
        if (shift)
        {
          fiddleContext.reset();
          makeContext();
        }
        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_T: // No good keys available for this
        strokePosition = StrokePosition((uint32_t(strokePosition) + 1) % 3);
        break;
      case GLFW_KEY_F:
        disableFill = !disableFill;
        break;
      case GLFW_KEY_X:
        clockwiseFill = !clockwiseFill;
        break;
      case GLFW_KEY_P:
        if (!shift)
        {
          paused = !paused;
        }
        else
        {
          RIVE_PROF_TOGGLEDRAW();
        }

        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);

  RIVE_PROF_INIT()

#ifdef DEBUG
  options.enableVulkanCoreValidationLayers = 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;
      clockwiseFill = true;
    }
    else if (!strcmp(argv[i], "--glcwib"))
    {
      api = API::gl;
      msaa = 1;
      clockwiseFill = true;
      inkbleed = 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], "--dawncwib"))
    {
      api = API::dawn;
      msaa = 1;
      clockwiseFill = true;
      inkbleed = true;
    }
    else if (!strcmp(argv[i], "--d3d"))
    {
      api = API::d3d;
    }
    else if (!strcmp(argv[i], "--d3d12"))
    {
      api = API::d3d12;
    }
    else if (!strcmp(argv[i], "--d3d12GBV"))
    {
      options.enableValidationLayer = true;
    }
    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], "--vkcwa"))
    {
      api = API::vulkan;
      clockwiseFill = true;
      forceAtomicMode = true;
    }
    else if (!strcmp(argv[i], "--vkcwib"))
    {
      api = API::vulkan;
      msaa = 1;
      clockwiseFill = true;
      inkbleed = 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 (!strcmp(argv[i], "--cw"))
    {
      clockwiseFill = true;
    }
    else if (sscanf(argv[i], "--msaa%u", &msaa) == 1)
    {
      // Already updated msaa
    }
    else if (!strcmp(argv[i], "--core"))
    {
      options.coreFeaturesOnly = true;
    }
    else if (!strcmp(argv[i], "--validation"))
    {
      options.enableVulkanCoreValidationLayers = 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, 24);
  }
  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;
  }
  // Create hidden, then show. GLFW_FOCUS_ON_SHOW only applies to a
  // hidden->visible transition, so with the default (visible) the show
  // below is a no-op and the window can come up behind the terminal.
  glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
  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);
  // Windows can still refuse to hand over the foreground, so ask
  // explicitly as well.
  glfwFocusWindow(window);
#ifdef _WIN32
  forceWindowToForeground(window);
#endif

  makeContext();

  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)
  {
    if (inkbleed)
    {
      title << " (inkbleed)";
    }
    else
    {
      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_L(0)

#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,
      .inkbleedOverride = inkbleed,
  });

  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);
      strokePaint->strokePosition(strokePosition);

      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;
    }
  }
}
