package tc.oc.commons.bukkit.inventory;
import java.util.Objects;
import java.util.Optional;
import javax.annotation.Nullable;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryView;
import org.bukkit.inventory.ItemStack;
import tc.oc.commons.core.util.Utils;
import static com.google.common.base.Preconditions.checkNotNull;
public class InventorySlot<I extends Inventory> {
private final I inventory;
private final Optional<Slot<I, ?>> slot;
public InventorySlot(I inventory, Optional<Slot<I, ?>> slot) {
this.inventory = checkNotNull(inventory);
this.slot = checkNotNull(slot);
}
public InventorySlot(I inventory, Slot<I, ?> slot) {
this(inventory, Optional.of(slot));
}
public InventorySlot(I inventory) {
this(inventory, Optional.empty());
}
public static <I extends Inventory> InventorySlot<I> fromInventoryIndex(I inventory, int index) {
final Slot slot = Slot.forInventoryIndex(inventory.getClass(), index);
if(slot == null) {
throw new IllegalArgumentException("Could not determine slot at index " + index + " in inventory " + inventory);
}
return new InventorySlot<>(inventory, slot);
}
public static <I extends Inventory> InventorySlot<I> fromInventoryIndex(I inventory, @Nullable Integer index) {
return index != null ? fromInventoryIndex(inventory, (int) index)
: new InventorySlot<>(inventory);
}
public static InventorySlot<?> fromViewIndex(InventoryView view, int rawIndex) {
final Slot slot = Slot.forViewIndex(view, rawIndex);
if(slot == null) {
throw new IllegalArgumentException("Could not determine slot at index " + rawIndex + " in view " + view);
}
final Inventory inventory = rawIndex == view.convertSlot(rawIndex) ? view.getTopInventory()
: view.getBottomInventory();
return new InventorySlot<>(inventory, slot);
}
public static InventorySlot<?> fromEvent(InventoryClickEvent event) {
return fromViewIndex(event.getView(), event.getRawSlot());
}
public I inventory() {
return inventory;
}
public Optional<Slot<I, ?>> slot() {
return slot;
}
public void putItem(ItemStack item) {
if(slot.isPresent()) {
slot.get().putItem(inventory, item);
} else {
inventory.addItem(item);
}
}
public @Nullable ItemStack getItem() {
return slot.isPresent() ? slot.get().getItem(inventory)
: InventoryUtils.contents(inventory).findFirst().orElse(null);
}
public Optional<ItemStack> contents() {
return slot.isPresent() ? Optional.ofNullable(slot.get().getItem(inventory))
: InventoryUtils.contents(inventory).findFirst();
}
@Override
public int hashCode() {
return Objects.hash(inventory, slot);
}
@Override
public boolean equals(Object obj) {
return Utils.equals(InventorySlot.class, this, obj, that -> this.inventory.equals(that.inventory()) &&
this.slot.equals(that.slot()));
}
@Override
public String toString() {
return getClass().getSimpleName() +
"{inventory=" + inventory +
(slot.map(s -> " slot=" + s).orElse("")) +
"}";
}
}