#pragma once

// C++
#include <functional>
#include <vector>
#include <stdint.h>

/*!
  \file ObjectIDManager.hpp
  \brief A manager for handling object ID generation
 */

 //! The persistent ID request
struct PersistentIDRequest {
	uint64_t requestID;

	std::function<void(uint32_t)> callback;
};

//! The Object ID Manager
class ObjectIDManager {
private:
	static ObjectIDManager* m_Address;         //!< The singleton instance

	std::vector<PersistentIDRequest*> requests; //!< All outstanding persistent ID requests
	uint64_t currentRequestID;                  //!< The current request ID

	uint32_t currentObjectID;                   //!< The current object ID

public:

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

		return m_Address;
	}

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

	//! Requests a persistent ID
	/*!
	  \param callback The callback function
	 */
	void RequestPersistentID(std::function<void(uint32_t)> callback);


	//! Handles a persistent ID response
	/*!
	  \param requestID The request ID
	  \param persistentID The persistent ID
	 */
	void HandleRequestPersistentIDResponse(uint64_t requestID, uint32_t persistentID);

	//! Generates an object ID server-sided
	/*!
	  \return A generated object ID
	 */
	uint32_t GenerateObjectID(void);

	//! Generates a random object ID server-sided
	/*!
	 \return A generated object ID
	 */
	static uint32_t GenerateRandomObjectID();

	//! Generates a persistent object ID server-sided
	/*!
	  \return A generated object ID
	 */
	uint32_t GeneratePersistentObjectID(void);
};