#ifndef _H_INSTANCEDRAW_H
#define _H_INSTANCEDRAW_H

#include <vector>
#include <glm/glm.hpp>
#include <thirdparty/glad/glad.h>
#include <cstring>

#define MAX_INSTANCES 1000
#define MAX_TEXTURES 31

class Texture;
class TextureArray;

struct InstanceData {
	glm::mat4 modelMatrix;
	glm::vec2 originalSize;
	int tileIndex = 0;
	int textureIndex = 0;
	int tilesPerRow = 0;
	int startID = 0;
};

class BaseInstanceDraw
{
public:
	virtual ~BaseInstanceDraw() {}

	virtual void setup() = 0;
	virtual void updateInstanceData(const std::vector<InstanceData>&) = 0;
	virtual void draw() = 0;
protected:
	unsigned VAO, VBO, EBO, instanceVBO;
	Texture* texture = nullptr;
	InstanceData instanceData[MAX_INSTANCES];
	size_t numOfInstances = 0;
	unsigned indices[6] = {
		0, 1, 2,
		3, 2, 0
	};
};

class TileTextureInstance : public BaseInstanceDraw
{
public:
	TileTextureInstance(const char* texturePath);
	TileTextureInstance(const std::vector<const char*> texturePaths);

	void updateInstanceData(const std::vector<InstanceData>&) override;
	void draw() override;

	const TextureArray* getTextureArray() { return textures; }
	const Texture* getTexture() { return texture; }

	~TileTextureInstance();

private:
	void setup() override;
	TextureArray* textures = nullptr;
	float vertices[20] = {
		// vertex		  
		-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, // bottom left
		 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, // bottom right
		 0.5f,  0.5f, 0.0f, 1.0f, 1.0f, // top right
		-0.5f,  0.5f, 0.0f, 0.0f, 1.0f  // top left
	};
};

#endif // _H_INSTANCEDRAW_H
