#ifndef SHADER_H
#define SHADER_H

#include <stdint.h>
#include <glad/glad.h>

const int SHADERUNIFORM_MAX_COUNT = 16;
const int INPUT_LAYOUT_MAX_COUNT = 8;

enum VertexAttribute_t {
	VERTEXATTR_VEC2,
	VERTEXATTR_VEC3,
	VERTEXATTR_VEC4,

	VERTEXATTR_MAX
};

enum ShaderSemantic_t {
	SHADERSEMANTIC_POSITION,
	SHADERSEMANTIC_COLOR,
	SHADERSEMANTIC_TEXCOORD,
	SHADERSEMANTIC_TEXCOORD0,
	SHADERSEMANTIC_TEXCOORD1,
	SHADERSEMANTIC_NORMAL,
	SHADERSEMANTIC_TANGENT,
	SHADERSEMANTIC_BITANGENT,

	SHADERSEMANTIC_MAX
};

enum ShaderUniformType_t {
	SHADERUNIFORM_FLOAT,
	SHADERUNIFORM_VEC2,
	SHADERUNIFORM_VEC3,
	SHADERUNIFORM_VEC4,
	SHADERUNIFORM_MAT4,

	SHADERUNIFORM_MAX
};

struct InputLayoutDesc_t {
	VertexAttribute_t attribute;
	ShaderSemantic_t semantic;
};

struct ShaderUniformDesc_t {
	ShaderUniformType_t type;
	const char* name;
	size_t size;
};

class Shader
{
public:
	Shader();
	~Shader();

	void Create(const char* name, const char* vsfilepath, const char* psfilepath);
	void Destroy();

	void AllocateAttributes();

public:
	// TEMP SOLUTION
	ShaderUniformDesc_t m_uniform_desc[SHADERUNIFORM_MAX_COUNT];
	size_t m_uniform_count;

	InputLayoutDesc_t m_layouts[INPUT_LAYOUT_MAX_COUNT];
	size_t m_layout_count;

	GLuint m_glLayouts[INPUT_LAYOUT_MAX_COUNT];

	// #TODO: REMOVE PLEASE
	int m_stride;

	const char* m_name;

	GLuint m_program;
};

inline int GetVertexAttributeSize( VertexAttribute_t attrib )
{
	switch ( attrib )
	{
	case VERTEXATTR_VEC2:
		return 2;
	case VERTEXATTR_VEC3:
		return 3;
	case VERTEXATTR_VEC4:
		return 4;
	default:
		break;
	}

	return 0;
}

#endif // !SHADER_H
