#pragma once

#include "dCommonVars.h"
#include <unordered_map>
#include "Singleton.h"
#include <vector>

class Entity;

struct RarityTableEntry {
	uint32_t rarity;
	float randMax;
};

typedef std::vector<RarityTableEntry> RarityTable;

struct LootMatrixEntry {
	uint32_t lootTableIndex;
	uint32_t rarityTableIndex;
	float percent;
	uint32_t minDrop;
	uint32_t maxDrop;
};

typedef std::vector<LootMatrixEntry> LootMatrix;

struct LootTableEntry {
	LOT itemID;
	bool isMissionDrop;
};

typedef std::vector<LootTableEntry> LootTable;

// used for glue code with Entity and Player classes
namespace Loot {
	struct Info {
		LWOOBJID id;
		LOT lot;
		uint32_t count;
	};
}


class LootGenerator : public Singleton<LootGenerator> {
public:
	LootGenerator();

	std::unordered_map<LOT, int32_t> RollLootMatrix(Entity* player, uint32_t matrixIndex);
	std::unordered_map<LOT, int32_t> RollLootMatrix(uint32_t matrixIndex);
	void GiveLoot(Entity* player, uint32_t matrixIndex, eLootSourceType lootSourceType = eLootSourceType::NONE);
	void GiveLoot(Entity* player, std::unordered_map<LOT, int32_t>& result, eLootSourceType lootSourceType = eLootSourceType::NONE);
	void GiveActivityLoot(Entity* player, Entity* source, uint32_t activityID, int32_t rating = 0);
	void DropLoot(Entity* player, Entity* killedObject, uint32_t matrixIndex, uint32_t minCoins, uint32_t maxCoins);
	void DropLoot(Entity* player, Entity* killedObject, std::unordered_map<LOT, int32_t>& result, uint32_t minCoins, uint32_t maxCoins);
	void DropActivityLoot(Entity* player, Entity* source, uint32_t activityID, int32_t rating = 0);

private:
	std::unordered_map<uint32_t, uint8_t> m_ItemRarities;
	std::unordered_map<uint32_t, RarityTable> m_RarityTables;
	std::unordered_map<uint32_t, LootMatrix> m_LootMatrices;
	std::unordered_map<uint32_t, LootTable> m_LootTables;
};