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

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

import com.hypixel.hytale.math.random.RandomExtra;
import com.hypixel.hytale.math.vector.Vector3d;
import java.util.function.Predicate;
import com.hypixel.hytale.server.core.universe.world.SoundUtil;
import com.hypixel.hytale.protocol.SoundCategory;
import com.hypixel.hytale.protocol.BlockSoundEvent;
import com.hypixel.hytale.server.core.asset.type.blocksound.config.BlockSoundSet;
import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType;
import com.hypixel.hytale.component.ComponentAccessor;
import com.hypixel.hytale.server.core.entity.movement.MovementStatesComponent;
import com.hypixel.hytale.server.core.modules.entity.component.MovementAudioComponent;
import com.hypixel.hytale.server.core.modules.entity.component.PositionDataComponent;
import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
import java.util.Iterator;
import com.hypixel.hytale.protocol.ComponentUpdateType;
import com.hypixel.hytale.protocol.ComponentUpdate;
import java.util.Map;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.CommandBuffer;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.component.ArchetypeChunk;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import com.hypixel.hytale.component.SystemGroup;
import com.hypixel.hytale.component.query.Query;
import com.hypixel.hytale.server.core.modules.entity.component.AudioComponent;
import com.hypixel.hytale.server.core.modules.entity.tracker.EntityTrackerSystems;
import com.hypixel.hytale.component.ComponentType;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.component.system.tick.EntityTickingSystem;

public class AudioSystems
{
    public static class EntityTrackerUpdate extends EntityTickingSystem<EntityStore>
    {
        private final ComponentType<EntityStore, EntityTrackerSystems.Visible> visibleComponentType;
        private final ComponentType<EntityStore, AudioComponent> audioComponentType;
        private final Query<EntityStore> query;
        
        public EntityTrackerUpdate() {
            this.visibleComponentType = EntityTrackerSystems.Visible.getComponentType();
            this.audioComponentType = AudioComponent.getComponentType();
            this.query = (Query<EntityStore>)Query.and(this.visibleComponentType, this.audioComponentType);
        }
        
        @Nullable
        @Override
        public SystemGroup<EntityStore> getGroup() {
            return EntityTrackerSystems.QUEUE_UPDATE_GROUP;
        }
        
        @Nonnull
        @Override
        public Query<EntityStore> getQuery() {
            return this.query;
        }
        
        @Override
        public boolean isParallel(final int archetypeChunkSize, final int taskCount) {
            return EntityTickingSystem.maybeUseParallel(archetypeChunkSize, taskCount);
        }
        
        @Override
        public void tick(final float dt, final int index, @Nonnull final ArchetypeChunk<EntityStore> archetypeChunk, @Nonnull final Store<EntityStore> store, @Nonnull final CommandBuffer<EntityStore> commandBuffer) {
            final EntityTrackerSystems.Visible visibleComponent = archetypeChunk.getComponent(index, this.visibleComponentType);
            assert visibleComponent != null;
            final AudioComponent audioComponent = archetypeChunk.getComponent(index, this.audioComponentType);
            assert audioComponent != null;
            final Ref<EntityStore> ref = archetypeChunk.getReferenceTo(index);
            if (audioComponent.consumeNetworkOutdated()) {
                queueUpdatesFor(ref, audioComponent, visibleComponent.visibleTo);
            }
            else if (!visibleComponent.newlyVisibleTo.isEmpty()) {
                queueUpdatesFor(ref, audioComponent, visibleComponent.newlyVisibleTo);
            }
        }
        
        private static void queueUpdatesFor(@Nonnull final Ref<EntityStore> ref, @Nonnull final AudioComponent audioComponent, @Nonnull final Map<Ref<EntityStore>, EntityTrackerSystems.EntityViewer> visibleTo) {
            final ComponentUpdate update = new ComponentUpdate();
            update.type = ComponentUpdateType.Audio;
            update.soundEventIds = audioComponent.getSoundEventIds();
            for (final Map.Entry<Ref<EntityStore>, EntityTrackerSystems.EntityViewer> entry : visibleTo.entrySet()) {
                entry.getValue().queueUpdate(ref, update);
            }
        }
    }
    
    public static class TickMovementAudio extends EntityTickingSystem<EntityStore>
    {
        @Nonnull
        @Override
        public Query<EntityStore> getQuery() {
            return (Query<EntityStore>)Query.and(TransformComponent.getComponentType(), PositionDataComponent.getComponentType(), MovementAudioComponent.getComponentType(), MovementStatesComponent.getComponentType());
        }
        
        @Override
        public void tick(final float dt, final int index, @Nonnull final ArchetypeChunk<EntityStore> archetypeChunk, @Nonnull final Store<EntityStore> store, @Nonnull final CommandBuffer<EntityStore> commandBuffer) {
            final TransformComponent transformComponent = archetypeChunk.getComponent(index, TransformComponent.getComponentType());
            assert transformComponent != null;
            final PositionDataComponent positionDataComponent = archetypeChunk.getComponent(index, PositionDataComponent.getComponentType());
            assert positionDataComponent != null;
            final MovementAudioComponent movementAudioComponent = archetypeChunk.getComponent(index, MovementAudioComponent.getComponentType());
            assert movementAudioComponent != null;
            final int insideBlockTypeId = positionDataComponent.getInsideBlockTypeId();
            final int lastInsideBlockTypeId = movementAudioComponent.getLastInsideBlockTypeId();
            final Ref<EntityStore> ref = archetypeChunk.getReferenceTo(index);
            final Vector3d position = transformComponent.getPosition();
            if (lastInsideBlockTypeId != insideBlockTypeId) {
                movementAudioComponent.setLastInsideBlockTypeId(insideBlockTypeId);
                playMoveInSound(ref, store, movementAudioComponent, position, insideBlockTypeId);
                if (lastInsideBlockTypeId != 0) {
                    final BlockType blockType = BlockType.getAssetMap().getAsset(lastInsideBlockTypeId);
                    final int soundSetId = blockType.getBlockSoundSetIndex();
                    if (soundSetId != 0) {
                        final BlockSoundSet soundSet = BlockSoundSet.getAssetMap().getAsset(soundSetId);
                        final int soundEvent = soundSet.getSoundEventIndices().getOrDefault(BlockSoundEvent.MoveOut, 0);
                        if (soundEvent != 0) {
                            SoundUtil.playSoundEvent3d(soundEvent, SoundCategory.SFX, position.x, position.y, position.z, movementAudioComponent.getShouldHearPredicate(ref), commandBuffer);
                        }
                    }
                }
            }
            final MovementStatesComponent movementStates = archetypeChunk.getComponent(index, MovementStatesComponent.getComponentType());
            assert movementStates != null;
            if (!movementStates.getMovementStates().idle && movementAudioComponent.canMoveInRepeat() && movementAudioComponent.tickMoveInRepeat(dt)) {
                playMoveInSound(ref, commandBuffer, movementAudioComponent, position, insideBlockTypeId);
            }
        }
        
        private static void playMoveInSound(@Nonnull final Ref<EntityStore> ref, @Nonnull final ComponentAccessor<EntityStore> store, @Nonnull final MovementAudioComponent movementAudioComponent, @Nonnull final Vector3d position, final int insideBlockTypeId) {
            movementAudioComponent.setNextMoveInRepeat(MovementAudioComponent.NO_REPEAT);
            if (insideBlockTypeId == 0) {
                return;
            }
            final BlockType blockType = BlockType.getAssetMap().getAsset(insideBlockTypeId);
            final int soundSetId = blockType.getBlockSoundSetIndex();
            if (soundSetId == 0) {
                return;
            }
            final BlockSoundSet soundSet = BlockSoundSet.getAssetMap().getAsset(soundSetId);
            final int soundEvent = soundSet.getSoundEventIndices().getOrDefault(BlockSoundEvent.MoveIn, 0);
            if (soundEvent == 0) {
                return;
            }
            SoundUtil.playSoundEvent3d(soundEvent, SoundCategory.SFX, position.x, position.y, position.z, movementAudioComponent.getShouldHearPredicate(ref), store);
            movementAudioComponent.setNextMoveInRepeat(RandomExtra.randomRange(soundSet.getMoveInRepeatRange().getInclusiveMin(), soundSet.getMoveInRepeatRange().getInclusiveMax()));
        }
    }
}
