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

package com.hypixel.hytale.builtin.deployables.config;

import com.hypixel.hytale.codec.validation.Validators;
import com.hypixel.hytale.codec.KeyedCodec;
import com.hypixel.hytale.codec.codecs.array.ArrayCodec;
import com.hypixel.hytale.codec.Codec;
import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.builtin.deployables.DeployablesUtils;
import com.hypixel.hytale.math.vector.Vector3f;
import com.hypixel.hytale.math.vector.Vector3d;
import com.hypixel.hytale.server.core.modules.entity.damage.DamageCause;
import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
import java.time.Instant;
import java.time.temporal.TemporalUnit;
import java.time.temporal.ChronoUnit;
import com.hypixel.hytale.server.core.modules.time.TimeResource;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.CommandBuffer;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.component.ArchetypeChunk;
import javax.annotation.Nonnull;
import com.hypixel.hytale.builtin.deployables.component.DeployableComponent;
import com.hypixel.hytale.codec.builder.BuilderCodec;

public class DeployableTrapSpawnerConfig extends DeployableTrapConfig
{
    public static final BuilderCodec<DeployableTrapSpawnerConfig> CODEC;
    private String[] deployableSpawnerIds;
    private DeployableSpawner[] deployableSpawners;
    
    @Override
    public void tick(@Nonnull final DeployableComponent deployableComponent, final float dt, final int index, @Nonnull final ArchetypeChunk<EntityStore> archetypeChunk, @Nonnull final Store<EntityStore> store, @Nonnull final CommandBuffer<EntityStore> commandBuffer) {
        final Ref<EntityStore> entityRef = archetypeChunk.getReferenceTo(index);
        switch (deployableComponent.getFlag(DeployableComponent.DeployableFlag.STATE)) {
            case 0: {
                this.tickDeploymentState(store, deployableComponent, entityRef);
                break;
            }
            case 1: {
                this.tickDeployAnimationState(store, deployableComponent, entityRef);
                break;
            }
            case 2: {
                this.tickFuzeState(store, deployableComponent);
                break;
            }
            case 3: {
                this.tickLiveState(store, deployableComponent, entityRef, commandBuffer, dt);
                break;
            }
            case 4: {
                this.tickTriggeredState(commandBuffer, store, deployableComponent, entityRef);
                break;
            }
            case 5: {
                this.tickDespawnState(deployableComponent, entityRef, store);
                break;
            }
        }
    }
    
    private void tickDeploymentState(@Nonnull final Store<EntityStore> store, @Nonnull final DeployableComponent component, @Nonnull final Ref<EntityStore> entityRef) {
        component.setFlag(DeployableComponent.DeployableFlag.STATE, 1);
        DeployableConfig.playAnimation(store, entityRef, this, "Deploy");
    }
    
    private void tickDeployAnimationState(final Store<EntityStore> store, final DeployableComponent component, final Ref<EntityStore> entityRef) {
        component.setFlag(DeployableComponent.DeployableFlag.STATE, 2);
        DeployableConfig.playAnimation(store, entityRef, this, "Deploy");
    }
    
    private void tickFuzeState(@Nonnull final Store<EntityStore> store, @Nonnull final DeployableComponent component) {
        final Instant now = store.getResource(TimeResource.getResourceType()).getNow();
        final Instant readyTime = component.getSpawnInstant().plus((long)this.fuzeDuration, (TemporalUnit)ChronoUnit.SECONDS);
        if (now.isAfter(readyTime)) {
            component.setFlag(DeployableComponent.DeployableFlag.STATE, 3);
        }
    }
    
    private void tickLiveState(@Nonnull final Store<EntityStore> store, @Nonnull final DeployableComponent component, @Nonnull final Ref<EntityStore> entityRef, final CommandBuffer<EntityStore> commandBuffer, final float dt) {
        final Vector3d position = store.getComponent(entityRef, TransformComponent.getComponentType()).getPosition();
        final float radius = this.getRadius(store, component.getSpawnInstant());
        component.setTimeSinceLastAttack(component.getTimeSinceLastAttack() + dt);
        if (component.getTimeSinceLastAttack() > this.damageInterval && this.isLive(store, component)) {
            component.setTimeSinceLastAttack(0.0f);
            this.handleDetection(store, commandBuffer, entityRef, component, position, radius, DamageCause.PHYSICAL);
        }
    }
    
    private void tickTriggeredState(final CommandBuffer<EntityStore> commandBuffer, @Nonnull final Store<EntityStore> store, @Nonnull final DeployableComponent component, @Nonnull final Ref<EntityStore> entityRef) {
        component.setFlag(DeployableComponent.DeployableFlag.STATE, 5);
        final Vector3d parentPosition = store.getComponent(entityRef, TransformComponent.getComponentType()).getPosition();
        final Ref<EntityStore> parentOwner = store.getComponent(entityRef, DeployableComponent.getComponentType()).getOwner();
        final World world = store.getExternalData().getWorld();
        if (this.deployableSpawners != null) {
            for (final DeployableSpawner spawner : this.deployableSpawners) {
                if (spawner != null) {
                    final DeployableConfig config = spawner.getConfig();
                    final Vector3d[] positionOffsets2;
                    final Vector3d[] positionOffsets = positionOffsets2 = spawner.getPositionOffsets();
                    for (final Vector3d offset : positionOffsets2) {
                        final Vector3f childPosition = Vector3d.add(parentPosition, offset).toVector3f();
                        world.execute(() -> DeployablesUtils.spawnDeployable(commandBuffer, store, config, parentOwner, childPosition, new Vector3f(), "UP"));
                    }
                }
            }
        }
    }
    
    private void tickDespawnState(@Nonnull final DeployableComponent component, @Nonnull final Ref<EntityStore> entityRef, @Nonnull final Store<EntityStore> store) {
        component.setFlag(DeployableComponent.DeployableFlag.STATE, 6);
        super.onTriggered(store, entityRef);
    }
    
    @Override
    protected void onTriggered(@Nonnull final Store<EntityStore> store, @Nonnull final Ref<EntityStore> ref) {
        store.getComponent(ref, DeployableComponent.getComponentType()).setFlag(DeployableComponent.DeployableFlag.STATE, 4);
    }
    
    static {
        CODEC = BuilderCodec.builder(DeployableTrapSpawnerConfig.class, DeployableTrapSpawnerConfig::new, DeployableTrapConfig.CODEC).appendInherited(new KeyedCodec<String[]>("DeployableConfig", new ArrayCodec<String>(Codec.STRING, String[]::new)), (o, i) -> o.deployableSpawnerIds = i, o -> o.deployableSpawnerIds, (o, p) -> o.deployableSpawnerIds = p.deployableSpawnerIds).addValidator(Validators.nonNull()).add().afterDecode(config -> {
            if (config.deployableSpawnerIds != null) {
                final int length = config.deployableSpawnerIds.length;
                config.deployableSpawners = new DeployableSpawner[length];
                for (int j = 0; j < length; ++j) {
                    final String key = config.deployableSpawnerIds[j];
                    config.deployableSpawners[j] = DeployableSpawner.getAssetMap().getAsset(key);
                }
            }
        }).build();
    }
}
