package fr.aumgn.diamondrush.listeners;

import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockFormEvent;
import org.bukkit.event.block.BlockFromToEvent;
import org.bukkit.event.block.BlockIgniteEvent;
import org.bukkit.event.block.BlockPhysicsEvent;
import org.bukkit.event.block.BlockPistonExtendEvent;
import org.bukkit.event.block.BlockPistonRetractEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.player.PlayerBucketEmptyEvent;
import org.bukkit.event.world.StructureGrowEvent;

import fr.aumgn.bukkitutils.util.Vector;
import fr.aumgn.diamondrush.DiamondRush;
import fr.aumgn.diamondrush.game.Game;
import fr.aumgn.diamondrush.game.Team;

public class RegionsListener implements Listener {

    @EventHandler
    public void onBreak(BlockBreakEvent event) {
        Vector pos = new Vector(event.getBlock());
        Game game = DiamondRush.getGame();
        for (Team team : game.getTeams()) {
            if (team.getTotem() != null && team.getTotem().isTotemBlock(pos) 
                    && event.getBlock().getType() == Material.OBSIDIAN) {
                if (event.getPlayer().getItemInHand().getType() 
                        == Material.DIAMOND_PICKAXE) {
                    game.decreaseLives(team);
                } else {
                    event.setCancelled(true);
                }
                return;
            }
        }

        if (isProtected(event.getBlock().getWorld(), pos)) {
            event.setCancelled(true);
        }
    }

    @EventHandler
    public void onPlace(BlockPlaceEvent event) {
        if (isProtected(event.getBlock())) {
            event.setCancelled(true);
        }
    }

    @EventHandler
    public void onIgnite(BlockIgniteEvent event) {
        if (isProtected(event.getBlock())) {
            event.setCancelled(true);
        }
    }

    @EventHandler
    public void onExplode(EntityExplodeEvent event) {
        for (Block block : event.blockList()) {
            if (isProtected(block)) {
                event.setCancelled(true);
                return;
            }
        }
    }

    @EventHandler
    public void onPhysics(BlockPhysicsEvent event) {
        if (isProtected(event.getBlock())) {
            event.setCancelled(true);
        }
    }

    @EventHandler
    public void onForm(BlockFormEvent event) {
        if (isProtected(event.getBlock())) {
            event.setCancelled(true);
        }
    }

    @EventHandler
    public void onStructureGrow(StructureGrowEvent event) {
        for (BlockState state : event.getBlocks()) {
            if (isProtected(state.getBlock())) {
                event.setCancelled(true);
                return;
            }
        }
    }

    @EventHandler
    public void onFromTo(BlockFromToEvent event) {
        if (isProtected(event.getToBlock())) {
            event.setCancelled(true);
        }
    }

    @EventHandler
    public void onPistonRetract(BlockPistonRetractEvent event) {
        Location location = event.getRetractLocation();
        if (isProtected(location.getWorld(), new Vector(location))) {
            event.setCancelled(true);
        }
    }

    @EventHandler
    public void onPistonExtend(BlockPistonExtendEvent event) {
        for (Block block : event.getBlocks()) {
            if (isProtected(block)) {
                event.setCancelled(true);
                return;
            }
        }
    }

    @EventHandler
    public void onBucketEmpty(PlayerBucketEmptyEvent event) {
        Block block = event.getBlockClicked().
                getRelative(event.getBlockFace());
        if (isProtected(block)) {
            event.setCancelled(true);
        }
    }

    private boolean isProtected(Block block) {
        return isProtected(block.getWorld(), new Vector(block));
    }

    private boolean isProtected(World world, Vector pos) {
        Game game = DiamondRush.getGame();

        if (!world.equals(game.getWorld())) {
            return false;
        }

        if (game.getSpawn() != null 
                && game.getSpawn().contains(pos)) {
            return true;
        }

        for (Team team : game.getTeams()) {
            if (team.getSpawn() != null 
                    && team.getSpawn().contains(pos)) {
                return true;
            }
            if (team.getTotem() != null 
                    && team.getTotem().contains(pos)) {
                return true;
            }
        }

        return false;
    }
}

@@ -34,16 +34,44 @@
 eners;%0A%0A
+import java.util.Iterator;%0A%0A
 import o
@@ -2243,127 +2243,164 @@
     
-for (Block block : event.blockList()) %7B%0A            if (isProtected(block)) %7B%0A                event.setCancelled(true);
+Iterator%3CBlock%3E it = event.blockList().iterator();%0A        while (it.hasNext()) %7B%0A            Block block = it.next();%0A            if (isProtected(block)) %7B
 %0A   
@@ -2404,38 +2404,43 @@
                 
-return
+it.remove()
 ;%0A            %7D%0A
@@ -2874,29 +2874,33 @@
 ) %7B%0A        
-for (
+Iterator%3C
 BlockState s
@@ -2901,16 +2901,14 @@
 tate
- state :
+%3E it =
  eve
@@ -2913,35 +2913,123 @@
 vent.getBlocks()
-) %7B
+.iterator();%0A        while (it.hasNext()) %7B%0A            Block block = it.next().getBlock();
 %0A            if 
@@ -3045,24 +3045,13 @@
 ted(
-state.getB
+b
 lock
-()
 )) %7B
@@ -3067,39 +3067,26 @@
         
-event.setCancelled(true
+it.remove(
 );%0A     
@@ -3096,33 +3096,101 @@
     
+%7D%0A
     
-return;%0A            %7D
+    %7D%0A        if (event.getBlocks().size() %3C 1) %7B%0A            event.setCancelled(true);
 %0A   

Make region protection more accurate for explosion & growth