package net.t7seven7t.craftfx.data.trigger;
import net.t7seven7t.craftfx.data.AbstractData;
import net.t7seven7t.craftfx.data.ConfigDataHolder;
import net.t7seven7t.craftfx.data.Data;
import net.t7seven7t.craftfx.data.DataHolder;
import org.bukkit.util.NumberConversions;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
/**
* Data about which slots a trigger item can fire from
*/
public class SlotData extends AbstractData {
private static final Set<Integer> ARMOR_SLOTS
= IntStream.rangeClosed(36, 39).boxed().collect(Collectors.toSet());
private static final Set<Integer> HOTBAR_SLOTS
= IntStream.rangeClosed(0, 8).boxed().collect(Collectors.toSet());
private static final Set<Integer> ALL_SLOTS
= IntStream.rangeClosed(0, 35).boxed().collect(Collectors.toSet());
static {
ALL_SLOTS.addAll(ARMOR_SLOTS);
}
private int[] slots;
private boolean handSlot;
public SlotData(String slots) {
this.slots = fromCollection(parseSlots(slots));
}
public SlotData(boolean handSlot, int... slots) {
this.handSlot = handSlot;
this.slots = slots;
}
public SlotData(boolean handSlot, List<Integer> slots) {
this.handSlot = handSlot;
this.slots = fromCollection(slots);
}
public boolean isHandSlot() {
return handSlot;
}
public int[] getSlots() {
return slots;
}
private Set<Integer> parseSlots(String str) {
final String[] parts = str.split(", ?");
final Set<Integer> ints = new HashSet<>();
handSlot = false;
loop:
for (String s : parts) {
s = s.toLowerCase();
switch (s) {
case "all":
ints.addAll(ALL_SLOTS);
break loop;
case "armor":
ints.addAll(ARMOR_SLOTS);
break;
case "hotbar":
ints.addAll(HOTBAR_SLOTS);
break;
case "hand":
handSlot = true;
break;
default:
int i = NumberConversions.toInt(s);
if (i < 0 || i > 36) break;
ints.add(i);
break;
}
}
return ints;
}
private int[] fromCollection(Collection<Integer> ints) {
final int[] slots = new int[ints.size()];
final Iterator<Integer> it = ints.iterator();
for (int i = 0; i < ints.size(); i++) slots[i] = it.next();
return slots;
}
@Override
public void onDataHolderUpdate() {
final DataHolder holder = getHolder().get();
if (holder instanceof ConfigDataHolder) {
final ConfigDataHolder h = (ConfigDataHolder) holder;
if (h.getConfig().isList("slots")) {
final List<?> list = h.getConfig().getList("slots");
final Set<Integer> ints = new HashSet<>();
for (Object o : list) {
if (o instanceof String) {
ints.addAll(parseSlots((String) o));
} else {
int i = NumberConversions.toInt(o);
if (i < 0 || i > 36) continue;
ints.add(i);
}
}
slots = fromCollection(ints);
return;
}
}
final Optional<String> opt = holder.get("slots", String.class);
opt.ifPresent(s -> slots = fromCollection(parseSlots(s)));
}
@Override
public Data getCopy() {
return new SlotData(handSlot, slots);
}
}