package net.sqdmc.enderpearlcooldown;

import java.util.HashMap;
import java.util.Map;

import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;

public class EPCListener implements Listener {

    /** playername -> last throw timestamp */
    private final Map<String, Long> lastThrow = new HashMap<String, Long>();

    @EventHandler(priority = EventPriority.NORMAL)
    public void onPlayerUseEP(PlayerInteractEvent event) {

        if (event.getAction() == Action.LEFT_CLICK_AIR
                || event.getAction() == Action.LEFT_CLICK_BLOCK
                || event.getItem() == null
                || event.getItem().getType() != Material.ENDER_PEARL) {
            return;
        }
        // ignore certain materials...
        if (event.getClickedBlock() != null && !event.isCancelled() && !event.getPlayer().isSneaking()) {
            Material clickedMat = event.getClickedBlock().getType();
            if (clickedMat == Material.CHEST
                    || clickedMat == Material.ENDER_CHEST
                    || clickedMat == Material.FURNACE
                    || clickedMat == Material.WORKBENCH
                    || clickedMat == Material.HOPPER
                    || clickedMat == Material.ANVIL
                    || clickedMat == Material.COMMAND
                    || clickedMat == Material.DROPPER
                    || clickedMat == Material.DISPENSER) {
                return;
            }
        }

        Player player = event.getPlayer();

        // may a player use pearls at all?
        if (!player.hasPermission("enderpearl.use")) {
            sendMessageChecked(player, EPC.getIstance().messageNotAllowed);
            event.setCancelled(true);
            return;
        }

        // apply cooldown to player
        Long now = System.currentTimeMillis();
        if (validthrow(player, now)) {
            if (!pay(player)) { // player can't pay
                event.setCancelled(true);
            } else { // allow throw, set cooldown
                lastThrow.put(player.getName(), now);
            }
        } else {
            event.setCancelled(true);
        }
    }

    /** Check if player needs to and can pay for a throw. */
    private boolean pay(Player player) {
        if (!player.hasPermission("enderpearl.pay")
                || EPC.getIstance().price == 0
                || EPC.getIstance().economy == null) {
            return true;
        }

        String name = player.getName();
        double price = EPC.getIstance().price;
        boolean success = false;
        if (EPC.getIstance().economy.has(name, price)) {
            success = EPC.getIstance().economy.withdrawPlayer(name, price)
                    .transactionSuccess();
        }

        if (!success) {
            sendMessageChecked(
                    player,
                    EPC.getIstance().messageMoney.replace("{price}",
                            EPC.getIstance().economy.format(price)));
        }
        return success;
    }

    /** Return remaining cooldown in seconds. */
    private double remainingCooldown(Player player, long throwTime) {
        Long lastPlayerPearl = lastThrow.get(player.getName());
        return (EPC.getIstance().cooldown - (throwTime - lastPlayerPearl)) / 1000.0;
    }

    /** Check if player is allowed to throw a pearl at this moment. */
    private boolean validthrow(Player player, long throwTime) {
        if (!player.hasPermission("enderpearl.cooldown")) {
            return true; // no cooldown for this player
        }

        Long lastPlayerPearl = lastThrow.get(player.getName());

        // for players with cooldown, check if cooldown has passed
        if (lastPlayerPearl == null
                || (throwTime - lastPlayerPearl) >= EPC.getIstance().cooldown) {
            return true;
        }

        sendMessageChecked(
                player,
                EPC.getIstance().messageCooldown.replace(
                        "{seconds}",
                        String.format("%.1f",
                                remainingCooldown(player, throwTime))));
        return false;
    }

    private static void sendMessageChecked(Player player, String message) {
        if (EPC.getIstance().showMessage) {
            player.sendMessage(message);
        }
    }
}
@@ -36,57 +36,8 @@
 n;%0A%0A
-import java.util.HashMap;%0Aimport java.util.Map;%0A%0A
 impo
@@ -60,16 +60,16 @@
 terial;%0A
+
 import o
@@ -295,16 +295,75 @@
 Event;%0A%0A
+import java.util.*;%0A%0Aimport static org.bukkit.Material.*;%0A%0A
 public c
@@ -522,24 +522,592 @@
 , Long%3E();%0A%0A
+    // materials that allow interactions are ignored, since the enderpearl will not fire%0A    private final static Set%3CMaterial%3E interactables =%0A            new HashSet%3C%3E(Arrays.asList(%0A                ANVIL, COMMAND, BED, BED_BLOCK, DISPENSER, DROPPER, ENCHANTMENT_TABLE,%0A                ENDER_CHEST, FENCE_GATE, FURNACE, HOPPER, IRON_DOOR, IRON_DOOR_BLOCK,%0A                ITEM_FRAME, LEVER, REDSTONE_COMPARATOR, REDSTONE_COMPARATOR_OFF, REDSTONE_COMPARATOR_ON,%0A                STONE_BUTTON, TRAP_DOOR, WOODEN_DOOR, WOOD_BUTTON, WOOD_DOOR, WORKBENCH%0A            ));%0A%0A
     @EventHa
@@ -1415,25 +1415,16 @@
 pe() != 
-Material.
 ENDER_PE
@@ -1694,514 +1694,51 @@
 if (
-clickedMat == Material.CHEST%0A                    %7C%7C clickedMat == Material.ENDER_CHEST%0A                    %7C%7C clickedMat == Material.FURNACE%0A                    %7C%7C clickedMat == Material.WORKBENCH%0A                    %7C%7C clickedMat == Material.HOPPER%0A                    %7C%7C clickedMat == Material.ANVIL%0A                    %7C%7C clickedMat == Material.COMMAND%0A                    %7C%7C clickedMat == Material.DROPPER%0A                    %7C%7C clickedMat == Material.DISPENSER) %7B%0A                return;%0A            %7D
+interactables.contains(clickedMat)) return;
 %0A   

add more materials to ignore on interaction