package us.corenetwork.tradecraft;

import java.util.List;
import java.util.Map;

import net.minecraft.server.v1_8_R3.BiomeBase;
import net.minecraft.server.v1_8_R3.EntityTypes;
import net.minecraft.server.v1_8_R3.EntityVillager;
import net.minecraft.server.v1_8_R3.NBTReadLimiter;
import net.minecraft.server.v1_8_R3.World;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftVillager;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Villager;
import org.bukkit.event.entity.CreatureSpawnEvent;

/**
 * Created by Matej on 23.2.2014.
 */
public class NMSVillagerManager {
    public static void register()
    {
        //Replace "Villager" entity type
        ((Map) ReflectionUtils.getStatic(EntityTypes.class, "c")).put("Villager", CustomVillager.class);
        ((Map) ReflectionUtils.getStatic(EntityTypes.class, "d")).put(CustomVillager.class, "Villager");
        ((Map) ReflectionUtils.getStatic(EntityTypes.class, "e")).put(120, CustomVillager.class);
        ((Map) ReflectionUtils.getStatic(EntityTypes.class, "f")).put(CustomVillager.class, 120);

        //Replace all villagers in biomes
        BiomeBase[] biomes = (BiomeBase[]) ReflectionUtils.getStatic(BiomeBase.class, "biomes");
        for (BiomeBase biome : biomes)
        {
            if (biome == null)
                continue;

            fixBiomeMeta((List<BiomeBase.BiomeMeta>) ReflectionUtils.get(BiomeBase.class, biome, "aw"));
            fixBiomeMeta((List<BiomeBase.BiomeMeta>) ReflectionUtils.get(BiomeBase.class, biome, "at"));
            fixBiomeMeta((List<BiomeBase.BiomeMeta>) ReflectionUtils.get(BiomeBase.class, biome, "au"));
            fixBiomeMeta((List<BiomeBase.BiomeMeta>) ReflectionUtils.get(BiomeBase.class, biome, "av"));

        }
    }

    private static void fixBiomeMeta(List<BiomeBase.BiomeMeta> meta)
    {
        for (BiomeBase.BiomeMeta m : meta)
        {
            if (m.b.equals(EntityVillager.class))
            {
                m.b = CustomVillager.class;
            }
        }
    }

    /***
     * Convert regular villager into custom villager.
     */
    public static void convert(Entity entity)
    {
        if (entity.getType() != EntityType.VILLAGER)
            return;

        EntityVillager nmsVillager = ((CraftVillager) entity).getHandle();

        World world = nmsVillager.world;
        Location location = entity.getLocation();
        int profession = nmsVillager.getProfession();

        CustomVillager newVillager = new CustomVillager(world, profession);
        newVillager.setPosition(location.getX(), location.getY(), location.getZ());
        newVillager.setAgeRaw(nmsVillager.getAge());

        world.removeEntity(nmsVillager);
        world.addEntity(newVillager, CreatureSpawnEvent.SpawnReason.CUSTOM);
    }

    public static boolean isCustomVillager(Entity entity)
    {
        return ((CraftEntity) entity).getHandle() instanceof CustomVillager;
    }

    public static int getType(Villager villager)
    {
        EntityVillager nmsVillager = ((CraftVillager) villager).getHandle();
        return nmsVillager.getProfession();
    }


    public static NBTReadLimiter UNLIMTED_NBT_READER_INSTANCE = new UnlimitedNBTLimiter();
    private static class UnlimitedNBTLimiter extends NBTReadLimiter
    {
        public UnlimitedNBTLimiter()
        {
            super(0);
        }

        @Override
        public void a(long l)
        {
        }
    }
}

@@ -73,16 +73,38 @@
 til.Map;
+%0Aimport java.util.Set;
 %0A%0Aimport
@@ -128,20 +128,20 @@
 rver.v1_
-8_R3
+9_R1
 .BiomeBa
@@ -171,28 +171,28 @@
 t.server.v1_
-8_R3
+9_R1
 .EntityTypes
@@ -224,20 +224,20 @@
 rver.v1_
-8_R3
+9_R1
 .EntityV
@@ -276,20 +276,20 @@
 rver.v1_
-8_R3
+9_R1
 .NBTRead
@@ -332,20 +332,20 @@
 .v1_
-8_R3
+9_R1
 .World;%0A
 impo
@@ -340,16 +340,17 @@
 .World;%0A
+%0A
 import o
@@ -394,36 +394,36 @@
 .craftbukkit.v1_
-8_R3
+9_R1
 .entity.CraftEnt
@@ -464,12 +464,12 @@
 .v1_
-8_R3
+9_R1
 .ent
@@ -1258,16 +1258,20 @@
         
+Set%3C
 BiomeBas
@@ -1271,18 +1271,17 @@
 iomeBase
-%5B%5D
+%3E
  biomes 
@@ -1283,16 +1283,20 @@
 omes = (
+Set%3C
 BiomeBas
@@ -1300,10 +1300,9 @@
 Base
-%5B%5D
+%3E
 ) Re
@@ -1343,22 +1343,17 @@
 class, %22
-biomes
+i
 %22);%0A    
@@ -1553,18 +1553,17 @@
 biome, %22
-aw
+x
 %22));%0A   
@@ -1657,18 +1657,17 @@
 biome, %22
-at
+u
 %22));%0A   
@@ -1765,10 +1765,9 @@
 e, %22
-au
+v
 %22));
@@ -1865,18 +1865,17 @@
 biome, %22
-av
+w
 %22));%0A%0A  

update methods to 1.9 nms change