package be.isach.ultracosmetics.menu;
import be.isach.ultracosmetics.UltraCosmetics;
import be.isach.ultracosmetics.player.UltraPlayer;
import be.isach.ultracosmetics.util.ItemFactory;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.HashMap;
import java.util.Map;
import static be.isach.ultracosmetics.util.ItemFactory.fillerItem;
/**
* Represents a Menu. A menu can have multiple pages in case of cosmetics.
* Each item in the menu will, when clicked by a player, execute a ClickRunnable.
*
* @author iSach
* @since 07-05-2016
*/
public abstract class Menu implements Listener {
/**
* UltraCosmetcs Instance.
*/
private UltraCosmetics ultraCosmetics;
/**
* Click Runnables maps.
* <p>
* Key: Item
* Value: ClickRunnable to call when item is clicked.
*/
private Map<Inventory, Map<ItemStack, ClickRunnable>> clickRunnableMap = new HashMap<>();
public Menu(UltraCosmetics ultraCosmetics) {
this.ultraCosmetics = ultraCosmetics;
ultraCosmetics.getServer().getPluginManager().registerEvents(this, ultraCosmetics);
}
public void open(UltraPlayer player) {
Inventory inventory = Bukkit.createInventory(null, getSize(), getName());
putItems(inventory, player);
ItemFactory.fillInventory(inventory);
player.getBukkitPlayer().openInventory(inventory);
}
protected void putItem(Inventory inventory, int slot, ItemStack itemStack, ClickRunnable clickRunnable) {
Validate.notNull(itemStack);
Validate.notNull(clickRunnable);
ItemMeta itemMeta = itemStack.getItemMeta();
itemMeta.addItemFlags(ItemFlag.values());
itemStack.setItemMeta(itemMeta);
inventory.setItem(slot, itemStack);
if(clickRunnableMap.containsKey(inventory)) {
Map<ItemStack, ClickRunnable> map = clickRunnableMap.get(inventory);
map.put(itemStack, clickRunnable);
} else {
Map<ItemStack, ClickRunnable> map = new HashMap<>();
map.put(itemStack, clickRunnable);
clickRunnableMap.put(inventory, map);
}
}
@EventHandler
public void onClick(InventoryClickEvent event) {
// Check Inventory isn't null
if (event.getInventory() == null) {
return;
}
// Check Item clicked isn't null
if (event.getCurrentItem() == null) {
return;
}
// Check clicker is player
if (!(event.getWhoClicked() instanceof Player)) {
return;
}
// Check Inventory is the good one
if (!event.getInventory().getName().contains(getName())) {
return;
}
// Check that the filler item isn't being clicked
if (fillerItem != null && event.getCurrentItem().equals(fillerItem)) {
event.setCancelled(true);
return;
}
// Check that Inventory is valid.
if (!clickRunnableMap.keySet().contains(event.getInventory())) {
return;
}
// Check that Item is meant to do an action.
if (!clickRunnableMap.get(event.getInventory()).keySet().contains(event.getCurrentItem())) {
return;
}
event.setCancelled(true);
ClickRunnable clickRunnable = clickRunnableMap.get(event.getInventory()).get(event.getCurrentItem());
// Check clickrunnable isn't null.
if (clickRunnable == null) {
return;
}
Player player = (Player) event.getWhoClicked();
UltraPlayer ultraPlayer = ultraCosmetics.getPlayerManager().getUltraPlayer(player);
clickRunnable.run(new ClickData(event.getInventory(), ultraPlayer, event.getAction(), event.getCurrentItem(), event.getSlot()));
((Player) event.getWhoClicked()).updateInventory();
}
public UltraCosmetics getUltraCosmetics() {
return ultraCosmetics;
}
protected abstract void putItems(Inventory inventory, UltraPlayer player);
protected abstract int getSize();
protected abstract String getName();
}