package me.deftware.mixin.mixins.world;

import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import me.deftware.client.framework.entity.Entity;
import me.deftware.client.framework.entity.types.EntityPlayer;
import me.deftware.client.framework.event.events.EventEntityUpdated;
import me.deftware.client.framework.event.events.EventWorldLoad;
import me.deftware.client.framework.global.GameKeys;
import me.deftware.client.framework.global.GameMap;
import me.deftware.client.framework.world.classifier.BlockClassifier;
import me.deftware.mixin.imp.IMixinWorldClient;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.client.render.WorldRenderer;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.profiler.Profiler;
import net.minecraft.util.registry.RegistryKey;
import net.minecraft.world.World;
import net.minecraft.world.dimension.DimensionType;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

import java.util.function.Supplier;

@Mixin(ClientWorld.class)
public class MixinWorldClient implements IMixinWorldClient {

    @Unique
    private final Int2ObjectMap<Entity> entities = new Int2ObjectOpenHashMap<>();

    /*@ModifyVariable(method = "randomBlockDisplayTick(IIIILjava/util/Random;ZLnet/minecraft/util/math/BlockPos$Mutable;)V", at = @At("HEAD"))
    public boolean randomBlockDisplayTick(boolean spawnBarrierBlocks) {
        if (GameMap.INSTANCE.get(GameKeys.FULL_BARRIER_TEXTURE, false))
            return true;
        return spawnBarrierBlocks;
    }*/

    @Inject(method = "<init>(Lnet/minecraft/client/network/ClientPlayNetworkHandler;Lnet/minecraft/client/world/ClientWorld$Properties;Lnet/minecraft/util/registry/RegistryKey;Lnet/minecraft/world/dimension/DimensionType;ILjava/util/function/Supplier;Lnet/minecraft/client/render/WorldRenderer;ZJ)V", at = @At("TAIL"))
    private void onConstructed(ClientPlayNetworkHandler clientPlayNetworkHandler, ClientWorld.Properties properties, RegistryKey<World> registryKey, DimensionType dimensionType, int i, Supplier<Profiler> supplier, WorldRenderer worldRenderer, boolean debugWorld, long seed, CallbackInfo ci) {
        new EventWorldLoad().broadcast();
        BlockClassifier.getClassifiers().forEach(blockClassifier -> blockClassifier.getClassifiedBlocks().clear());
    }

    @Inject(method = "addEntityPrivate", at = @At("TAIL"))
    private void addEntityPrivate(int id, net.minecraft.entity.Entity entity, CallbackInfo ci) {
        Entity e = entity instanceof PlayerEntity ?
                new EntityPlayer((PlayerEntity) entity) : Entity.newInstance(entity);
        entities.put(id, e);
        new EventEntityUpdated(EventEntityUpdated.Change.Added, e).broadcast();
    }

    @Inject(method = "removeEntity", at = @At("TAIL"))
    public void removeEntity(int entityId, net.minecraft.entity.Entity.RemovalReason reason, CallbackInfo ci) {
        new EventEntityUpdated(EventEntityUpdated.Change.Removed, entities.remove(entityId)).broadcast();
    }

    @Override
    @Unique
    public Int2ObjectMap<Entity> getLoadedEntitiesAccessor() {
        return entities;
    }

}

@@ -669,24 +669,92 @@
 orkHandler;%0A
+import net.minecraft.client.network.ClientPlayerInteractionManager;%0A
 import net.m
@@ -883,24 +883,126 @@
 ayerEntity;%0A
+import net.minecraft.item.Item;%0Aimport net.minecraft.item.ItemStack;%0Aimport net.minecraft.item.Items;%0A
 import net.m
@@ -1082,16 +1082,53 @@
 tryKey;%0A
+import net.minecraft.world.GameMode;%0A
 import n
@@ -1339,124 +1339,9 @@
 ion.
-At;%0Aimport org.spongepowered.asm.mixin.injection.Inject;%0Aimport org.spongepowered.asm.mixin.injection.ModifyVariable
+*
 ;%0Aim
@@ -1635,215 +1635,749 @@
     
-/*@ModifyVariable(method = %22randomBlockDisplayTick(IIIILjava/util/Random;ZLnet/minecraft/util/math/BlockPos$Mutable;)V%22, at = @At(%22HEAD%22))%0A    public boolean randomBlockDisplayTick(boolean spawnBarrierBlo
+@Redirect(method = %22getBlockParticle%22, at = @At(value = %22INVOKE%22, target = %22Lnet/minecraft/client/network/ClientPlayerInteractionManager;getCurrentGameMode()Lnet/minecraft/world/GameMode;%22, opcode = 180))%0A    private GameMode getBlockParticle$getGameMode(ClientPlayerInteractionManager clientPlayerInteractionManager) %7B%0A        if (GameMap.INSTANCE.get(GameKeys.FULL_BARRIER_TEXTURE, false))%0A            return GameMode.CREATIVE;%0A        return clientPlayerInteractionManager.getCurrentGameMode();%0A    %7D%0A%0A    @Redirect(method = %22getBlockParticle%22, at = @At(value = %22INVOKE%22, target = %22Lnet/minecraft/item/ItemStack;getItem()Lnet/minecraft/item/Item;%22, opcode = 180, ordinal = 0))%0A    private Item getBlockParticle$getItem(ItemStack itemSta
 ck
-s
 ) %7B%0A
@@ -2471,12 +2471,21 @@
 urn 
-true
+Items.BARRIER
 ;%0A  
@@ -2501,35 +2501,34 @@
 urn 
-spawnBarrierBlocks
+itemStack.getItem()
 ;%0A    %7D
-*/
 %0A%0A  

Fix barrier flag