#ifndef ROGUE_RENDERER_H
#define ROGUE_RENDERER_H

#include "roguedefs.h"
#include <SDL2/SDL_render.h>
#include <SDL2/SDL_stdinc.h>
#include <SDL2/SDL_video.h>
#include <filesystem>
#include <optional>
#include <vector>

namespace rogue {
// Contains all data required to render the game world
class RenderData {
	friend class RenderDataSetup;
	friend class Render;
public: ~RenderData();
private: RenderData() = default;
	SDL_Window *window{nullptr};
	SDL_Renderer *renderer{nullptr};
	std::vector<SDL_Texture*> sprites{};
};

// Global interface for rendering
class Render {
private:
	friend class RenderData;
	static void clear_render_data();
public:
	static void provide_render_data(RenderData &data);

	static void clear(Tile camera_center, unsigned fov = 10);
	static void draw(Tile world_space_tile, Sprite sprite);
	static void present();
private:
	static Tile camera_center;
	static unsigned camera_width;
	static Tile camera_offset;
	static int tile_screen_width;
	static int half_tile_screen_width;
	static RenderData *data;
};

// Render configuration, builder for RenderData
class RenderDataSetup {
public:
	RenderDataSetup() = default;
	RenderDataSetup &with_window(char const *name, Uint32 flags);
	RenderDataSetup &with_renderer(Uint32 flags);
	RenderDataSetup &with_resource_path(std::filesystem::path base_path);
	RenderDataSetup &with_sprite(std::filesystem::path sprite_path);
	RenderData build();
private:
	unsigned fov{10};
	std::optional<std::filesystem::path> resource_base_path;
	SDL_Window *window{nullptr};
	SDL_Renderer *renderer{nullptr};
	std::vector<SDL_Texture*> sprites{};
};
}

#endif // !ROGUE_RENDERER_H
