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

package com.hypixel.hytale.builtin.hytalegenerator.commands;

import com.hypixel.hytale.server.core.prefab.selection.standard.BlockSelection;
import com.hypixel.hytale.math.vector.Vector3d;
import com.hypixel.hytale.builtin.hytalegenerator.LoggerUtil;
import com.hypixel.hytale.common.util.ExceptionUtil;
import com.hypixel.hytale.builtin.hytalegenerator.newsystem.NViewport;
import com.hypixel.hytale.builtin.buildertools.BuilderToolsPlugin;
import com.hypixel.hytale.builtin.hytalegenerator.bounds.Bounds3i;
import com.hypixel.hytale.math.vector.Vector3i;
import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
import com.hypixel.hytale.server.core.Message;
import com.hypixel.hytale.server.core.command.system.arguments.system.Argument;
import com.hypixel.hytale.server.core.entity.entities.Player;
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.types.ArgTypes;
import javax.annotation.Nullable;
import com.hypixel.hytale.builtin.hytalegenerator.assets.AssetManager;
import com.hypixel.hytale.server.core.command.system.arguments.system.OptionalArg;
import javax.annotation.Nonnull;
import com.hypixel.hytale.server.core.command.system.arguments.system.FlagArg;
import com.hypixel.hytale.server.core.command.system.basecommands.AbstractPlayerCommand;

public class ViewportCommand extends AbstractPlayerCommand
{
    @Nonnull
    private final FlagArg deleteFlag;
    @Nonnull
    private final OptionalArg<Integer> radiusArg;
    @Nonnull
    private final AssetManager assetManager;
    @Nullable
    private Runnable activeTask;
    
    public ViewportCommand(@Nonnull final AssetManager assetManager) {
        super("Viewport", "Establishes a worldgen viewport on the selected region.");
        this.deleteFlag = this.withFlagArg("delete", "Deletes the existing Viewport instance.");
        this.radiusArg = this.withOptionalArg("radius", "Creates a viewport with the given radius in chunks around the player.", ArgTypes.INTEGER);
        this.assetManager = assetManager;
    }
    
    @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 Player playerComponent = store.getComponent(ref, Player.getComponentType());
        assert playerComponent != null;
        if (this.activeTask != null) {
            this.assetManager.unregisterReloadListener(this.activeTask);
            this.activeTask = null;
        }
        if (context.get((Argument<?, Boolean>)this.deleteFlag)) {
            playerRef.sendMessage(Message.translation("server.commands.viewport.removed"));
            return;
        }
        final Integer radius = context.get((Argument<?, Integer>)this.radiusArg) << 5;
        Bounds3i viewportBounds_voxelGrid;
        if (radius != null) {
            final Vector3d playerPosition_voxelGrid = store.getComponent(ref, TransformComponent.getComponentType()).getPosition();
            final Vector3i min_voxelGrid = playerPosition_voxelGrid.clone().subtract(radius).toVector3i();
            final Vector3i max_voxelGrid = playerPosition_voxelGrid.clone().add(radius).toVector3i().add(Vector3i.ALL_ONES);
            viewportBounds_voxelGrid = new Bounds3i(min_voxelGrid, max_voxelGrid);
        }
        else {
            final BuilderToolsPlugin.BuilderState builderState = BuilderToolsPlugin.getState(playerComponent, playerRef);
            final BlockSelection selection = builderState.getSelection();
            if (selection == null) {
                return;
            }
            viewportBounds_voxelGrid = new Bounds3i(selection.getSelectionMin(), selection.getSelectionMax());
        }
        final NViewport viewport = new NViewport(viewportBounds_voxelGrid, world, context.sender());
        (this.activeTask = (() -> world.execute(() -> {
            try {
                viewport.refresh();
            }
            catch (final Exception e) {
                final String msg = "Could not refresh viewport because of the following exception:\n";
                final String msg2 = msg + ExceptionUtil.toStringWithStack(e);
                LoggerUtil.getLogger().severe(msg2);
            }
        }))).run();
        this.assetManager.registerReloadListener(this.activeTask);
        playerRef.sendMessage(Message.translation("server.commands.viewport.created"));
    }
}
