#include "artboard.hpp"
#include "file.hpp"
#include "layout.hpp"
#include "animation/linear_animation_instance.hpp"
#include "low_level/low_level_renderer.hpp"
#include <string.h>

#if __APPLE__
#define GLFW_EXPOSE_NATIVE_COCOA
#endif

#include "graphics_api.hpp"

// Make sure gl3w is included before glfw3
// #include "GL/gl3w.h"
#include "GLFW/glfw3.h"
#include "GLFW/glfw3native.h"

#include <stdio.h>

void* viewerNativeWindowHandle = nullptr;

int main(int argc, const char** argv)
{
	auto graphicsApi = rive::GraphicsApi::unknown;
	if (argc >= 2)
	{
		// Figure out if the user requested a specific Graphics API.
		const char* deviceName = argv[1];
		if (strcmp(deviceName, "gl") == 0 || strcmp(deviceName, "opengl") == 0)
		{
			graphicsApi = rive::GraphicsApi::opengl;
		}
		else if (strcmp(deviceName, "mtl") == 0 ||
		         strcmp(deviceName, "metal") == 0)
		{
			graphicsApi = rive::GraphicsApi::metal;
		}
		else if (strcmp(deviceName, "vk") == 0 ||
		         strcmp(deviceName, "vulkan") == 0)
		{
			graphicsApi = rive::GraphicsApi::vulkan;
		}
		else if (strcmp(deviceName, "d3d11") == 0)
		{
			graphicsApi = rive::GraphicsApi::d3d11;
		}
		else if (strcmp(deviceName, "d3d12") == 0)
		{
			graphicsApi = rive::GraphicsApi::d3d12;
		}
	}

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

	if (graphicsApi == rive::GraphicsApi::opengl)
	{
		glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API);
		glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
		glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
		glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
		glfwWindowHint(GLFW_SAMPLES, 16);
	}
	else
	{
		glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
	}

	GLFWwindow* window = glfwCreateWindow(640, 480, "Rive", nullptr, nullptr);
	if (!window)
	{
		glfwTerminate();
		fprintf(stderr, "Failed to create window.\n");
		return -1;
	}

#ifdef __APPLE__
	glfwMakeContextCurrent(window);
	viewerNativeWindowHandle = static_cast<void*>(glfwGetCocoaWindow(window));
#endif

	// If no specific API requested, big the default one for the platform.
	rive::LowLevelRenderer* renderer =
	    graphicsApi == rive::GraphicsApi::unknown
	        ? rive::GraphicsApi::makeRenderer()
	        : rive::GraphicsApi::makeRenderer(graphicsApi);

	if (renderer == nullptr || !renderer->initialize())
	{
		return 1;
	}

	char windowTitle[128];
	snprintf(windowTitle,
	         128,
	         "Rive Low Level Renderer (%s)",
	         rive::GraphicsApi::name(renderer->type()));
	glfwSetWindowTitle(window, windowTitle);

	// Load a rive file
	uint8_t* fileBytes = nullptr;
	unsigned int fileBytesLength = 0;

	// std::string filename = "assets/polygon_party.riv";
	// std::string filename = "assets/triangle.riv";
	// std::string filename = "assets/juice.riv";
	// std::string filename = "assets/clip.riv";
	// std::string filename = "assets/clipped_circle_star_2.riv";
	std::string filename = "assets/marty.riv";
	// std::string filename = "assets/off_road_car.riv";
	// std::string filename = "assets/simple_stroke.riv";
	// std::string filename = "assets/leg_issues.riv";
	// std::string filename = "assets/control.riv";
	// std::string filename = "assets/stroke_caps.riv";
	FILE* fp = fopen(filename.c_str(), "r");
	fseek(fp, 0, SEEK_END);
	fileBytesLength = ftell(fp);
	fseek(fp, 0, SEEK_SET);
	delete[] fileBytes;
	fileBytes = new uint8_t[fileBytesLength];
	if (fread(fileBytes, 1, fileBytesLength, fp) != fileBytesLength)
	{
		delete[] fileBytes;
		fprintf(stderr, "failed to read all of %s\n", filename.c_str());
		return 1;
	}
	auto reader = rive::BinaryReader(fileBytes, fileBytesLength);
	rive::File* file = nullptr;
	auto result = rive::File::import(reader, &file);
	if (result != rive::ImportResult::success)
	{
		delete[] fileBytes;
		fprintf(stderr, "failed to import file\n");
		return 1;
	}

	rive::Artboard* artboard = file->artboard();
	artboard->advance(0.0f);

	rive::LinearAnimationInstance* animationInstance = nullptr;
	int animationIndex = 0;
	auto animation =
	    animationIndex >= 0 && animationIndex < artboard->animationCount()
	        ? artboard->animation(animationIndex)
	        : nullptr;
	if (animation != nullptr)
	{
		animationInstance = new rive::LinearAnimationInstance(animation);
	}

	double lastTime = glfwGetTime();
	int lastWidth = 0, lastHeight = 0;
	float projection[16] = {0.0f};
	while (!glfwWindowShouldClose(window))
	{
		int width = 0, height = 0;
		glfwGetFramebufferSize(window, &width, &height);

		if (lastWidth != width || lastHeight != height)
		{
			lastWidth = width;
			lastHeight = height;
			renderer->orthographicProjection(
			    projection, 0.0f, width, height, 0.0f, 0.0f, 1.0f);
			renderer->modelViewProjection(projection);
		}

		double time = glfwGetTime();
		float elapsed = (float)(time - lastTime);
		lastTime = time;

		renderer->startFrame();

		if (artboard != nullptr)
		{
			if (animationInstance != nullptr)
			{
				animationInstance->advance(elapsed);
				animationInstance->apply(artboard);
			}
			artboard->advance(elapsed);
			renderer->save();
			renderer->align(rive::Fit::contain,
			                rive::Alignment::center,
			                rive::AABB(0, 0, width, height),
			                artboard->bounds());
			artboard->draw(renderer);
			renderer->restore();
		}

		renderer->endFrame();

#if __APPLE__
		glfwSwapBuffers(window);
#endif
		glfwPollEvents();
	}

	glfwTerminate();
	return 0;
}