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

package com.hypixel.hytale.server.spawning.commands;

import com.hypixel.hytale.server.core.command.system.arguments.system.Argument;
import com.hypixel.hytale.server.core.command.system.exceptions.GeneralCommandException;
import com.hypixel.hytale.server.spawning.util.FloodFillPositionSelector;
import com.hypixel.hytale.component.Holder;
import com.hypixel.hytale.server.spawning.wrappers.BeaconSpawnWrapper;
import com.hypixel.hytale.math.vector.Vector3d;
import com.hypixel.hytale.math.vector.Vector3f;
import com.hypixel.hytale.component.ComponentAccessor;
import com.hypixel.hytale.server.spawning.beacons.LegacySpawnBeaconEntity;
import com.hypixel.hytale.component.AddReason;
import com.hypixel.hytale.server.core.entity.nameplate.Nameplate;
import com.hypixel.hytale.server.core.modules.entity.component.DisplayNameComponent;
import com.hypixel.hytale.server.core.Message;
import com.hypixel.hytale.server.core.modules.entity.component.PersistentModel;
import com.hypixel.hytale.server.core.modules.entity.component.ModelComponent;
import com.hypixel.hytale.server.core.entity.UUIDComponent;
import com.hypixel.hytale.server.core.asset.type.model.config.Model;
import com.hypixel.hytale.server.core.asset.type.model.config.ModelAsset;
import com.hypixel.hytale.server.spawning.beacons.SpawnBeacon;
import com.hypixel.hytale.server.spawning.SpawningPlugin;
import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.server.core.command.system.CommandContext;
import com.hypixel.hytale.server.core.command.system.arguments.types.ArgumentType;
import com.hypixel.hytale.server.core.command.system.arguments.system.FlagArg;
import javax.annotation.Nonnull;
import com.hypixel.hytale.server.core.command.system.arguments.system.RequiredArg;
import com.hypixel.hytale.server.core.command.system.basecommands.AbstractPlayerCommand;
import com.hypixel.hytale.server.core.command.system.AbstractCommand;
import com.hypixel.hytale.server.spawning.assets.spawns.config.BeaconNPCSpawn;
import com.hypixel.hytale.server.core.command.system.arguments.types.AssetArgumentType;
import com.hypixel.hytale.server.core.command.system.basecommands.AbstractCommandCollection;

public class SpawnBeaconsCommand extends AbstractCommandCollection
{
    private static final AssetArgumentType<BeaconNPCSpawn, ?> BEACON_SPAWN_ASSET_TYPE;
    
    public SpawnBeaconsCommand() {
        super("beacons", "server.commands.spawning.beacons.desc");
        this.addSubCommand(new Add());
        this.addSubCommand(new ManualTrigger());
    }
    
    static {
        BEACON_SPAWN_ASSET_TYPE = new AssetArgumentType<BeaconNPCSpawn, Object>("server.commands.spawning.beacons.arg.beacon.name", BeaconNPCSpawn.class, "server.commands.spawning.beacons.arg.beacon.usage");
    }
    
    private static class Add extends AbstractPlayerCommand
    {
        @Nonnull
        private final RequiredArg<BeaconNPCSpawn> beaconArg;
        @Nonnull
        private final FlagArg manualArg;
        
        public Add() {
            super("add", "server.commands.spawning.beacons.add.desc");
            this.beaconArg = this.withRequiredArg("beacon", "server.commands.spawning.beacons.add.arg.beacon.desc", (ArgumentType<BeaconNPCSpawn>)SpawnBeaconsCommand.BEACON_SPAWN_ASSET_TYPE);
            this.manualArg = this.withFlagArg("manual", "server.commands.spawning.beacons.add.manual.desc");
        }
        
        @Override
        protected void execute(@Nonnull final CommandContext context, @Nonnull final Store<EntityStore> store, @Nonnull final Ref<EntityStore> ref, @Nonnull final PlayerRef playerRef, @Nonnull final World world) {
            final TransformComponent transformComponent = store.getComponent(ref, TransformComponent.getComponentType());
            assert transformComponent != null;
            final Vector3f rotation = transformComponent.getRotation();
            final Vector3d position = transformComponent.getPosition();
            final BeaconNPCSpawn beacon = this.beaconArg.get(context);
            final BeaconSpawnWrapper wrapper = SpawningPlugin.get().getBeaconSpawnWrapper(BeaconNPCSpawn.getAssetMap().getIndex(beacon.getId()));
            if (((Argument<Arg, Boolean>)this.manualArg).get(context)) {
                final SpawnBeacon entity = new SpawnBeacon();
                entity.setSpawnWrapper(wrapper);
                final BeaconNPCSpawn spawn = wrapper.getSpawn();
                final String modelName = spawn.getModel();
                ModelAsset modelAsset = null;
                if (modelName != null && !modelName.isEmpty()) {
                    modelAsset = ModelAsset.getAssetMap().getAsset(modelName);
                }
                Model model;
                if (modelAsset == null) {
                    model = SpawningPlugin.get().getSpawnMarkerModel();
                }
                else {
                    model = Model.createUnitScaleModel(modelAsset);
                }
                final Holder<EntityStore> holder = EntityStore.REGISTRY.newHolder();
                holder.addComponent(SpawnBeacon.getComponentType(), entity);
                holder.addComponent(TransformComponent.getComponentType(), new TransformComponent(position, rotation));
                holder.ensureComponent(UUIDComponent.getComponentType());
                holder.addComponent(ModelComponent.getComponentType(), new ModelComponent(model));
                holder.addComponent(PersistentModel.getComponentType(), new PersistentModel(model.toReference()));
                final Message displayNameMessage = Message.raw(spawn.getId());
                holder.addComponent(DisplayNameComponent.getComponentType(), new DisplayNameComponent(displayNameMessage));
                holder.addComponent(Nameplate.getComponentType(), new Nameplate(spawn.getId()));
                store.addEntity(holder, AddReason.SPAWN);
            }
            else {
                LegacySpawnBeaconEntity.create(wrapper, position, rotation, store);
            }
            context.sendMessage(Message.translation("server.commands.spawning.beacons.add.added").param("beaconId", beacon.getId()));
        }
    }
    
    private static class ManualTrigger extends AbstractPlayerCommand
    {
        private static final Message MESSAGE_COMMANDS_SPAWNING_BEACONS_TRIGGER_NOT_BEACON;
        private static final Message MESSAGE_COMMANDS_SPAWNING_BEACONS_TRIGGER_NO_SPOTS;
        
        public ManualTrigger() {
            super("trigger", "server.commands.spawning.beacons.trigger.desc");
        }
        
        @Override
        protected void execute(@Nonnull final CommandContext context, @Nonnull final Store<EntityStore> store, @Nonnull final Ref<EntityStore> ref, @Nonnull final PlayerRef playerRef, @Nonnull final World world) {
            final FloodFillPositionSelector positionSelectorComponent = store.getComponent(ref, FloodFillPositionSelector.getComponentType());
            if (positionSelectorComponent == null) {
                throw new GeneralCommandException(ManualTrigger.MESSAGE_COMMANDS_SPAWNING_BEACONS_TRIGGER_NOT_BEACON);
            }
            final SpawnBeacon spawnBeaconComponent = store.getComponent(ref, SpawnBeacon.getComponentType());
            if (spawnBeaconComponent == null) {
                throw new GeneralCommandException(ManualTrigger.MESSAGE_COMMANDS_SPAWNING_BEACONS_TRIGGER_NOT_BEACON);
            }
            if (!spawnBeaconComponent.manualTrigger(ref, positionSelectorComponent, ref, store)) {
                context.sendMessage(ManualTrigger.MESSAGE_COMMANDS_SPAWNING_BEACONS_TRIGGER_NO_SPOTS);
            }
            else {
                context.sendMessage(Message.translation("server.commands.spawning.beacons.trigger.success"));
            }
        }
        
        static {
            MESSAGE_COMMANDS_SPAWNING_BEACONS_TRIGGER_NOT_BEACON = Message.translation("server.commands.spawning.beacons.trigger.notBeacon");
            MESSAGE_COMMANDS_SPAWNING_BEACONS_TRIGGER_NO_SPOTS = Message.translation("server.commands.spawning.beacons.trigger.no_spots");
        }
    }
}
