/******************************************************************************
*	File		-	asset_index.h
*	Author		-	Joey Pollack
*	Date		-	2021/10/25 (y/m/d)
*	Mod Date	-	2021/10/25 (y/m/d)
*	Description	-	Loads and stores the index.dat file. Allows querying
*                   the asset index by asset ID or name.
******************************************************************************/

#include "asset_index.h"
#include <utils/binary_file_buffer.h>

namespace lunarium
{
    AssetIndex* AssetIndex::mpInstance = nullptr;

    AssetIndex::AssetIndex()
    {
    }

    AssetIndex& AssetIndex::GetInstance()
    {
        if (!mpInstance)
        {
            mpInstance = new AssetIndex;
        }

        return *mpInstance;
    }
    
    void AssetIndex::FreeInstance()
    {
        for (auto iter = mpInstance->mAssets.begin(); iter != mpInstance->mAssets.end(); iter++)
        {
            delete iter->second;
        }

        mpInstance->mAssets.clear();
        mpInstance->mAssetsByName.clear();

        delete mpInstance;
        mpInstance = nullptr;
    }
    

    OpRes AssetIndex::LoadIndex(const char* filename)
    {
        BinaryFileBuffer buffer;
        if (!buffer.LoadFile(filename))
        {
            return OpRes::Fail("AssetIndex::LoadIndex - unable to load file: %s", filename);
        }

        int32_t num_assets = 0;
        buffer.Read((char*) &num_assets, 4);

        char str_buf[512];

        for (int i = 0; i < num_assets; i++)
        {
            AssetInfo* pAI = new AssetInfo;
            buffer.Read((char*) &pAI->ID, 4);

            int16_t name_size = 0;
            buffer.Read((char*) &name_size, 2);
            buffer.Read(str_buf, name_size);
            pAI->Name = str_buf;

            buffer.Read((char*) &pAI->Type, 2);
            buffer.Read((char*) &name_size, 2);
            buffer.Read(str_buf, name_size);
            pAI->File = str_buf;

            buffer.Read((char*) &pAI->Offset, 4);

            mAssets[pAI->ID] = pAI;
            mAssetsByName[pAI->Name] = pAI;
        }

        buffer.Unload();

        return OpRes::OK();
    }
    
    const AssetIndex::AssetInfo* AssetIndex::GetAssetInfo(int id) const
    {
        auto res = mAssets.find(id);
        if (res != mAssets.end())
        {
            return res->second;
        }
        
        return nullptr;
    }

    const AssetIndex::AssetInfo* AssetIndex::GetAssetInfo(const char* name) const
    {
        auto res = mAssetsByName.find(name);
        if (res != mAssetsByName.end())
        {
            return res->second;
        }

        return nullptr;
    }
}