#pragma once

// ::Assets::Macros::Header::

#define FILE_VERSION 1

#define CreateMagicValue(a, b, c, d) ((u32)(d << 24) | (u32)(c << 16) | (u32)(b << 8) | (u32)(a))

// ::Assets::Types::Header::

typedef enum AssetType_e : u32
{
	SHADER_ASSET,
	TEXTURE_ASSET,
	SOUND_ASSET,
	MODEL_ASSET,
	ASSET_TYPE_MAX,
} AssetType;

typedef enum ShaderAsset_e : u32
{
	QUAD_FRAG_SPIRV_SHADER,
	QUAD_VERT_SPIRV_SHADER,
	GUI_FRAG_SPIRV_SHADER,
	GUI_VERT_SPIRV_SHADER,
	
	SHADER_ASSET_MAX,
} ShaderAsset;

typedef enum TextureAsset_e : u32
{
	PATTERMON_OBESE,
	PATTERMON_PURPLOID,
	PATTERMON_YUKATA,
	HAMSTER,
	HAMSMOKER,
	CHEESOID,
	HOG,

	TEXTURE_ASSET_MAX
} TextureAsset;

typedef enum TextureAssetTag_e : u32
{
	TEXTURE_ASSET_TAG_MAX,
} TextureAssetTag;

typedef enum SoundAsset_e : u32
{
	SOUND_ASSET_MAX,
} SoundAsset;

typedef enum SoundAssetTag_e : u32
{
	SOUND_ASSET_TAG_MAX,
} SoundAssetTag;

typedef enum ModelAsset_e : u32
{
	MODEL_ASSET_MAX,
} ModelAsset;

typedef enum ModelAssetTag_e : u32
{
	MODEL_ASSET_TAG_MAX,
} ModelAssetTag;

typedef struct TextureAssetMeta
{
	u32 w;
	u32 h;
	u32 ch;
} TextureAssetMeta;

typedef struct ModelAssetMeta
{
	u32 vert_count;
	u32 idx_count;
} ModelAssetMeta;

typedef struct Asset
{
	u8  *bytes;
	u64	len;
} Asset;

typedef struct AssetTag
{
	u32 tag_id;
	f32 value;
} AssetTag;

typedef struct AssetFile
{
	u64 data_offset;
	u64 len;
	union
	{
		TextureAssetMeta texture_meta;
		ModelAssetMeta 	 model_meta;
	};
} AssetFile;

typedef struct FileHeader
{
	u32 magic_num;
	u32 version;

	u32 tag_counts[ASSET_TYPE_MAX];
	u32 asset_counts[ASSET_TYPE_MAX];

	u64 tag_offsets[ASSET_TYPE_MAX];
	u64 asset_offsets[ASSET_TYPE_MAX];
} FileHeader;

// ::Assets::Init::Functions::Header::

static void apInit();

// ::Assets::Loading::Functions::Header::

static Asset apLoadTexture(TextureAsset asset_id);
static Asset apLoadShader(ShaderAsset asset_id);
static TextureAssetMeta apGetTextureMeta(TextureAsset asset_id);
static void apUnloadTexture(TextureAsset asset_id);
static void apUnloadShader(ShaderAsset asset_id);

// ::Assets::Util::Functions::Header::

// TODO(MA): Implement async asset handling
static inline b32 apMarkUnloaded(AssetType type, u32 index);
static inline void apMarkLoaded(AssetType type, u32 index);
