package com.elmakers.mine.bukkit.world.listener;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;

import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
import org.bukkit.plugin.Plugin;

import com.elmakers.mine.bukkit.utility.ConfigurationUtils;
import com.elmakers.mine.bukkit.world.MagicWorld;
import com.elmakers.mine.bukkit.world.WorldController;

public class WorldSpawnListener implements Listener
{
    private final WorldController controller;
    private boolean spawning = false;
    private Set<SpawnReason> ignoreReasons = new HashSet<>();

    public WorldSpawnListener(final WorldController controller) {
        this.controller = controller;
    }

    public void load(ConfigurationSection config) {
        List<String> reasonList = ConfigurationUtils.getStringList(config, "ignore_reasons");
        ignoreReasons.clear();
        if (reasonList != null) {
            for (String reason : reasonList) {
                try {
                    SpawnReason ignoreReason = SpawnReason.valueOf(reason.toUpperCase());
                    ignoreReasons.add(ignoreReason);
                } catch (Exception ex) {
                    controller.getLogger().warning("Invalid spawn reason in ignore_reasons: " + reason);
                }
            }
        }
    }

    @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
    public void onEntitySpawn(CreatureSpawnEvent event) {
        if (spawning || ignoreReasons.contains(event.getSpawnReason())) return;

        MagicWorld magicWorld = controller.getWorld(event.getLocation().getWorld().getName());
        if (magicWorld == null) return;

        LivingEntity entity = event.getEntity();
        Plugin plugin = controller.getPlugin();
        spawning = true;
        try {
            if (magicWorld.processEntitySpawn(plugin, entity)) {
                entity.remove();
                event.setCancelled(true);
            }
        } catch (Exception ex) {
            controller.getLogger().log(Level.SEVERE, "Error replacing mob", ex);
        }
        spawning = false;
    }
}

@@ -147,16 +147,41 @@
 Level;%0A%0A
+import org.bukkit.Chunk;%0A
 import o
@@ -222,24 +222,57 @@
 ionSection;%0A
+import org.bukkit.entity.Entity;%0A
 import org.b
@@ -519,24 +519,70 @@
 pawnReason;%0A
+import org.bukkit.event.world.ChunkLoadEvent;%0A
 import org.b
@@ -1674,32 +1674,32 @@
 %7D%0A            %7D%0A
-
         %7D%0A    %7D%0A
@@ -1695,24 +1695,991 @@
    %7D%0A    %7D%0A%0A
+    @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)%0A    public void onChunkLoad(ChunkLoadEvent event) %7B%0A        if (spawning %7C%7C ignoreReasons.contains(SpawnReason.CHUNK_GEN) %7C%7C !event.isNewChunk()) return;%0A        Chunk chunk = event.getChunk();%0A        MagicWorld magicWorld = controller.getWorld(chunk.getWorld().getName());%0A        if (magicWorld == null) return;%0A%0A        Plugin plugin = controller.getPlugin();%0A        spawning = true;%0A        for (Entity testEntity : chunk.getEntities()) %7B%0A            if (!(testEntity instanceof LivingEntity)) continue;%0A            LivingEntity entity = (LivingEntity)testEntity;%0A            try %7B%0A                if (magicWorld.processEntitySpawn(plugin, entity)) %7B%0A                    entity.remove();%0A                %7D%0A            %7D catch (Exception ex) %7B%0A                controller.getLogger().log(Level.SEVERE, %22Error replacing mob%22, ex);%0A            %7D%0A        %7D%0A        spawning = false;%0A    %7D%0A%0A
     @EventHa

Fix passive mob spawn replacement, they come preloaded in new chunks now