package xyz.upperlevel.uppercore.arena;

import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerQuitEvent;
import xyz.upperlevel.uppercore.Uppercore;
import xyz.upperlevel.uppercore.arena.events.ArenaQuitEvent.ArenaQuitReason;
import xyz.upperlevel.uppercore.config.Config;
import xyz.upperlevel.uppercore.util.WorldUtil;

import java.io.File;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

public class ArenaManager implements Listener {
    public static final File ARENAS_FOLDER = new File(Uppercore.getPlugin().getDataFolder(), "arenas");
    public static ArenaManager instance = new ArenaManager();

    private final Map<String, Arena> byId = new HashMap<>();

    //================================================================================
    // Loading

    public <A extends Arena> void load(Class<A> arenaClass) {
        File[] files = ARENAS_FOLDER.listFiles();
        if (files == null) {
            return;
        }
        for (File file : files) {
            String id = file.getName().substring(0, file.getName().lastIndexOf('.'));

            // First loads the arena world.
            String world = Arena.getSignature(id);
            WorldUtil.createEmptyWorld(world);

            // Then loads arena's data.
            Config cfg = Config.fromYaml(file);
            A arena = cfg.get(arenaClass);
            register(arena);

            // If the arena is ready, sets to enabled.
            if (arena.isReady()) {
                arena.setEnabled(true);
            }
        }
        Bukkit.getPluginManager().registerEvents(this, Uppercore.plugin());
    }

    //================================================================================
    // Registering

    public void register(Arena arena) {
        byId.put(arena.getId(), arena);
    }

    public Arena get(String id) {
        return byId.get(id);
    }

    public Arena get(World world) {
        for (Arena arena : byId.values()) {
            if (world.equals(arena.getWorld())) {
                return arena;
            }
        }
        return null;
    }

    public Arena get(Player player) {
        for (Arena arena : byId.values()) {
            if (arena.getPlayers().contains(player)) {
                return arena;
            }
        }
        return null;
    }

    public void destroy(Arena arena) {
        byId.remove(arena.getId());
        if (arena.getWorld() != null) {
            arena.destroy();
        }
    }

    public Collection<Arena> getArenas() {
        return byId.values();
    }

    public void unload() {
        for (Arena arena : byId.values()) {
            arena.unload();
        }
    }

    //================================================================================
    // Events

    @EventHandler
    private void onPlayerQuit(PlayerQuitEvent e) {
        Arena arena = get(e.getPlayer());
        if (arena != null) {
            arena.quit(e.getPlayer(), ArenaQuitReason.GAME_QUIT);
        }
    }

    public static ArenaManager get() {
        return instance;
    }
}

@@ -85,16 +85,77 @@
 .World;%0A
+import org.bukkit.block.Block;%0Aimport org.bukkit.block.Sign;%0A
 import o
@@ -247,24 +247,114 @@
 t.Listener;%0A
+import org.bukkit.event.block.Action;%0Aimport org.bukkit.event.player.PlayerInteractEvent;%0A
 import org.b
@@ -2604,32 +2604,260 @@
 rn null;%0A    %7D%0A%0A
+    public Arena getArena(Sign joinSign) %7B%0A        for (Arena arena : byId.values()) %7B%0A            if (arena.getJoinSigns().contains(joinSign)) %7B%0A                return arena;%0A            %7D%0A        %7D%0A        return null;%0A    %7D%0A%0A
     public void 
@@ -3514,32 +3514,626 @@
        %7D%0A    %7D%0A%0A
+    @EventHandler%0A    private void onJoinSignClick(PlayerInteractEvent e) %7B%0A        Block block = e.getClickedBlock();%0A        if (e.getAction() == Action.RIGHT_CLICK_BLOCK && block != null) %7B%0A            if (block.getState() instanceof Sign) %7B%0A                Arena arena = getArena((Sign) block.getState());%0A                // If the sign is a join-sign and the player isn't within any arena, then can join.%0A                if (arena != null && arena.isEnabled() && get(e.getPlayer()) == null) %7B%0A                    arena.join(e.getPlayer());%0A                %7D%0A            %7D%0A        %7D%0A    %7D%0A%0A
     public stati

Make player join when right-clicks sign