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

package com.hypixel.hytale.server.core.universe.world;

import java.util.Iterator;
import com.hypixel.hytale.component.ComponentType;
import com.hypixel.hytale.protocol.Packet;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import com.hypixel.hytale.protocol.packets.world.SpawnParticleSystem;
import com.hypixel.hytale.protocol.Position;
import com.hypixel.hytale.protocol.Direction;
import com.hypixel.hytale.server.core.asset.type.particle.config.WorldParticle;
import com.hypixel.hytale.protocol.Color;
import com.hypixel.hytale.math.vector.Vector3f;
import javax.annotation.Nullable;
import it.unimi.dsi.fastutil.objects.ObjectList;
import java.util.List;
import com.hypixel.hytale.server.core.modules.entity.EntityModule;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.spatial.SpatialResource;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.component.ComponentAccessor;
import com.hypixel.hytale.math.vector.Vector3d;
import javax.annotation.Nonnull;

public class ParticleUtil
{
    public static final double DEFAULT_PARTICLE_DISTANCE = 75.0;
    
    public static void spawnParticleEffect(@Nonnull final String name, @Nonnull final Vector3d position, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        final SpatialResource<Ref<EntityStore>, EntityStore> playerSpatialResource = componentAccessor.getResource(EntityModule.get().getPlayerSpatialResourceType());
        final ObjectList<Ref<EntityStore>> playerRefs = SpatialResource.getThreadLocalReferenceList();
        playerSpatialResource.getSpatialStructure().collect(position, 75.0, playerRefs);
        spawnParticleEffect(name, position.getX(), position.getY(), position.getZ(), null, playerRefs, componentAccessor);
    }
    
    public static void spawnParticleEffect(@Nonnull final String name, @Nonnull final Vector3d position, @Nonnull final List<Ref<EntityStore>> playerRefs, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        spawnParticleEffect(name, position.getX(), position.getY(), position.getZ(), null, playerRefs, componentAccessor);
    }
    
    public static void spawnParticleEffect(@Nonnull final String name, @Nonnull final Vector3d position, @Nullable final Ref<EntityStore> sourceRef, @Nonnull final List<Ref<EntityStore>> playerRefs, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        spawnParticleEffect(name, position.getX(), position.getY(), position.getZ(), sourceRef, playerRefs, componentAccessor);
    }
    
    public static void spawnParticleEffect(@Nonnull final String name, @Nonnull final Vector3d position, @Nonnull final Vector3f rotation, @Nonnull final List<Ref<EntityStore>> playerRefs, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        spawnParticleEffect(name, position.getX(), position.getY(), position.getZ(), rotation.getYaw(), rotation.getPitch(), rotation.getRoll(), null, playerRefs, componentAccessor);
    }
    
    public static void spawnParticleEffect(@Nonnull final String name, @Nonnull final Vector3d position, @Nonnull final Vector3f rotation, @Nullable final Ref<EntityStore> sourceRef, @Nonnull final List<Ref<EntityStore>> playerRefs, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        spawnParticleEffect(name, position.getX(), position.getY(), position.getZ(), rotation.getYaw(), rotation.getPitch(), rotation.getRoll(), sourceRef, playerRefs, componentAccessor);
    }
    
    public static void spawnParticleEffect(final String name, @Nonnull final Vector3d position, final float yaw, final float pitch, final float roll, @Nullable final Ref<EntityStore> sourceRef, @Nonnull final List<Ref<EntityStore>> playerRefs, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        spawnParticleEffect(name, position.getX(), position.getY(), position.getZ(), yaw, pitch, roll, sourceRef, playerRefs, componentAccessor);
    }
    
    public static void spawnParticleEffect(@Nonnull final String name, @Nonnull final Vector3d position, final float yaw, final float pitch, final float roll, final float scale, @Nonnull final Color color, @Nonnull final List<Ref<EntityStore>> playerRefs, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        spawnParticleEffect(name, position.getX(), position.getY(), position.getZ(), yaw, pitch, roll, scale, color, null, playerRefs, componentAccessor);
    }
    
    public static void spawnParticleEffect(@Nonnull final WorldParticle particles, @Nonnull final Vector3d position, @Nonnull final List<Ref<EntityStore>> playerRefs, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        spawnParticleEffect(particles, position, null, playerRefs, componentAccessor);
    }
    
    public static void spawnParticleEffect(@Nonnull final WorldParticle particles, @Nonnull final Vector3d position, @Nullable final Ref<EntityStore> sourceRef, @Nonnull final List<Ref<EntityStore>> playerRefs, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        spawnParticleEffect(particles, position, 0.0f, 0.0f, 0.0f, sourceRef, playerRefs, componentAccessor);
    }
    
    public static void spawnParticleEffects(@Nonnull final WorldParticle[] particles, @Nonnull final Vector3d position, @Nullable final Ref<EntityStore> sourceRef, @Nonnull final List<Ref<EntityStore>> playerRefs, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        for (final WorldParticle particle : particles) {
            spawnParticleEffect(particle, position, sourceRef, playerRefs, componentAccessor);
        }
    }
    
    public static void spawnParticleEffect(@Nonnull final WorldParticle particles, @Nonnull final Vector3d position, float yaw, float pitch, float roll, @Nullable final Ref<EntityStore> sourceRef, @Nonnull final List<Ref<EntityStore>> playerRefs, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        final com.hypixel.hytale.protocol.Vector3f positionOffset = particles.getPositionOffset();
        if (positionOffset != null) {
            final Vector3d offset = new Vector3d(positionOffset.x, positionOffset.y, positionOffset.z);
            offset.rotateY(yaw);
            offset.rotateX(pitch);
            offset.rotateZ(roll);
            position.x += offset.x;
            position.y += offset.y;
            position.z += offset.z;
        }
        final Direction rotationOffset = particles.getRotationOffset();
        if (rotationOffset != null) {
            yaw += (float)Math.toRadians(rotationOffset.yaw);
            pitch += (float)Math.toRadians(rotationOffset.pitch);
            roll += (float)Math.toRadians(rotationOffset.roll);
        }
        final String systemId = particles.getSystemId();
        if (systemId != null) {
            spawnParticleEffect(systemId, position.getX(), position.getY(), position.getZ(), yaw, pitch, roll, particles.getScale(), particles.getColor(), sourceRef, playerRefs, componentAccessor);
        }
    }
    
    public static void spawnParticleEffect(@Nonnull final String name, final double x, final double y, final double z, @Nonnull final List<Ref<EntityStore>> playerRefs, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        spawnParticleEffect(name, x, y, z, null, playerRefs, componentAccessor);
    }
    
    public static void spawnParticleEffect(@Nonnull final String name, final double x, final double y, final double z, @Nullable final Ref<EntityStore> sourceRef, @Nonnull final List<Ref<EntityStore>> playerRefs, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        spawnParticleEffect(name, x, y, z, 0.0f, 0.0f, 0.0f, 1.0f, null, sourceRef, playerRefs, componentAccessor);
    }
    
    public static void spawnParticleEffect(@Nonnull final String name, final double x, final double y, final double z, final float rotationYaw, final float rotationPitch, final float rotationRoll, @Nullable final Ref<EntityStore> sourceRef, @Nonnull final List<Ref<EntityStore>> playerRefs, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        spawnParticleEffect(name, x, y, z, rotationYaw, rotationPitch, rotationRoll, 1.0f, null, sourceRef, playerRefs, componentAccessor);
    }
    
    public static void spawnParticleEffect(@Nonnull final String name, final double x, final double y, final double z, final float rotationYaw, final float rotationPitch, final float rotationRoll, final float scale, @Nullable final Color color, @Nullable final Ref<EntityStore> sourceRef, @Nonnull final List<Ref<EntityStore>> playerRefs, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        Direction rotation = null;
        if (rotationYaw != 0.0f || rotationPitch != 0.0f || rotationRoll != 0.0f) {
            rotation = new Direction(rotationYaw, rotationPitch, rotationRoll);
        }
        final SpawnParticleSystem packet = new SpawnParticleSystem(name, new Position(x, y, z), rotation, scale, color);
        final ComponentType<EntityStore, PlayerRef> playerRefComponentType = PlayerRef.getComponentType();
        for (final Ref<EntityStore> playerRef : playerRefs) {
            if (!playerRef.isValid()) {
                continue;
            }
            if (sourceRef != null && playerRef.equals(sourceRef)) {
                continue;
            }
            final PlayerRef playerRefComponent = componentAccessor.getComponent(playerRef, playerRefComponentType);
            assert playerRefComponent != null;
            playerRefComponent.getPacketHandler().writeNoCache(packet);
        }
    }
}
