#ifndef _MINECRAFT_NETWORK_PACKET_H_
#define _MINECRAFT_NETWORK_PACKET_H_

#include "NetEventCallback.h"

#include "../raknet/MessageIdentifiers.h"
#include "../raknet/RakNetTypes.h"
#include "../raknet/BitStream.h"
#include "../raknet/PacketPriority.h"

class LevelChunk;


enum MinecraftPacketIds
{
	PACKET_KEEPALIVE = 0,

	PACKET_LOGIN,
	PACKET_LOGINSTATUS,
	PACKET_READY,

	PACKET_MESSAGE,
	PACKET_SETTIME,

	PACKET_STARTGAME,

	PACKET_ADDMOB,
	PACKET_ADDPLAYER,
	PACKET_REMOVEPLAYER,
	PACKET_TELEPORTENTITY,

	PACKET_ADDENTITY,
	PACKET_REMOVEENTITY,
	PACKET_ADDITEMENTITY,
	PACKET_TAKEITEMENTITY,

	PACKET_MOVEENTITY,
	PACKET_MOVEENTITY_POS,
	PACKET_MOVEENTITY_ROT,
	PACKET_MOVEENTITY_POSROT,
	PACKET_MOVEPLAYER,

	PACKET_PLACEBLOCK,
	PACKET_REMOVEBLOCK,
	PACKET_UPDATEBLOCK,

	PACKET_ADDPAINTING,

	PACKET_EXPLODE,

	PACKET_LEVELEVENT,
	PACKET_TILEEVENT,
	PACKET_ENTITYEVENT,

	PACKET_REQUESTCHUNK,
	PACKET_CHUNKDATA,

	PACKET_PLAYEREQUIPMENT,
	PACKET_PLAYERARMOREQUIPMENT,
	PACKET_INTERACT,
	PACKET_USEITEM,
	PACKET_PLAYERACTION,
	PACKET_UPDATEARMOR,
	PACKET_HURTARMOR,

	PACKET_SETENTITYDATA,
	PACKET_SETENTITYMOTION,
	PACKET_SETHEALTH,
	PACKET_SETSPAWNPOSITION,

	PACKET_ANIMATE,
	PACKET_RESPAWN,

	PACKET_SENDINVENTORY,
	PACKET_DROPITEM,

	PACKET_CONTAINEROPEN,
	PACKET_CONTAINERCLOSE,
	PACKET_CONTAINERSETSLOT,
	PACKET_CONTAINERSETDATA,
	PACKET_CONTAINERSETCONTENT,
	PACKET_CONTAINERACK,

	PACKET_CHAT,
	PACKET_SIGNUPDATE,

	PACKET_ADVENTURESETTINGS,
/*
	PACKET_PRELOGIN,
	PACKET_CHAT,
	PACKET_SETEQUIPPEDITEM,
	PACKET_SETSPAWNPOSITION,

	PACKET_PLAYERACTION,
	PACKET_SETCARRIEDITEM,
	PACKET_ENTITYACTIONATPOSITION,
	PACKET_PLAYERCOMMAND,

	PACKET_ADDENTITY,
	PACKET_ADDMOB,
	PACKET_ADDPAINTING,
	PACKET_PLAYERINPUT,
	PACKET_SETENTITYMOTION,
	PACKET_REMOVEENTITY,

	PACKET_MOVEENTITY,
	PACKET_SETRIDING,
	PACKET_ENTITYDATA,

	PACKET_CHUNKVISIBILITY,
	PACKET_BLOCKREGIONUPDATE,
	PACKET_CHUNKBLOCKUPDATE,
	PACKET_BLOCKUPDATE,
	PACKET_BLOCKEVENT,

	PACKET_GAMEEVENT,
	PACKET_ADDGLOBALENTITY,

	PACKET_CONTAINEROPEN,
	PACKET_CONTAINERCLOSE,
	PACKET_CONTAINERCLICK,
	PACKET_CONTAINERSETSLOT,
	PACKET_CONTAINERSETCONTENT,
	PACKET_CONTAINERSETDATA,
	PACKET_CONTAINERACK,

	PACKET_SIGNUPDATE,
	PACKET_AWARDSTAT,

	PACKET_DISCONNECT,
	*/

	PACKET_END_ID
};


const int NUM_PACKETS = PACKET_END_ID;

class Packet
{
public:
	Packet();
	virtual ~Packet() {}

	virtual void write(RakNet::BitStream* bitStream) = 0;
	virtual void read(RakNet::BitStream* bitStream) = 0;

	virtual void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback) = 0;

	PacketPriority priority;
	PacketReliability reliability;
};


class MinecraftPackets
{
public:

	static Packet* createPacket(int id);

};

namespace PacketUtil {
	signed char  Rot_degreesToChar(float rot);
	float Rot_charToDegrees(signed char rot);
	void Rot_entityToChar(const Entity* e, signed char& yRot, signed char& xRot);
	void Rot_charToEntity(Entity* e, signed char yRot, signed char xRot);

	void writeItemInstance(const ItemInstance& item, RakNet::BitStream* stream);
	ItemInstance readItemInstance(RakNet::BitStream* stream);
}

#endif
