/*
 * Original project: RedEnvelope by KaguyaStudio-MC
 * Original project link: https://github.com/KaguyaStudio-MC/RedEnvelope
 * Modified by: LeisureTimeDock
 * This file is part of RedEnvelope
 * Licensed under Camellia License Version 1.0
 */

package top.leisuretimedock.redenvelope.core.network;

import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer;
import net.minecraftforge.network.NetworkDirection;
import net.minecraftforge.network.NetworkRegistry;
import net.minecraftforge.network.PacketDistributor;
import net.minecraftforge.network.simple.SimpleChannel;
import top.leisuretimedock.redenvelope.RedEnvelope;

public class RENetworkHandler {
    private static int cid = 0;
    /**
     * The constant INSTANCE.
     */
    public static final SimpleChannel INSTANCE = NetworkRegistry.newSimpleChannel(
            new ResourceLocation(RedEnvelope.MOD_ID, "main"),
            () -> RedEnvelope.ModInfo.VERSION,
            RedEnvelope.ModInfo.VERSION::equals,
            RedEnvelope.ModInfo.VERSION::equals
    );
    public static void register() {
        INSTANCE.messageBuilder(RedEnvelopePacket.class, cid++)
                .decoder(RedEnvelopePacket::decode)
                .encoder(RedEnvelopePacket::encode)
                .consumerMainThread(RedEnvelopePacket::handle)
                .add();
        INSTANCE.messageBuilder(SyncREStoragePacket.class, cid++, NetworkDirection.PLAY_TO_CLIENT)
                .decoder(SyncREStoragePacket::decode)
                .encoder(SyncREStoragePacket::encode)
                .consumerMainThread(SyncREStoragePacket::handle)
                .add();
        INSTANCE.messageBuilder(OpenRedEnvelopePacket.class, cid++, NetworkDirection.PLAY_TO_SERVER)
                .decoder(OpenRedEnvelopePacket::decode)
                .encoder(OpenRedEnvelopePacket::encode)
                .consumerMainThread(OpenRedEnvelopePacket::handle)
                .add();
        INSTANCE.messageBuilder(PlaySoundToClientPacket.class, cid++, NetworkDirection.PLAY_TO_CLIENT)
                .decoder(PlaySoundToClientPacket::decode)
                .encoder(PlaySoundToClientPacket::encode)
                .consumerMainThread(PlaySoundToClientPacket::handle)
                .add();
    }
    /**
     * Send to player.
     *
     * @param <MSG>   the type parameter
     * @param message the message
     * @param player  the player
     */
    public static <MSG> void sendToPlayer(MSG message, ServerPlayer player){
        INSTANCE.send(PacketDistributor.PLAYER.with(() -> player), message);
    }

    /**
     * Send to all player.
     *
     * @param <MSG>   the type parameter
     * @param message the message
     */
    public static <MSG> void sendToAllPlayer(MSG message){
        INSTANCE.send(PacketDistributor.ALL.noArg(), message);
    }

    /**
     * Send to player.
     *
     * @param <MSG>             the type parameter
     * @param <T>               the type parameter
     * @param message           the message
     * @param entity            the entity
     * @param packetDistributor the packet distributor
     */
    public static <MSG, T> void sendToPlayer(MSG message, T entity, PacketDistributor<T> packetDistributor){
        INSTANCE.send(packetDistributor.with(() -> entity), message);
    }
}
