// 
// 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.server.core.modules.physics.component.PhysicsValues;
import com.hypixel.hytale.component.ComponentAccessor;
import com.hypixel.hytale.component.Ref;
import javax.annotation.Nullable;
import com.hypixel.hytale.component.Archetype;
import com.hypixel.hytale.component.Component;
import com.hypixel.hytale.component.ComponentType;
import com.hypixel.hytale.component.Holder;
import javax.annotation.Nonnull;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.component.ArchetypeChunk;

public class EntityUtils
{
    @Nonnull
    public static Holder<EntityStore> toHolder(final int index, @Nonnull final ArchetypeChunk<EntityStore> archetypeChunk) {
        final Holder<EntityStore> holder = EntityStore.REGISTRY.newHolder();
        final Archetype<EntityStore> archetype = archetypeChunk.getArchetype();
        for (int i = archetype.getMinIndex(); i < archetype.length(); ++i) {
            final ComponentType componentType = archetype.get(i);
            if (componentType != null) {
                final Component component = archetypeChunk.getComponent(index, (ComponentType<EntityStore, Component>)componentType);
                if (component != null) {
                    holder.addComponent((ComponentType<EntityStore, Component>)componentType, component);
                }
            }
        }
        return holder;
    }
    
    @Nullable
    private static <T extends Entity> ComponentType<EntityStore, T> findComponentType(@Nonnull final Archetype<EntityStore> archetype) {
        return findComponentType(archetype, Entity.class);
    }
    
    @Nullable
    private static <C extends Component<EntityStore>, T extends C> ComponentType<EntityStore, T> findComponentType(@Nonnull final Archetype<EntityStore> archetype, @Nonnull final Class<C> entityClass) {
        for (int i = archetype.getMinIndex(); i < archetype.length(); ++i) {
            final ComponentType<EntityStore, ? extends Component<EntityStore>> componentType = (ComponentType<EntityStore, ? extends Component<EntityStore>>)archetype.get(i);
            if (componentType != null) {
                if (entityClass.isAssignableFrom(componentType.getTypeClass())) {
                    return (ComponentType<EntityStore, T>)componentType;
                }
            }
        }
        return null;
    }
    
    @Deprecated
    @Nullable
    public static Entity getEntity(@Nullable final Ref<EntityStore> ref, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        if (ref == null || !ref.isValid()) {
            return null;
        }
        final ComponentType<EntityStore, Entity> componentType = findComponentType(componentAccessor.getArchetype(ref));
        if (componentType == null) {
            return null;
        }
        return componentAccessor.getComponent(ref, componentType);
    }
    
    @Nullable
    @Deprecated
    public static Entity getEntity(final int index, @Nonnull final ArchetypeChunk<EntityStore> archetypeChunk) {
        final ComponentType<EntityStore, Entity> componentType = findComponentType(archetypeChunk.getArchetype());
        if (componentType == null) {
            return null;
        }
        return archetypeChunk.getComponent(index, componentType);
    }
    
    @Nullable
    @Deprecated
    public static Entity getEntity(@Nonnull final Holder<EntityStore> holder) {
        final Archetype<EntityStore> archetype = holder.getArchetype();
        if (archetype == null) {
            return null;
        }
        final ComponentType<EntityStore, Entity> componentType = findComponentType(archetype);
        if (componentType == null) {
            return null;
        }
        return holder.getComponent(componentType);
    }
    
    @Deprecated
    public static boolean hasEntity(@Nonnull final Archetype<EntityStore> archetype) {
        return findComponentType(archetype) != null;
    }
    
    @Deprecated
    public static boolean hasLivingEntity(@Nonnull final Archetype<EntityStore> archetype) {
        return findComponentType(archetype, LivingEntity.class) != null;
    }
    
    @Nonnull
    @Deprecated
    public static PhysicsValues getPhysicsValues(@Nonnull final Ref<EntityStore> ref, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        final PhysicsValues physicsValuesComponent = componentAccessor.getComponent(ref, PhysicsValues.getComponentType());
        if (physicsValuesComponent != null) {
            return physicsValuesComponent;
        }
        final ModelComponent modelComponent = componentAccessor.getComponent(ref, ModelComponent.getComponentType());
        final Model model = (modelComponent != null) ? modelComponent.getModel() : null;
        if (model != null && model.getPhysicsValues() != null) {
            return model.getPhysicsValues();
        }
        return PhysicsValues.getDefault();
    }
}
