#ifndef MATERIALS_COMMONS_GEOMETRY_INFORMATION_H
#define MATERIALS_COMMONS_GEOMETRY_INFORMATION_H

const uint GAT_Coord        = 0; // Vector3
const uint GAT_Normal       = 1; // Vector3
const uint GAT_Albedo       = 2; // Vector3
const uint GAT_UV0          = 3; // Vector2
const uint GAT_UV1          = 4; // Vector2
const uint GAT_BonesWeights = 5; // 4x<uint16,uint16> = 16 bytes
const uint GAT_Custom0      = 6; // 1x<any32>
const uint GAT_Custom1      = 7; // 1x<any32>
const uint GAT_Last         = 8;

const uint GAT_Coord_Mask        = 1 << GAT_Coord;
const uint GAT_Normal_Mask       = 1 << GAT_Normal;
const uint GAT_Albedo_Mask       = 1 << GAT_Albedo;
const uint GAT_UV0_Mask          = 1 << GAT_UV0;
const uint GAT_UV1_Mask          = 1 << GAT_UV1;
const uint GAT_BonesWeights_Mask = 1 << GAT_BonesWeights;
const uint GAT_Custom0_Mask      = 1 << GAT_Custom0;
const uint GAT_Custom1_Mask      = 1 << GAT_Custom1;

struct GeometryInformationAttribute
{
	// usually these attributes live in separate buffers, but we really need dynamic meshes where memory is allocated from the GPU side
	uint offset;			// in uint32
	uint stride;			// in uint32
	uint _pad0;
	uint _pad1;
};

struct GeometryInformation
{
	uint vtx_num;
	uint surfaces_num;
	uint builtin_attribute_mask;
	uint flipbook_cards_num;
	
	uint idx_buffer_offset;					// in uint32. we need this for index buffers allocated on GPU.
											// when generating indirect drawcalls this is filled in as start_index value.
											// attribute fetching still needs to account for each attribute's offset because they are allocated from single buffer

	uint is_gpu_allocated;					// when true means it was created on the GPU
	uint gpu_memory_allocation_size;		// for debugging
	uint gpu_memory_allocation_size_total;	// for debugging

	uint aux_tracking_0;
	uint aux_tracking_1;
	uint aux_tracking_2;
	uint aux_tracking_3;

	GeometryInformationAttribute attributes[GAT_Last];
	uint faces_num_per_surface[64];		// don't pass via uniform buffer until we can get rid of packing
};

GeometryInformationAttribute GeometryInformationAttributeGetDefault(uint gat)
{
	GeometryInformationAttribute gia;
	gia.stride =  0;
	gia.offset = -1;

	// stride is in u32/f32
	if (gat == GAT_Coord)
		gia.stride = 3;
	if (gat == GAT_Normal)
		gia.stride = 3;
	if (gat == GAT_Albedo)
		gia.stride = 3;
	if (gat == GAT_UV0)
		gia.stride = 2;
	if (gat == GAT_UV1)
		gia.stride = 2;
	if (gat == GAT_BonesWeights)
		gia.stride = 2; // 4 * u16
	if (gat == GAT_Custom0)
		gia.stride = 1;
	if (gat == GAT_Custom1)
		gia.stride = 1;

	return gia;
}

#define GAT_Normal_Default vec3(0.0, 0.0, 1.0)
#define GAT_Albedo_Default vec3(1.0, 1.0, 1.0)
#define GAT_Custom0_Default uint(0)


#endif // MATERIALS_COMMONS_GEOMETRY_INFORMATION_H
