
func TypeToPacketIdentifier(d proto_base.Direction, s proto_base.State, t any) (i string) {
	switch d {
	case proto_base.ToServer:
		switch s {
		case proto_base.Handshaking:
			i = HandshakingToServerTypeToPacketIdentifier(t)
		case proto_base.Status:
			i = StatusToServerTypeToPacketIdentifier(t)
		case proto_base.Login:
			i = LoginToServerTypeToPacketIdentifier(t)
		case proto_base.Configuration:
			i = ConfigurationToServerTypeToPacketIdentifier(t)
		case proto_base.Play:
			i = PlayToServerTypeToPacketIdentifier(t)
		}
	case proto_base.ToClient:
		switch s {
		case proto_base.Handshaking:
			i = HandshakingToClientTypeToPacketIdentifier(t)
		case proto_base.Status:
			i = StatusToClientTypeToPacketIdentifier(t)
		case proto_base.Login:
			i = LoginToClientTypeToPacketIdentifier(t)
		case proto_base.Configuration:
			i = ConfigurationToClientTypeToPacketIdentifier(t)
		case proto_base.Play:
			i = PlayToClientTypeToPacketIdentifier(t)
		}
	}
	return
}

func PacketIdentifierToType(d proto_base.Direction, s proto_base.State, i string) (t any) {
	switch d {
	case proto_base.ToServer:
		switch s {
		case proto_base.Handshaking:
			t = HandshakingToServerPacketIdentifierToType(i)
		case proto_base.Status:
			t = StatusToServerPacketIdentifierToType(i)
		case proto_base.Login:
			t = LoginToServerPacketIdentifierToType(i)
		case proto_base.Configuration:
			t = ConfigurationToServerPacketIdentifierToType(i)
		case proto_base.Play:
			t = PlayToServerPacketIdentifierToType(i)
		}
	case proto_base.ToClient:
		switch s {
		case proto_base.Handshaking:
			t = HandshakingToClientPacketIdentifierToType(i)
		case proto_base.Status:
			t = StatusToClientPacketIdentifierToType(i)
		case proto_base.Login:
			t = LoginToClientPacketIdentifierToType(i)
		case proto_base.Configuration:
			t = ConfigurationToClientPacketIdentifierToType(i)
		case proto_base.Play:
			t = PlayToClientPacketIdentifierToType(i)
		}
	}
	return
}

func DecodePacket(d proto_base.Direction, s proto_base.State, r io.Reader) (params any, err error) {
	switch d {
	case proto_base.ToServer:
		switch s {
		case proto_base.Handshaking:
			var packet HandshakingToServerPacket
			packet, err = HandshakingToServerPacket{}.Decode(r)
			if err != nil {
				return
			}
			params = packet.Params
		case proto_base.Status:
			var packet StatusToServerPacket
			packet, err = StatusToServerPacket{}.Decode(r)
			if err != nil {
				return
			}
			params = packet.Params
		case proto_base.Login:
			var packet LoginToServerPacket
			packet, err = LoginToServerPacket{}.Decode(r)
			if err != nil {
				return
			}
			params = packet.Params
		case proto_base.Configuration:
			var packet ConfigurationToServerPacket
			packet, err = ConfigurationToServerPacket{}.Decode(r)
			if err != nil {
				return
			}
			params = packet.Params
		case proto_base.Play:
			var packet PlayToServerPacket
			packet, err = PlayToServerPacket{}.Decode(r)
			if err != nil {
				return
			}
			params = packet.Params
		}
	case proto_base.ToClient:
		switch s {
		case proto_base.Handshaking:
			var packet HandshakingToClientPacket
			packet, err = HandshakingToClientPacket{}.Decode(r)
			if err != nil {
				return
			}
			params = packet.Params
		case proto_base.Status:
			var packet StatusToClientPacket
			packet, err = StatusToClientPacket{}.Decode(r)
			if err != nil {
				return
			}
			params = packet.Params
		case proto_base.Login:
			var packet LoginToClientPacket
			packet, err = LoginToClientPacket{}.Decode(r)
			if err != nil {
				return
			}
			params = packet.Params
		case proto_base.Configuration:
			var packet ConfigurationToClientPacket
			packet, err = ConfigurationToClientPacket{}.Decode(r)
			if err != nil {
				return
			}
			params = packet.Params
		case proto_base.Play:
			var packet PlayToClientPacket
			packet, err = PlayToClientPacket{}.Decode(r)
			if err != nil {
				return
			}
			params = packet.Params
		}
	}
	return
}

func EncodePacket(d proto_base.Direction, s proto_base.State, i string, p any, w io.Writer) (err error) {
	switch d {
	case proto_base.ToServer:
		switch s {
		case proto_base.Handshaking:
			err = HandshakingToServerPacket{i, p}.Encode(w)
		case proto_base.Status:
			err = StatusToServerPacket{i, p}.Encode(w)
		case proto_base.Login:
			err = LoginToServerPacket{i, p}.Encode(w)
		case proto_base.Configuration:
			err = ConfigurationToServerPacket{i, p}.Encode(w)
		case proto_base.Play:
			err = PlayToServerPacket{i, p}.Encode(w)
		}
	case proto_base.ToClient:
		switch s {
		case proto_base.Handshaking:
			err = HandshakingToClientPacket{i, p}.Encode(w)
		case proto_base.Status:
			err = StatusToClientPacket{i, p}.Encode(w)
		case proto_base.Login:
			err = LoginToClientPacket{i, p}.Encode(w)
		case proto_base.Configuration:
			err = ConfigurationToClientPacket{i, p}.Encode(w)
		case proto_base.Play:
			err = PlayToClientPacket{i, p}.Encode(w)
		}
	}
	return
}
