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

package com.hypixel.hytale.server.core.io.handlers.game;

import com.hypixel.hytale.server.core.entity.entities.player.windows.Window;
import com.hypixel.hytale.server.core.inventory.container.SortType;
import com.hypixel.hytale.server.core.entity.entities.player.windows.ItemContainerWindow;
import com.hypixel.hytale.server.core.io.PacketHandler;
import com.hypixel.hytale.protocol.Packet;
import com.hypixel.hytale.server.core.event.events.ecs.SwitchActiveSlotEvent;
import com.hypixel.hytale.server.core.util.TempAssetIdUtil;
import com.hypixel.hytale.server.core.modules.item.ItemModule;
import java.util.logging.Level;
import com.hypixel.hytale.logger.HytaleLogger;
import com.hypixel.hytale.server.core.event.events.ecs.DropItemEvent;
import java.util.Iterator;
import java.util.List;
import com.hypixel.hytale.server.core.asset.type.item.config.ItemArmor;
import com.hypixel.hytale.server.core.inventory.transaction.ItemStackSlotTransaction;
import com.hypixel.hytale.server.core.asset.type.item.config.BlockSelectorToolData;
import com.hypixel.hytale.server.core.inventory.container.CombinedItemContainer;
import com.hypixel.hytale.server.core.universe.world.SoundUtil;
import com.hypixel.hytale.protocol.SoundCategory;
import com.hypixel.hytale.server.core.asset.type.soundevent.config.SoundEvent;
import com.hypixel.hytale.protocol.ItemSoundEvent;
import com.hypixel.hytale.server.core.asset.type.itemsound.config.ItemSoundSet;
import com.hypixel.hytale.server.core.asset.type.item.config.BlockGroup;
import com.hypixel.hytale.server.core.asset.type.item.config.Item;
import com.hypixel.hytale.server.core.inventory.container.ItemContainer;
import com.hypixel.hytale.server.core.inventory.transaction.ItemStackTransaction;
import com.hypixel.hytale.server.core.inventory.Inventory;
import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.component.ComponentAccessor;
import com.hypixel.hytale.server.core.entity.ItemUtils;
import com.hypixel.hytale.server.core.inventory.ItemStack;
import com.hypixel.hytale.server.core.util.NotificationUtil;
import com.hypixel.hytale.server.core.Message;
import com.hypixel.hytale.protocol.GameMode;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.server.core.entity.entities.Player;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import javax.annotation.Nonnull;
import com.hypixel.hytale.protocol.packets.inventory.InventoryAction;
import com.hypixel.hytale.protocol.packets.inventory.SwitchHotbarBlockSet;
import com.hypixel.hytale.protocol.packets.inventory.SetActiveSlot;
import com.hypixel.hytale.protocol.packets.inventory.SmartMoveItemStack;
import com.hypixel.hytale.protocol.packets.inventory.MoveItemStack;
import com.hypixel.hytale.protocol.packets.inventory.DropItemStack;
import com.hypixel.hytale.protocol.packets.inventory.SmartGiveCreativeItem;
import com.hypixel.hytale.protocol.packets.inventory.DropCreativeItem;
import com.hypixel.hytale.protocol.packets.inventory.SetCreativeItem;
import com.hypixel.hytale.server.core.io.handlers.IPacketHandler;
import com.hypixel.hytale.server.core.io.handlers.SubPacketHandler;

public class InventoryPacketHandler implements SubPacketHandler
{
    private final IPacketHandler packetHandler;
    static final /* synthetic */ boolean $assertionsDisabled;
    
    public InventoryPacketHandler(final IPacketHandler packetHandler) {
        this.packetHandler = packetHandler;
    }
    
    @Override
    public void registerHandlers() {
        this.packetHandler.registerHandler(171, p -> this.handle((SetCreativeItem)p));
        this.packetHandler.registerHandler(172, p -> this.handle((DropCreativeItem)p));
        this.packetHandler.registerHandler(173, p -> this.handle((SmartGiveCreativeItem)p));
        this.packetHandler.registerHandler(174, p -> this.handle((DropItemStack)p));
        this.packetHandler.registerHandler(175, p -> this.handle((MoveItemStack)p));
        this.packetHandler.registerHandler(176, p -> this.handle((SmartMoveItemStack)p));
        this.packetHandler.registerHandler(177, p -> this.handle((SetActiveSlot)p));
        this.packetHandler.registerHandler(178, p -> this.handle((SwitchHotbarBlockSet)p));
        this.packetHandler.registerHandler(179, p -> this.handle((InventoryAction)p));
    }
    
    public void handle(@Nonnull final SetCreativeItem packet) {
        final PlayerRef playerRef = this.packetHandler.getPlayerRef();
        final Ref<EntityStore> ref = playerRef.getReference();
        if (ref == null || !ref.isValid()) {
            return;
        }
        final Store<EntityStore> store = ref.getStore();
        final World world = store.getExternalData().getWorld();
        world.execute(() -> {
            final Player playerComponent = store.getComponent(ref, Player.getComponentType());
            if (!InventoryPacketHandler.$assertionsDisabled && playerComponent == null) {
                throw new AssertionError();
            }
            else {
                final PlayerRef playerRefComponent = store.getComponent(ref, PlayerRef.getComponentType());
                if (!InventoryPacketHandler.$assertionsDisabled && playerRefComponent == null) {
                    throw new AssertionError();
                }
                else if (playerComponent.getGameMode() != GameMode.Creative) {
                    NotificationUtil.sendNotification(playerRefComponent.getPacketHandler(), Message.translation("server.general.setCreativeItem.notInCreativeMode"));
                }
                else {
                    final Inventory inventory = playerComponent.getInventory();
                    final int quantity = packet.item.quantity;
                    if (quantity > 0) {
                        final ItemStack itemStack = ItemStack.fromPacket(packet.item);
                        if (packet.slotId < 0) {
                            final ItemStackTransaction transaction = inventory.getCombinedHotbarFirst().addItemStack(itemStack);
                            final ItemStack remainder = transaction.getRemainder();
                            if (remainder != null && !remainder.isEmpty()) {
                                ItemUtils.dropItem(ref, remainder, store);
                            }
                        }
                        else {
                            final ItemContainer sectionById = inventory.getSectionById(packet.inventorySectionId);
                            if (packet.override) {
                                sectionById.setItemStackForSlot((short)packet.slotId, itemStack);
                            }
                            else {
                                final ItemStack existing = sectionById.getItemStack((short)packet.slotId);
                                if (existing != null && !existing.isEmpty() && existing.isStackableWith(itemStack)) {
                                    sectionById.addItemStackToSlot((short)packet.slotId, itemStack);
                                }
                                else {
                                    sectionById.setItemStackForSlot((short)packet.slotId, itemStack);
                                }
                            }
                        }
                    }
                    else if (packet.override) {
                        inventory.getSectionById(packet.inventorySectionId).setItemStackForSlot((short)packet.slotId, null);
                    }
                }
            }
        });
    }
    
    public void handle(@Nonnull final DropCreativeItem packet) {
        final PlayerRef playerRef = this.packetHandler.getPlayerRef();
        final Ref<EntityStore> ref = playerRef.getReference();
        if (ref == null || !ref.isValid()) {
            return;
        }
        final Store<EntityStore> store = ref.getStore();
        final World world = store.getExternalData().getWorld();
        ItemStack itemStack = ItemStack.fromPacket(packet.item);
        if (itemStack == null) {
            return;
        }
        final Item item = itemStack.getItem();
        if (item == Item.UNKNOWN) {
            return;
        }
        final ItemStack fStack;
        itemStack = (fStack = itemStack.withQuantity(Math.min(itemStack.getQuantity(), item.getMaxStack())));
        world.execute(() -> {
            final Player playerComponent = store.getComponent(ref, Player.getComponentType());
            if (!InventoryPacketHandler.$assertionsDisabled && playerComponent == null) {
                throw new AssertionError();
            }
            else {
                final PlayerRef playerRefComponent = store.getComponent(ref, PlayerRef.getComponentType());
                if (!InventoryPacketHandler.$assertionsDisabled && playerRefComponent == null) {
                    throw new AssertionError();
                }
                else if (playerComponent.getGameMode() != GameMode.Creative) {
                    NotificationUtil.sendNotification(playerRefComponent.getPacketHandler(), Message.translation("server.general.setCreativeItem.notInCreativeMode"));
                }
                else {
                    ItemUtils.dropItem(ref, fStack, store);
                }
            }
        });
    }
    
    public void handle(final SwitchHotbarBlockSet packet) {
        final PlayerRef playerRef = this.packetHandler.getPlayerRef();
        final Ref<EntityStore> ref = playerRef.getReference();
        if (ref == null || !ref.isValid()) {
            return;
        }
        final Store<EntityStore> store = ref.getStore();
        final World world = store.getExternalData().getWorld();
        world.execute(() -> {
            final Player playerComponent = store.getComponent(ref, Player.getComponentType());
            if (!InventoryPacketHandler.$assertionsDisabled && playerComponent == null) {
                throw new AssertionError();
            }
            else {
                final Inventory inventory = playerComponent.getInventory();
                final byte slot = inventory.getActiveHotbarSlot();
                if (slot != -1) {
                    final ItemContainer hotbar = inventory.getHotbar();
                    final ItemStack stack = hotbar.getItemStack(slot);
                    if (stack != null && !stack.isEmpty()) {
                        final BlockGroup set = BlockGroup.findItemGroup(stack.getItem());
                        if (set != null) {
                            final Item desiredItem = Item.getAssetMap().getAsset(packet.itemId);
                            if (desiredItem != null) {
                                final int currentIndex = set.getIndex(stack.getItem());
                                if (currentIndex != -1) {
                                    final int desiredIndex = set.getIndex(desiredItem);
                                    if (desiredIndex != -1 && desiredIndex != currentIndex) {
                                        ItemStack maxSelectorTool = null;
                                        short maxSlot = -1;
                                        final CombinedItemContainer combinedInventory = inventory.getCombinedArmorHotbarUtilityStorage();
                                        for (short i = 0; i < combinedInventory.getCapacity(); ++i) {
                                            final ItemStack potentialSelector = combinedInventory.getItemStack(i);
                                            if (!ItemStack.isEmpty(potentialSelector)) {
                                                final Item item = potentialSelector.getItem();
                                                final BlockSelectorToolData selectorTool = item.getBlockSelectorToolData();
                                                if (selectorTool != null) {
                                                    if (maxSelectorTool == null || maxSelectorTool.getDurability() < potentialSelector.getDurability()) {
                                                        maxSelectorTool = potentialSelector;
                                                        maxSlot = i;
                                                    }
                                                }
                                            }
                                        }
                                        if (maxSelectorTool != null) {
                                            final BlockSelectorToolData toolData = maxSelectorTool.getItem().getBlockSelectorToolData();
                                            if (playerComponent.canDecreaseItemStackDurability(ref, store) && !maxSelectorTool.isUnbreakable()) {
                                                playerComponent.updateItemStackDurability(ref, maxSelectorTool, combinedInventory, maxSlot, -toolData.getDurabilityLossOnUse(), store);
                                            }
                                            final ItemStack replacement = new ItemStack(set.get(desiredIndex), stack.getQuantity());
                                            hotbar.setItemStackForSlot(slot, replacement);
                                            final ItemSoundSet soundSet = ItemSoundSet.getAssetMap().getAsset(desiredItem.getItemSoundSetIndex());
                                            if (soundSet != null) {
                                                final String dragSound = soundSet.getSoundEventIds().get(ItemSoundEvent.Drop);
                                                if (dragSound != null) {
                                                    final int dragSoundIndex = SoundEvent.getAssetMap().getIndex(dragSound);
                                                    if (dragSoundIndex != 0) {
                                                        SoundUtil.playSoundEvent2d(ref, dragSoundIndex, SoundCategory.UI, store);
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        });
    }
    
    public void handle(@Nonnull final SmartGiveCreativeItem packet) {
        final PlayerRef playerRef = this.packetHandler.getPlayerRef();
        final Ref<EntityStore> ref = playerRef.getReference();
        if (ref == null || !ref.isValid()) {
            return;
        }
        final Store<EntityStore> store = ref.getStore();
        final World world = store.getExternalData().getWorld();
        world.execute(() -> {
            final Player playerComponent = store.getComponent(ref, Player.getComponentType());
            if (!InventoryPacketHandler.$assertionsDisabled && playerComponent == null) {
                throw new AssertionError();
            }
            else {
                final PlayerRef playerRefComponent = store.getComponent(ref, PlayerRef.getComponentType());
                if (!InventoryPacketHandler.$assertionsDisabled && playerRefComponent == null) {
                    throw new AssertionError();
                }
                else if (playerComponent.getGameMode() != GameMode.Creative) {
                    NotificationUtil.sendNotification(playerRefComponent.getPacketHandler(), Message.translation("server.general.setCreativeItem.notInCreativeMode"));
                }
                else {
                    final Inventory inventory = playerComponent.getInventory();
                    final ItemStack itemStack = ItemStack.fromPacket(packet.item);
                    switch (packet.moveType) {
                        case EquipOrMergeStack: {
                            final Item item = itemStack.getItem();
                            final ItemArmor itemArmor = item.getArmor();
                            if (itemArmor != null) {
                                inventory.getArmor().setItemStackForSlot((short)itemArmor.getArmorSlot().ordinal(), itemStack);
                                return;
                            }
                            else {
                                final int quantity = itemStack.getQuantity();
                                if (item.getUtility().isUsable()) {
                                    final ItemStackTransaction transaction = inventory.getUtility().addItemStack(itemStack);
                                    final ItemStack remainder = transaction.getRemainder();
                                    if (ItemStack.isEmpty(remainder) || remainder.getQuantity() != quantity) {
                                        final List<ItemStackSlotTransaction> slotTransactions = transaction.getSlotTransactions();
                                        for (final ItemStackSlotTransaction slotTransaction : slotTransactions) {
                                            if (!slotTransaction.succeeded()) {
                                                continue;
                                            }
                                            else {
                                                inventory.setActiveUtilitySlot((byte)slotTransaction.getSlot());
                                            }
                                        }
                                    }
                                    return;
                                }
                                else {
                                    break;
                                }
                            }
                            break;
                        }
                        case PutInHotbarOrWindow: {
                            inventory.getCombinedHotbarFirst().addItemStack(itemStack);
                            break;
                        }
                    }
                }
            }
        });
    }
    
    public void handle(@Nonnull final DropItemStack packet) {
        final PlayerRef playerRef = this.packetHandler.getPlayerRef();
        final Ref<EntityStore> ref = playerRef.getReference();
        if (ref == null || !ref.isValid()) {
            return;
        }
        final Store<EntityStore> store = ref.getStore();
        final World world = store.getExternalData().getWorld();
        world.execute(() -> {
            final DropItemEvent.PlayerRequest event = new DropItemEvent.PlayerRequest(packet.inventorySectionId, (short)packet.slotId);
            store.invoke(ref, event);
            final Player playerComponent = store.getComponent(ref, Player.getComponentType());
            if (!InventoryPacketHandler.$assertionsDisabled && playerComponent == null) {
                throw new AssertionError();
            }
            else {
                final Inventory inventory = playerComponent.getInventory();
                if (!event.isCancelled()) {
                    final ItemStackSlotTransaction transaction = inventory.getSectionById(event.getInventorySectionId()).removeItemStackFromSlot(event.getSlotId(), packet.quantity);
                    final ItemStack item = transaction.getOutput();
                    if (item == null || item.isEmpty()) {
                        HytaleLogger.getLogger().at(Level.WARNING).log("%s attempted to drop an empty ItemStack!", playerRef.getUsername());
                    }
                    else {
                        final String itemId = item.getItemId();
                        if (!ItemModule.exists(itemId)) {
                            HytaleLogger.getLogger().at(Level.WARNING).log("%s attempted to drop an unregistered ItemStack! %s", playerRef.getUsername(), itemId);
                        }
                        else {
                            ItemUtils.throwItem(ref, item, 6.0f, store);
                            SoundUtil.playSoundEvent2d(ref, TempAssetIdUtil.getSoundEventIndex("SFX_Player_Drop_Item"), SoundCategory.UI, store);
                        }
                    }
                }
                else {
                    playerComponent.sendInventory();
                }
            }
        });
    }
    
    public void handle(@Nonnull final MoveItemStack packet) {
        final PlayerRef playerRef = this.packetHandler.getPlayerRef();
        final Ref<EntityStore> ref = playerRef.getReference();
        if (ref == null || !ref.isValid()) {
            return;
        }
        final Store<EntityStore> store = ref.getStore();
        final World world = store.getExternalData().getWorld();
        world.execute(() -> {
            final Player playerComponent = store.getComponent(ref, Player.getComponentType());
            if (!InventoryPacketHandler.$assertionsDisabled && playerComponent == null) {
                throw new AssertionError();
            }
            else {
                final Inventory inventory = playerComponent.getInventory();
                inventory.moveItem(packet.fromSectionId, packet.fromSlotId, packet.quantity, packet.toSectionId, packet.toSlotId);
                if (packet.toSectionId != packet.fromSectionId && packet.toSectionId == -5) {
                    final byte newSlot = (byte)packet.toSlotId;
                    final int inventorySectionId = packet.toSectionId;
                    final byte currentSlot = inventory.getActiveSlot(inventorySectionId);
                    if (currentSlot != newSlot) {
                        final SwitchActiveSlotEvent event = new SwitchActiveSlotEvent(inventorySectionId, currentSlot, newSlot, true);
                        store.invoke(ref, event);
                        if (!event.isCancelled() && event.getNewSlot() != currentSlot) {
                            final byte newSlot2 = event.getNewSlot();
                            inventory.setActiveSlot(inventorySectionId, newSlot2);
                            playerRef.getPacketHandler().writeNoCache(new SetActiveSlot(inventorySectionId, newSlot2));
                        }
                    }
                }
            }
        });
    }
    
    public void handle(@Nonnull final SmartMoveItemStack packet) {
        final PlayerRef playerRef = this.packetHandler.getPlayerRef();
        final Ref<EntityStore> ref = playerRef.getReference();
        if (ref == null || !ref.isValid()) {
            return;
        }
        final Store<EntityStore> store = ref.getStore();
        final World world = store.getExternalData().getWorld();
        world.execute(() -> {
            final Player playerComponent = store.getComponent(ref, Player.getComponentType());
            if (!InventoryPacketHandler.$assertionsDisabled && playerComponent == null) {
                throw new AssertionError();
            }
            else {
                final Inventory inventory = playerComponent.getInventory();
                inventory.smartMoveItem(packet.fromSectionId, packet.fromSlotId, packet.quantity, packet.moveType);
            }
        });
    }
    
    public void handle(@Nonnull final SetActiveSlot packet) {
        final PlayerRef playerRef = this.packetHandler.getPlayerRef();
        final Ref<EntityStore> ref = playerRef.getReference();
        if (ref == null || !ref.isValid()) {
            return;
        }
        final Store<EntityStore> store = ref.getStore();
        final World world = store.getExternalData().getWorld();
        world.execute(() -> {
            final Player playerComponent = store.getComponent(ref, Player.getComponentType());
            if (!InventoryPacketHandler.$assertionsDisabled && playerComponent == null) {
                throw new AssertionError();
            }
            else {
                final Inventory inventory = playerComponent.getInventory();
                final PacketHandler packetHandler = playerRef.getPacketHandler();
                if (packet.inventorySectionId == -1) {
                    packetHandler.disconnect("Attempted to change the hotbar slot without an interaction");
                }
                else if (packet.activeSlot < -1 || packet.activeSlot >= inventory.getSectionById(packet.inventorySectionId).getCapacity()) {
                    packetHandler.disconnect("Attempted to set " + packet.inventorySectionId + " slot outside of range!");
                }
                else if (packet.activeSlot == inventory.getActiveSlot(packet.inventorySectionId)) {
                    packetHandler.disconnect("Attempted to set hotbar slot to already selected hotbar slot!");
                }
                else {
                    final byte previousSlot = inventory.getActiveSlot(packet.inventorySectionId);
                    byte targetSlot = (byte)packet.activeSlot;
                    final SwitchActiveSlotEvent event = new SwitchActiveSlotEvent(packet.inventorySectionId, previousSlot, targetSlot, false);
                    store.invoke(ref, event);
                    if (event.isCancelled()) {
                        targetSlot = previousSlot;
                    }
                    else if (targetSlot != event.getNewSlot()) {
                        targetSlot = event.getNewSlot();
                    }
                    if (targetSlot != packet.activeSlot) {
                        packetHandler.writeNoCache(new SetActiveSlot(packet.inventorySectionId, targetSlot));
                    }
                    if (targetSlot != previousSlot) {
                        inventory.setActiveSlot(packet.inventorySectionId, targetSlot);
                    }
                }
            }
        });
    }
    
    public void handle(@Nonnull final InventoryAction packet) {
        final PlayerRef playerRef = this.packetHandler.getPlayerRef();
        final Ref<EntityStore> ref = playerRef.getReference();
        if (ref == null || !ref.isValid()) {
            return;
        }
        if (packet.inventorySectionId < 0 && packet.inventorySectionId != -9) {
            return;
        }
        final Store<EntityStore> store = ref.getStore();
        final World world = store.getExternalData().getWorld();
        world.execute(() -> {
            final Player playerComponent = store.getComponent(ref, Player.getComponentType());
            if (!InventoryPacketHandler.$assertionsDisabled && playerComponent == null) {
                throw new AssertionError();
            }
            else {
                final Inventory inventory = playerComponent.getInventory();
                switch (packet.inventoryActionType) {
                    case TakeAll: {
                        if (packet.inventorySectionId == -9) {
                            inventory.takeAll(packet.inventorySectionId);
                            return;
                        }
                        else {
                            final Window window = playerComponent.getWindowManager().getWindow(packet.inventorySectionId);
                            if (window instanceof ItemContainerWindow) {
                                inventory.takeAll(packet.inventorySectionId);
                            }
                            break;
                        }
                        break;
                    }
                    case PutAll: {
                        if (packet.inventorySectionId == -9) {
                            inventory.putAll(packet.inventorySectionId);
                            return;
                        }
                        else {
                            final Window window2 = playerComponent.getWindowManager().getWindow(packet.inventorySectionId);
                            if (window2 instanceof ItemContainerWindow) {
                                inventory.putAll(packet.inventorySectionId);
                            }
                            break;
                        }
                        break;
                    }
                    case QuickStack: {
                        if (packet.inventorySectionId == -9) {
                            inventory.quickStack(packet.inventorySectionId);
                            return;
                        }
                        else {
                            final Window window3 = playerComponent.getWindowManager().getWindow(packet.inventorySectionId);
                            if (window3 instanceof ItemContainerWindow) {
                                inventory.quickStack(packet.inventorySectionId);
                            }
                            break;
                        }
                        break;
                    }
                    case Sort: {
                        final SortType sortType = SortType.VALUES[packet.actionData];
                        if (packet.inventorySectionId == 0) {
                            inventory.sortStorage(sortType);
                            break;
                        }
                        else if (packet.inventorySectionId == -9 && inventory.getBackpack() != null) {
                            inventory.getBackpack().sortItems(sortType);
                            return;
                        }
                        else {
                            final Window window4 = playerComponent.getWindowManager().getWindow(packet.inventorySectionId);
                            if (window4 instanceof final ItemContainerWindow itemContainerWindow) {
                                itemContainerWindow.getItemContainer().sortItems(sortType);
                                break;
                            }
                            else {
                                break;
                            }
                        }
                        break;
                    }
                }
            }
        });
    }
}
