#pragma once

// Custom Classes
#include "CDTable.h"

// Tables
#include "CDActivityRewardsTable.h"
#include "CDAnimationsTable.h"
#include "CDBehaviorParameterTable.h"
#include "CDBehaviorTemplateTable.h"
#include "CDComponentsRegistryTable.h"
#include "CDCurrencyTableTable.h"
#include "CDDestructibleComponentTable.h"
#include "CDEmoteTable.h"
#include "CDInventoryComponentTable.h"
#include "CDItemComponentTable.h"
#include "CDItemSetsTable.h"
#include "CDItemSetSkillsTable.h"
#include "CDLevelProgressionLookupTable.h"
#include "CDLootMatrixTable.h"
#include "CDLootTableTable.h"
#include "CDMissionNPCComponentTable.h"
#include "CDMissionTasksTable.h"
#include "CDMissionsTable.h"
#include "CDObjectSkillsTable.h"
#include "CDObjectsTable.h"
#include "CDPhysicsComponentTable.h"
#include "CDRebuildComponentTable.h"
#include "CDScriptComponentTable.h"
#include "CDSkillBehaviorTable.h"
#include "CDZoneTableTable.h"
#include "CDVendorComponentTable.h"
#include "CDActivitiesTable.h"
#include "CDPackageComponentTable.h"
#include "CDProximityMonitorComponentTable.h"
#include "CDMovementAIComponentTable.h"
#include "CDBrickIDTableTable.h"
#include "CDRarityTableTable.h"
#include "CDMissionEmailTable.h"
#include "CDRewardsTable.h"
#include "CDPropertyEntranceComponentTable.h"
#include "CDPropertyTemplateTable.h"
#include "CDFeatureGatingTable.h"
#include "CDRailActivatorComponent.h"

// C++
#include <type_traits>
#include <unordered_map>

/*!
  \file CDClientManager.hpp
  \brief A manager for the CDClient tables
 */

 //! Manages all data from the CDClient
class CDClientManager {
private:
	static CDClientManager* m_Address;                 //!< The singleton address

	std::unordered_map<std::string, CDTable*> tables;   //!< The tables

public:

	//! The singleton method
	static CDClientManager* Instance() {
		if (m_Address == 0) {
			m_Address = new CDClientManager;
		}

		return m_Address;
	}

	//! Initializes the manager
	void Initialize(void);

	//! Fetches a CDClient table
	/*!
	  This function uses typename T which must be a subclass of CDTable.
	  It returns the class that conforms to the class name

	  \param tableName The table name
	  \return The class or nullptr
	 */
	template<typename T>
	T* GetTable(const std::string& tableName) {
		static_assert(std::is_base_of<CDTable, T>::value, "T should inherit from CDTable!");

		for (auto itr = this->tables.begin(); itr != this->tables.end(); ++itr) {
			if (itr->first == tableName) {
				return dynamic_cast<T*>(itr->second);
			}
		}

		return nullptr;
	}
};