package vg.civcraft.mc.citadel.listener;

import static vg.civcraft.mc.citadel.Utility.explodeReinforcement;
import static vg.civcraft.mc.citadel.Utility.maybeReinforcementDamaged;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
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.EntityBreakDoorEvent;
import org.bukkit.event.entity.EntityChangeBlockEvent;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.player.PlayerQuitEvent;

import vg.civcraft.mc.citadel.Citadel;
import vg.civcraft.mc.citadel.PlayerState;
import vg.civcraft.mc.citadel.ReinforcementManager;
import vg.civcraft.mc.citadel.ReinforcementMode;
import vg.civcraft.mc.citadel.Utility;
import vg.civcraft.mc.citadel.reinforcement.Reinforcement;
import vg.civcraft.mc.namelayer.GroupManager;
import vg.civcraft.mc.namelayer.NameAPI;
import vg.civcraft.mc.namelayer.GroupManager.PlayerType;
import vg.civcraft.mc.namelayer.events.PromotePlayerEvent;
import vg.civcraft.mc.namelayer.group.Group;
import vg.civcraft.mc.namelayer.permission.GroupPermission;
import vg.civcraft.mc.namelayer.permission.PermissionType;


public class EntityListener implements Listener{
	protected GroupManager gm = NameAPI.getGroupManager();	
	
    @EventHandler(ignoreCancelled = true)
    public void explode(EntityExplodeEvent eee) {
        Iterator<Block> iterator = eee.blockList().iterator();
        List<Block> blocks = new ArrayList<Block>();
        while (iterator.hasNext()) {
            Block b = iterator.next();
            Block block = Utility.getRealBlock(b);
            // getRealBlock should return the block we care about so if its already in the list we know it is a double block and was already handled.
            if (blocks.contains(block))
            	continue;
            blocks.add(block);
            try {
	            if (explodeReinforcement(block)) {
	                block.getDrops().clear();
	                iterator.remove();
	            }
            } catch (NoClassDefFoundError e){
            	Citadel.Log("NoClassDefFoundError");
            }
        }
    }

    @EventHandler(ignoreCancelled = true)
    public void breakDoor(EntityBreakDoorEvent ebde) {
        ebde.setCancelled(maybeReinforcementDamaged(ebde.getBlock()));
    }

    @EventHandler(ignoreCancelled = true)
    public void changeBlock(EntityChangeBlockEvent ecbe) {
        ecbe.setCancelled(maybeReinforcementDamaged(ecbe.getBlock()));
    }

    @EventHandler(ignoreCancelled = true)
    public void spawn(CreatureSpawnEvent cse) {
    	ReinforcementManager reinforcementManager = Citadel.getReinforcementManager();
        EntityType type = cse.getEntityType();
        if (type != EntityType.IRON_GOLEM && type != EntityType.SNOWMAN) return;

        for (Block block : getGolemBlocks(type, cse.getLocation().getBlock())) {
            Reinforcement reinforcement = reinforcementManager.getReinforcement(block);
            if (reinforcement != null) {
            	/*
            	Citadel.verbose(
                        VerboseMsg.GolemCreated,
            			reinforcement.getBlock().getLocation().toString());
            			*/
                reinforcementManager.deleteReinforcement(reinforcement);
            }
        }
    }
    
    private List<Block> getGolemBlocks(EntityType type, Block base) {
        ArrayList<Block> blocks = new ArrayList<Block>();
        blocks.add(base);
        base = base.getRelative(BlockFace.UP);
        blocks.add(base);
        if (type == EntityType.IRON_GOLEM) {
            for (BlockFace face : new BlockFace[]{ BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, BlockFace.WEST }) {
                Block arm = base.getRelative(face);
                if (arm.getType() == Material.IRON_BLOCK)
                    blocks.add(arm);
            }
        }
        base = base.getRelative(BlockFace.UP);
        blocks.add(base);
        
        return blocks;
    }
    
    @EventHandler(priority = EventPriority.HIGHEST)
    public void playerQuitEvent(PlayerQuitEvent event){
    	Player p = event.getPlayer();
    	PlayerState state = PlayerState.get(p);
    	state.reset();
    }
    
    

    @EventHandler(priority = EventPriority.HIGHEST)
    public void PlayerPromoteEvent(PromotePlayerEvent event){
    	Player p = event.getPlayer();
    	Group g = event.getGroup();
    	PlayerType currentType = event.getCurrentPlayerType();
    	PlayerType futureType = event.getFuturePlayerType();
    	PlayerState state = PlayerState.get(p);
    	GroupPermission gPerm = gm.getPermissionforGroup(g);
    	if(state.getMode() == ReinforcementMode.NORMAL){
    		//player is in NORMAL mode don't need to do anything
    		return;
    	}
    	if(gPerm.isAccessible(currentType, PermissionType.BLOCKS)){
    		//see if they can access blocks current state
    		if (!gPerm.isAccessible(futureType, PermissionType.BLOCKS)){
    			//if they will no longer be able to access blocks
    			Group citadelGroup = state.getGroup();
    			if(citadelGroup.getName() == g.getName()){
    				//Player is Actively Reinforcing in that group
    				state.reset();
        			String msg = "Your PlayerType in group (" + g.getName() + ") changed you no longer have access to reinforce/bypass";
        			p.sendMessage(ChatColor.RED + msg);
        			p.sendMessage(ChatColor.GREEN + "Your mode has been set to " + 
        					ReinforcementMode.REINFORCEMENT.name() + ".");
    			}
    			
    			
    		}
    	}
    }   	
 
}

@@ -2099,16 +2099,91 @@
 (block))
+%7B%0A            %09block.getDrops().clear();%0A                iterator.remove();
 %0A       
@@ -2198,16 +2198,30 @@
 ntinue;%0A
+            %7D%0A
         

fix not stopping the block from exploding