#pragma once
#include <cstdint>
#include <string>
#include <vector>
#include "font.h"
#include "rect.h"
#include "resource.h"
#include "vec2.h"

using color = uint32_t;
struct ini;

enum class upscaler {
	none, scale2x, scale3x, lcd3x, rgb3x, bilinear3x, hatch3x
};

int upscaler_scale(upscaler upscaler);

std::tuple<double, double, double, double> color_to_elements(color color);
color elements_to_color(double r, double g, double b, double a);

struct image : resource {
	image(resource_manager& rm, ini_category const* ini, std::string const& path, std::vector<uint8_t> const& data);
	image(image const& other);
	image(vec2i size);
	image(vec2i size, color* data);
	~image();
	//static image_from_pointer()

	vec2i const& size() const;
	recti const& bounds() const;

	color* raw_pointer() const;
	color get(vec2i pos) const;
	color get_safe(vec2i pos) const;

	void clear(color color);
	void blend_to(color color, double amount);

	void draw(image const* image, vec2i pos);
	void draw(image const* image, vec2i pos, recti src_rect);
	void draw(image const* image, vec2i pos, color color);
	void draw(image const* image, vec2i pos, color color, recti src_rect);

	void draw_rot(image const* image, vec2i pos, double rot);
	void draw_rot(image const* image, vec2i pos, recti src_rect, double rot);

	void draw_upscaled(image const* image, upscaler upscaler);
	void draw_upscaled(image const* image, std::vector<upscaler> upscalers);

	void draw(std::string const& str, vec2i pos, font const* font, color color);
	void draw(std::string const& str, vec2i pos, font const* font, color color1, color color2);
private:
	void draw_upscaled(image const* image, vec2i size, upscaler upscaler);
	bool _alpha;
	bool _borrowed_pointer; //to know if to free or not
	color* _data; //not a vector so can wrap sdl surfaces
	recti _bounds;
};
