#pragma once

#include "ManagerSerializableNetMsgMap.h"
#include "NetMessengerStreamBuffer.h"
#include <string>
#include <string_view>
#include "AftrUtil_string.h"

namespace Aftr
{

#define NetMsgMacroDeclaration( className ) \
   \
   /** Returns a string containing the actual name of this class */ \
   virtual std::string getClassName() const \
   { \
      return std::string( #className ); \
   } \
   static consteval std::string_view getClassName_consteval() \
   { \
      return #className; \
   } \
   \
   static NetMsg* createFromStream( NetMessengerStreamBuffer& is ); \
   \
   virtual unsigned int getNetMsgID() const \
   { \
      return ManagerSerializableNetMsgMap::getNetMsgID( #className ); \
   } \
   \
   static consteval unsigned int getNetMsgID_consteval() \
   { \
      /* uses fnv1a hashing method to convert the class name to an ID which is the NetMsgID for this NetMsg */ \
      return hash_str_fnv1a_consteval_32_bit( #className ); \
   } \
   \
   class NetMsg_Serializable##className##Map \
   { \
      public: /*Declares stub class that registers fromFile function pointer w/ manager */ \
      NetMsg_Serializable##className##Map() \
      { \
         ManagerSerializableNetMsgMap::registerNetMsgType( #className, &(className::createFromStream) ); \
      } \
   }; \
   \
   typedef className ThisClassType; /* Refers to the actual class declared*/


#define NetMsgMacroDefinition( className ) \
   className::NetMsg_Serializable##className##Map instanceWO_Serializeable##className##Map; \
   typedef className ThisClassType; /* Refers to the actual class declared*/ \
   \
   NetMsg* ThisClassType::createFromStream( NetMessengerStreamBuffer& is ) \
   { \
      ThisClassType* msg = new ThisClassType(); \
      if( msg->fromStream( is ) ) \
         return msg; \
      delete msg; msg = nullptr; \
      return nullptr; \
   }
   

} //namespace Aftr

