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

package com.hypixel.hytale.server.core.entity;

import com.hypixel.hytale.server.core.asset.type.model.config.Model;
import com.hypixel.hytale.server.core.modules.entity.component.ModelComponent;
import com.hypixel.hytale.math.vector.Vector3f;
import com.hypixel.hytale.math.vector.Transform;
import com.hypixel.hytale.server.core.modules.entity.component.HeadRotation;
import java.util.logging.Level;
import com.hypixel.hytale.logger.HytaleLogger;
import com.hypixel.hytale.server.core.event.events.ecs.DropItemEvent;
import com.hypixel.hytale.server.core.inventory.transaction.ItemStackTransaction;
import com.hypixel.hytale.server.core.asset.type.item.config.Item;
import com.hypixel.hytale.component.Holder;
import com.hypixel.hytale.server.core.inventory.container.ItemContainer;
import com.hypixel.hytale.server.core.inventory.container.SimpleItemContainer;
import com.hypixel.hytale.component.AddReason;
import com.hypixel.hytale.server.core.modules.entity.item.ItemComponent;
import com.hypixel.hytale.server.core.modules.entity.player.PlayerSettings;
import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
import com.hypixel.hytale.server.core.entity.entities.Player;
import com.hypixel.hytale.server.core.event.events.ecs.InteractivelyPickupItemEvent;
import com.hypixel.hytale.component.ComponentAccessor;
import javax.annotation.Nullable;
import com.hypixel.hytale.math.vector.Vector3d;
import com.hypixel.hytale.server.core.inventory.ItemStack;
import javax.annotation.Nonnull;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.component.Ref;

public class ItemUtils
{
    public static void interactivelyPickupItem(@Nonnull final Ref<EntityStore> ref, @Nonnull final ItemStack itemStack, @Nullable final Vector3d origin, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        final LivingEntity entity = (LivingEntity)EntityUtils.getEntity(ref, componentAccessor);
        final InteractivelyPickupItemEvent event = new InteractivelyPickupItemEvent(itemStack);
        componentAccessor.invoke(ref, event);
        if (event.isCancelled()) {
            dropItem(ref, itemStack, componentAccessor);
            return;
        }
        final Player playerComponent = componentAccessor.getComponent(ref, Player.getComponentType());
        if (playerComponent != null) {
            final TransformComponent transformComponent = componentAccessor.getComponent(ref, TransformComponent.getComponentType());
            assert transformComponent != null;
            PlayerSettings playerSettingsComponent = componentAccessor.getComponent(ref, PlayerSettings.getComponentType());
            if (playerSettingsComponent == null) {
                playerSettingsComponent = PlayerSettings.defaults();
            }
            Holder<EntityStore> pickupItemHolder = null;
            final Item item = itemStack.getItem();
            final ItemContainer itemContainer = playerComponent.getInventory().getContainerForItemPickup(item, playerSettingsComponent);
            final ItemStackTransaction transaction = itemContainer.addItemStack(itemStack);
            final ItemStack remainder = transaction.getRemainder();
            if (remainder != null && !remainder.isEmpty()) {
                final int quantity = itemStack.getQuantity() - remainder.getQuantity();
                if (quantity > 0) {
                    final ItemStack itemStackClone = itemStack.withQuantity(quantity);
                    playerComponent.notifyPickupItem(ref, itemStackClone, null, componentAccessor);
                    if (origin != null) {
                        pickupItemHolder = ItemComponent.generatePickedUpItem(itemStackClone, origin, componentAccessor, ref);
                    }
                }
                dropItem(ref, remainder, componentAccessor);
            }
            else {
                playerComponent.notifyPickupItem(ref, itemStack, null, componentAccessor);
                if (origin != null) {
                    pickupItemHolder = ItemComponent.generatePickedUpItem(itemStack, origin, componentAccessor, ref);
                }
            }
            if (pickupItemHolder != null) {
                componentAccessor.addEntity(pickupItemHolder, AddReason.SPAWN);
            }
        }
        else {
            SimpleItemContainer.addOrDropItemStack(componentAccessor, ref, entity.getInventory().getCombinedHotbarFirst(), itemStack);
        }
    }
    
    @Nullable
    public static Ref<EntityStore> throwItem(@Nonnull final Ref<EntityStore> ref, @Nonnull ItemStack itemStack, float throwSpeed, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        final DropItemEvent.Drop event = new DropItemEvent.Drop(itemStack, throwSpeed);
        componentAccessor.invoke(ref, event);
        if (event.isCancelled()) {
            return null;
        }
        throwSpeed = event.getThrowSpeed();
        itemStack = event.getItemStack();
        if (itemStack.isEmpty() || !itemStack.isValid()) {
            HytaleLogger.getLogger().at(Level.WARNING).log("Attempted to throw invalid item %s at %s by %s", itemStack, throwSpeed, ref.getIndex());
            return null;
        }
        final HeadRotation headRotationComponent = componentAccessor.getComponent(ref, HeadRotation.getComponentType());
        assert headRotationComponent != null;
        final Vector3f rotation = headRotationComponent.getRotation();
        final Vector3d direction = Transform.getDirection(rotation.getPitch(), rotation.getYaw());
        return throwItem(ref, componentAccessor, itemStack, direction, throwSpeed);
    }
    
    @Nullable
    public static Ref<EntityStore> throwItem(@Nonnull final Ref<EntityStore> ref, @Nonnull final ComponentAccessor<EntityStore> store, @Nonnull final ItemStack itemStack, @Nonnull final Vector3d throwDirection, final float throwSpeed) {
        final TransformComponent transformComponent = store.getComponent(ref, TransformComponent.getComponentType());
        assert transformComponent != null;
        final ModelComponent modelComponent = store.getComponent(ref, ModelComponent.getComponentType());
        assert modelComponent != null;
        final Vector3d throwPosition = transformComponent.getPosition().clone();
        final Model model = modelComponent.getModel();
        throwPosition.add(0.0, model.getEyeHeight(ref, store), 0.0).add(throwDirection);
        final Holder<EntityStore> itemEntityHolder = ItemComponent.generateItemDrop(store, itemStack, throwPosition, Vector3f.ZERO, (float)throwDirection.x * throwSpeed, (float)throwDirection.y * throwSpeed, (float)throwDirection.z * throwSpeed);
        if (itemEntityHolder == null) {
            return null;
        }
        final ItemComponent itemComponent = itemEntityHolder.getComponent(ItemComponent.getComponentType());
        if (itemComponent != null) {
            itemComponent.setPickupDelay(1.5f);
        }
        return store.addEntity(itemEntityHolder, AddReason.SPAWN);
    }
    
    @Nullable
    public static Ref<EntityStore> dropItem(@Nonnull final Ref<EntityStore> ref, @Nonnull final ItemStack itemStack, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        return throwItem(ref, itemStack, 1.0f, componentAccessor);
    }
}
