package de.fanta.challengesjoinentities.adventure.ui;
import de.fanta.challengesjoinentities.ChallengesJoinEntities;
import de.fanta.challengesjoinentities.ChatUtil;
import de.fanta.challengesjoinentities.Server;
import de.fanta.challengesjoinentities.adventure.AdventureMap;
import de.fanta.challengesjoinentities.adventure.Category;
import de.fanta.challengesjoinentities.utils.ui.AbstractWindow;
import de.fanta.challengesjoinentities.utils.ui.ItemUtil;
import de.iani.cubesideutils.bukkit.items.CustomHeads;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.format.TextColor;
import net.md_5.bungee.api.ChatColor;
import org.bukkit.Bukkit;
import org.bukkit.Color;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class AdventureMapsUI extends AbstractWindow {
private final ChallengesJoinEntities plugin;
private final Category category;
private static final int NUM_OF_COLUMNS = 9;
private static final int NUM_OF_ITEM_COLUMNS = NUM_OF_COLUMNS - 1;
private static final int NUM_OF_ROWS = 6;
private static final int WINDOW_SIZE = NUM_OF_COLUMNS * NUM_OF_ROWS;
private static final int END_OF_FIRST_ROW_INDEX = NUM_OF_COLUMNS - 1;
private static final int END_OF_LAST_ROW_INDEX = WINDOW_SIZE - 1;
private final List<AdventureMap> maps;
private final int numOfItemRows;
private int scrollAmount;
public AdventureMapsUI(ChallengesJoinEntities plugin, Category category, Player player) {
super(player, Bukkit.createInventory(player, WINDOW_SIZE, ChatUtil.RED + category.getName() + " Map's"));
this.category = category;
this.plugin = plugin;
List<AdventureMap> maps = this.category.getMaps().stream().sorted(Comparator.comparing(AdventureMap::getName)).toList();
this.maps = new ArrayList<>(maps.size());
this.maps.addAll(maps);
this.numOfItemRows = (int) (Math.ceil(this.maps.size() / (double) NUM_OF_ITEM_COLUMNS));
this.scrollAmount = 0;
}
protected void rebuildInventory() {
ItemStack[] content = new ItemStack[WINDOW_SIZE];
// build scroll buttons
ItemStack scrollUpHead = this.scrollAmount <= 0 ? CustomHeads.QUARTZ_BLOCK_BLANK.getHead() : CustomHeads.QUARTZ_ARROW_UP.getHead();
ItemMeta scrollUpMeta = scrollUpHead.getItemMeta();
scrollUpMeta.setDisplayName((this.scrollAmount <= 0 ? ChatColor.GRAY : ChatColor.WHITE) + "Nach oben scrollen");
scrollUpHead.setItemMeta(scrollUpMeta);
content[NUM_OF_COLUMNS - 1] = scrollUpHead;
ItemStack scrollDownHead = this.scrollAmount >= this.numOfItemRows - NUM_OF_ROWS ? CustomHeads.QUARTZ_BLOCK_BLANK.getHead() : CustomHeads.QUARTZ_ARROW_DOWN.getHead();
ItemMeta scrollDownMeta = scrollDownHead.getItemMeta();
scrollDownMeta.setDisplayName((this.scrollAmount >= this.numOfItemRows - NUM_OF_ROWS ? ChatColor.GRAY : ChatColor.WHITE) + "Nach unten scrollen");
scrollDownHead.setItemMeta(scrollDownMeta);
content[WINDOW_SIZE - 1] = scrollDownHead;
// build scrollbar
for (int i = 1; i < NUM_OF_ROWS - 1; i++) {
content[(i + 1) * NUM_OF_COLUMNS - 1] = new ItemStack(Material.GRAY_STAINED_GLASS_PANE);
}
int numOfScrollbarRows = NUM_OF_ROWS - 2;
int currentScrollbarRow =
(int) Math.round(this.scrollAmount * numOfScrollbarRows / (double) this.numOfItemRows);
content[(currentScrollbarRow + 2) * NUM_OF_COLUMNS - 1] = new ItemStack(Material.BLACK_STAINED_GLASS_PANE);
// fill in items
int index = this.scrollAmount * NUM_OF_ITEM_COLUMNS;
for (int row = 0; row < NUM_OF_ROWS && index < this.maps.size(); row++) {
for (int column = 0; column < NUM_OF_ITEM_COLUMNS && index < this.maps.size(); column++) {
AdventureMap adventureMap = this.maps.get(index++);
content[row * NUM_OF_COLUMNS + column] = adventureMap == null ? null : adventureMap.getItem();
}
}
getInventory().setContents(content);
}
public void onItemClicked(InventoryClickEvent event) {
if (!mayAffectThisInventory(event)) {
return;
}
event.setCancelled(true);
if (!getInventory().equals(event.getClickedInventory())) {
return;
}
int slot = event.getSlot();
if (slot == END_OF_FIRST_ROW_INDEX) {
attempScrollUp();
return;
} else if (slot == END_OF_LAST_ROW_INDEX) {
attempScrollDown();
return;
}
if ((slot + 1) % NUM_OF_COLUMNS == 0) {
int numOfScrollbarRows = NUM_OF_ROWS - 2;
int selectedScrollBarRow = (slot + 1) / NUM_OF_COLUMNS - 2;
int targetScrollAmount = Math.round(selectedScrollBarRow * this.numOfItemRows / numOfScrollbarRows);
this.scrollAmount = Math.min(targetScrollAmount, this.numOfItemRows - NUM_OF_ROWS);
this.scrollAmount = Math.max(this.scrollAmount, 0);
rebuildInventory();
return;
}
int shopItemIndex = (slot - (slot / NUM_OF_COLUMNS))
+ this.scrollAmount * NUM_OF_ITEM_COLUMNS;
if (shopItemIndex >= this.maps.size()) {
return;
}
AdventureMap map = this.maps.get(shopItemIndex);
Player p = getPlayer();
if (map != null) {
if (event.isRightClick()) {
getPlayer().sendMessage(ChallengesJoinEntities.PREFIX_COMPONENT.append(Component.text("MapLink: klick mich :)", TextColor.color(Color.YELLOW.asRGB())).clickEvent(ClickEvent.clickEvent(ClickEvent.Action.OPEN_URL, map.getWebLink()))));
} else if (!Server.serverPlayers.containsValue(p.getUniqueId())) {
getPlayer().closeInventory();
this.plugin.getPluginConfig().getOnlineAdventureServer().ifPresentOrElse(server -> server.loadNewAdventure(p, category.getName(), map.getName()), () -> ChatUtil.sendErrorMessage(p, "Aktuell ist kein Server Frei!"));
} else {
ChatUtil.sendErrorMessage(p, "Du kannst nur einen Server starten!");
}
getPlayer().closeInventory();
}
}
private void attempScrollUp() {
if (this.scrollAmount <= 0) {
return;
}
this.scrollAmount--;
rebuildInventory();
}
private void attempScrollDown() {
if (this.scrollAmount >= this.numOfItemRows - NUM_OF_ROWS) {
return;
}
this.scrollAmount++;
rebuildInventory();
}
}