// 
// Decompiled by Procyon v0.6.0
// 

package com.hypixel.hytale.server.npc.util;

import com.hypixel.hytale.server.core.asset.type.item.config.ItemArmor;
import java.util.logging.Level;
import com.hypixel.hytale.server.npc.NPCPlugin;
import com.hypixel.hytale.server.core.inventory.container.CombinedItemContainer;
import com.hypixel.hytale.server.core.inventory.container.ItemContainer;
import com.hypixel.hytale.server.core.inventory.Inventory;
import com.hypixel.hytale.server.core.asset.type.item.config.ItemDropList;
import com.hypixel.hytale.server.core.asset.type.item.config.Item;
import com.hypixel.hytale.server.core.modules.item.ItemModule;
import java.util.List;
import com.hypixel.hytale.common.util.StringUtil;
import javax.annotation.Nonnull;
import com.hypixel.hytale.server.core.inventory.ItemStack;
import javax.annotation.Nullable;

public class InventoryHelper
{
    public static final short DEFAULT_NPC_HOTBAR_SLOTS = 3;
    public static final short MAX_NPC_HOTBAR_SLOTS = 8;
    public static final short DEFAULT_NPC_INVENTORY_SLOTS = 0;
    public static final short DEFAULT_NPC_UTILITY_SLOTS = 0;
    public static final short MAX_NPC_UTILITY_SLOTS = 4;
    public static final short DEFAULT_NPC_TOOL_SLOTS = 0;
    public static final short MAX_NPC_INVENTORY_SLOTS = 36;
    
    private InventoryHelper() {
    }
    
    public static boolean matchesItem(@Nullable final String pattern, @Nonnull final ItemStack itemStack) {
        return pattern != null && !pattern.isEmpty() && !ItemStack.isEmpty(itemStack) && StringUtil.isGlobMatching(pattern, itemStack.getItem().getId());
    }
    
    public static boolean matchesItem(@Nullable final List<String> patterns, @Nonnull final ItemStack itemStack) {
        return patterns != null && !patterns.isEmpty() && !ItemStack.isEmpty(itemStack) && matchesPatterns(patterns, itemStack.getItem().getId());
    }
    
    protected static boolean matchesPatterns(@Nonnull final List<String> patterns, @Nullable final String name) {
        if (name == null || name.isEmpty()) {
            return false;
        }
        for (int i = 0; i < patterns.size(); ++i) {
            final String pattern = patterns.get(i);
            if (pattern != null && !pattern.isEmpty() && StringUtil.isGlobMatching(pattern, name)) {
                return true;
            }
        }
        return false;
    }
    
    public static boolean itemKeyExists(@Nullable final String name) {
        return name != null && !name.isEmpty() && ItemModule.exists(name);
    }
    
    public static boolean itemKeyIsBlockType(@Nullable final String name) {
        if (name != null && !name.isEmpty()) {
            final Item item = Item.getAssetMap().getAsset(name);
            if (item != null && item.hasBlockType()) {
                return true;
            }
        }
        return false;
    }
    
    public static boolean itemDropListKeyExists(@Nullable final String name) {
        if (name != null && !name.isEmpty()) {
            final ItemDropList dropList = ItemDropList.getAssetMap().getAsset(name);
            return dropList != null;
        }
        return false;
    }
    
    public static byte findHotbarSlotWithItem(@Nonnull final Inventory inventory, final String name) {
        final ItemContainer hotbar = inventory.getHotbar();
        for (byte i = 0; i < hotbar.getCapacity(); ++i) {
            if (matchesItem(name, hotbar.getItemStack(i))) {
                return i;
            }
        }
        return -1;
    }
    
    public static short findHotbarSlotWithItem(@Nonnull final Inventory inventory, final List<String> name) {
        final ItemContainer hotbar = inventory.getHotbar();
        for (short i = 0; i < hotbar.getCapacity(); ++i) {
            if (matchesItem(name, hotbar.getItemStack(i))) {
                return i;
            }
        }
        return -1;
    }
    
    public static byte findHotbarEmptySlot(@Nonnull final Inventory inventory) {
        final ItemContainer hotbar = inventory.getHotbar();
        for (byte i = 0; i < hotbar.getCapacity(); ++i) {
            if (ItemStack.isEmpty(hotbar.getItemStack(i))) {
                return i;
            }
        }
        return -1;
    }
    
    public static short findInventorySlotWithItem(@Nonnull final Inventory inventory, final String name) {
        final CombinedItemContainer container = inventory.getCombinedHotbarFirst();
        for (short i = 0; i < container.getCapacity(); ++i) {
            if (matchesItem(name, container.getItemStack(i))) {
                return i;
            }
        }
        return -1;
    }
    
    public static short findInventorySlotWithItem(@Nonnull final Inventory inventory, final List<String> name) {
        final CombinedItemContainer container = inventory.getCombinedHotbarFirst();
        for (short i = 0; i < container.getCapacity(); ++i) {
            if (matchesItem(name, container.getItemStack(i))) {
                return i;
            }
        }
        return -1;
    }
    
    public static int countItems(@Nonnull final ItemContainer container, final List<String> name) {
        int count = 0;
        for (short i = 0; i < container.getCapacity(); ++i) {
            final ItemStack item = container.getItemStack(i);
            if (matchesItem(name, item)) {
                count += item.getQuantity();
            }
        }
        return count;
    }
    
    public static int countFreeSlots(@Nonnull final ItemContainer container) {
        int count = 0;
        for (short i = 0; i < container.getCapacity(); ++i) {
            final ItemStack item = container.getItemStack(i);
            if (item == null || item.isEmpty()) {
                ++count;
            }
        }
        return count;
    }
    
    public static boolean hotbarContainsItem(@Nonnull final Inventory inventory, final String name) {
        return findHotbarSlotWithItem(inventory, name) != -1;
    }
    
    public static boolean hotbarContainsItem(@Nonnull final Inventory inventory, final List<String> name) {
        return findHotbarSlotWithItem(inventory, name) != -1;
    }
    
    public static boolean holdsItem(@Nonnull final Inventory inventory, final String name) {
        return matchesItem(name, inventory.getItemInHand());
    }
    
    public static boolean containsItem(@Nonnull final Inventory inventory, final String name) {
        return findInventorySlotWithItem(inventory, name) != -1;
    }
    
    public static boolean containsItem(@Nonnull final Inventory inventory, final List<String> name) {
        return findInventorySlotWithItem(inventory, name) != -1;
    }
    
    public static boolean clearItemInHand(@Nonnull final Inventory inventory, final byte slotHint) {
        if (ItemStack.isEmpty(inventory.getItemInHand())) {
            return true;
        }
        byte slot = findHotbarEmptySlot(inventory);
        if (slot >= 0) {
            inventory.setActiveHotbarSlot(slot);
            return true;
        }
        slot = (byte)((slotHint != -1) ? slotHint : 0);
        inventory.getHotbar().removeItemStackFromSlot(slot);
        inventory.setActiveHotbarSlot(slot);
        return true;
    }
    
    public static void removeItemInHand(@Nonnull final Inventory inventory, final int count) {
        if (ItemStack.isEmpty(inventory.getItemInHand())) {
            return;
        }
        final byte activeHotbarSlot = inventory.getActiveHotbarSlot();
        if (activeHotbarSlot == -1) {
            return;
        }
        inventory.getHotbar().removeItemStackFromSlot(activeHotbarSlot, count);
    }
    
    public static boolean checkHotbarSlot(@Nonnull final Inventory inventory, final byte slot) {
        final ItemContainer hotbar = inventory.getHotbar();
        if (slot >= hotbar.getCapacity() || slot < 0) {
            NPCPlugin.get().getLogger().at(Level.WARNING).log("Invalid hotbar slot %s. Max is %s", slot, hotbar.getCapacity() - 1);
            return false;
        }
        return true;
    }
    
    public static boolean checkOffHandSlot(@Nonnull final Inventory inventory, final byte slot) {
        final ItemContainer utility = inventory.getUtility();
        if (slot >= utility.getCapacity() || slot < -1) {
            NPCPlugin.get().getLogger().at(Level.WARNING).log("Invalid utility slot %s. Max is %s, Min is %s", slot, utility.getCapacity() - 1, -1);
            return false;
        }
        return true;
    }
    
    public static void setHotbarSlot(@Nonnull final Inventory inventory, final byte slot) {
        if (inventory.getActiveHotbarSlot() == slot) {
            return;
        }
        if (checkHotbarSlot(inventory, slot)) {
            inventory.setActiveHotbarSlot(slot);
        }
    }
    
    public static void setOffHandSlot(@Nonnull final Inventory inventory, final byte slot) {
        if (inventory.getActiveUtilitySlot() == slot) {
            return;
        }
        if (checkOffHandSlot(inventory, slot)) {
            inventory.setActiveUtilitySlot(slot);
        }
    }
    
    public static boolean setHotbarItem(@Nonnull final Inventory inventory, @Nullable final String name, final byte slot) {
        if (name == null || name.isEmpty() || !itemKeyExists(name)) {
            return false;
        }
        final ItemContainer hotbar = inventory.getHotbar();
        if (!checkHotbarSlot(inventory, slot)) {
            return false;
        }
        if (matchesItem(name, hotbar.getItemStack(slot))) {
            return true;
        }
        hotbar.setItemStackForSlot(slot, createItem(name));
        return true;
    }
    
    public static boolean setOffHandItem(@Nonnull final Inventory inventory, @Nullable final String name, final byte slot) {
        if (name == null || name.isEmpty() || !itemKeyExists(name)) {
            return false;
        }
        final ItemContainer utility = inventory.getUtility();
        if (!checkOffHandSlot(inventory, slot)) {
            return false;
        }
        if (matchesItem(name, utility.getItemStack(slot))) {
            return true;
        }
        utility.setItemStackForSlot(slot, createItem(name));
        return true;
    }
    
    public static boolean useItem(@Nonnull final Inventory inventory, @Nullable final String name, byte slotHint) {
        if (name == null || name.isEmpty() || !itemKeyExists(name)) {
            return false;
        }
        if (holdsItem(inventory, name)) {
            return true;
        }
        final byte slot = findHotbarSlotWithItem(inventory, name);
        if (slot >= 0) {
            inventory.setActiveHotbarSlot(slot);
            return true;
        }
        if (slotHint == -1) {
            slotHint = findHotbarEmptySlot(inventory);
        }
        if (slotHint == -1) {
            slotHint = 0;
        }
        inventory.getHotbar().setItemStackForSlot(slotHint, createItem(name));
        inventory.setActiveHotbarSlot(slotHint);
        return true;
    }
    
    @Nullable
    public static ItemStack createItem(@Nullable final String name) {
        if (!itemKeyExists(name)) {
            return null;
        }
        return new ItemStack(name, 1);
    }
    
    public static boolean useItem(@Nonnull final Inventory inventory, @Nullable final String name) {
        return (name == null || name.isEmpty()) ? clearItemInHand(inventory, (byte)(-1)) : useItem(inventory, name, (byte)(-1));
    }
    
    public static boolean useArmor(@Nonnull final ItemContainer armorInventory, @Nullable final String armorItem) {
        final ItemStack itemStack = createItem(armorItem);
        return useArmor(armorInventory, itemStack);
    }
    
    public static boolean useArmor(@Nonnull final ItemContainer armorInventory, @Nullable final ItemStack itemStack) {
        if (itemStack == null) {
            return false;
        }
        final Item item = itemStack.getItem();
        if (item == null) {
            return false;
        }
        final ItemArmor armor = item.getArmor();
        if (armor == null) {
            return false;
        }
        final short slot = (short)armor.getArmorSlot().ordinal();
        return slot >= 0 && slot <= armorInventory.getCapacity() && armorInventory.setItemStackForSlot(slot, itemStack).succeeded();
    }
}
