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

package com.hypixel.hytale.builtin.instances.page;

import com.hypixel.hytale.codec.builder.BuilderCodec;
import java.util.concurrent.CompletableFuture;
import com.hypixel.hytale.math.vector.Vector3d;
import com.hypixel.hytale.server.core.modules.entity.component.HeadRotation;
import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.math.vector.Transform;
import com.hypixel.hytale.server.core.modules.entity.teleport.Teleport;
import com.hypixel.hytale.component.ComponentAccessor;
import com.hypixel.hytale.builtin.instances.InstancesPlugin;
import java.nio.file.Path;
import com.hypixel.hytale.server.core.ui.browser.FileBrowserEventData;
import com.hypixel.hytale.server.core.asset.AssetModule;
import com.hypixel.hytale.server.core.ui.builder.EventData;
import com.hypixel.hytale.protocol.packets.interface_.CustomUIEventBindingType;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.server.core.ui.builder.UIEventBuilder;
import com.hypixel.hytale.server.core.ui.builder.UICommandBuilder;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.component.Ref;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import com.hypixel.hytale.server.core.ui.browser.FileBrowserConfig;
import com.hypixel.hytale.protocol.packets.interface_.CustomPageLifetime;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import javax.annotation.Nonnull;
import com.hypixel.hytale.server.core.ui.browser.ServerFileBrowser;
import javax.annotation.Nullable;
import com.hypixel.hytale.server.core.ui.Value;
import com.hypixel.hytale.server.core.entity.entities.player.pages.InteractiveCustomUIPage;

public class InstanceListPage extends InteractiveCustomUIPage<PageData>
{
    private static final String COMMON_TEXT_BUTTON_DOCUMENT = "Pages/BasicTextButton.ui";
    private static final Value<String> BUTTON_LABEL_STYLE;
    private static final Value<String> BUTTON_LABEL_STYLE_SELECTED;
    private static final String ASSET_PACK_SUB_PATH = "Server/Instances";
    @Nullable
    private String selectedInstance;
    @Nonnull
    private final ServerFileBrowser browser;
    static final /* synthetic */ boolean $assertionsDisabled;
    
    public InstanceListPage(@Nonnull final PlayerRef playerRef) {
        super(playerRef, CustomPageLifetime.CanDismiss, PageData.CODEC);
        final FileBrowserConfig config = FileBrowserConfig.builder().listElementId("#List").searchInputId("#SearchInput").currentPathId("#CurrentPath").enableRootSelector(false).enableSearch(true).enableDirectoryNav(true).maxResults(50).assetPackMode(true, "Server/Instances").terminalDirectoryPredicate(path -> Files.exists(path.resolve("instance.bson"), new LinkOption[0])).build();
        this.browser = new ServerFileBrowser(config);
    }
    
    @Override
    public void build(@Nonnull final Ref<EntityStore> ref, @Nonnull final UICommandBuilder commandBuilder, @Nonnull final UIEventBuilder eventBuilder, @Nonnull final Store<EntityStore> store) {
        commandBuilder.append("Pages/InstanceListPage.ui");
        eventBuilder.addEventBinding(CustomUIEventBindingType.Activating, "#Spawn", EventData.of("Action", Action.Spawn.toString()));
        eventBuilder.addEventBinding(CustomUIEventBindingType.Activating, "#Load", EventData.of("Action", Action.Load.toString()));
        commandBuilder.set("#Load.Visible", !AssetModule.get().getBaseAssetPack().isImmutable());
        this.browser.buildCurrentPath(commandBuilder);
        this.browser.buildSearchInput(commandBuilder, eventBuilder);
        this.browser.buildFileList(commandBuilder, eventBuilder);
        commandBuilder.set("#Name.Text", (this.selectedInstance != null) ? this.selectedInstance : "");
        commandBuilder.set("#Name.Visible", this.selectedInstance != null);
        commandBuilder.set("#Spawn.Disabled", this.selectedInstance == null);
        commandBuilder.set("#Load.Disabled", this.selectedInstance == null);
    }
    
    @Override
    public void handleDataEvent(@Nonnull final Ref<EntityStore> ref, @Nonnull final Store<EntityStore> store, @Nonnull final PageData data) {
        if (data.searchQuery != null) {
            this.browser.setSearchQuery(data.searchQuery.trim().toLowerCase());
            final UICommandBuilder commandBuilder = new UICommandBuilder();
            final UIEventBuilder eventBuilder = new UIEventBuilder();
            this.browser.buildCurrentPath(commandBuilder);
            this.browser.buildFileList(commandBuilder, eventBuilder);
            this.sendUpdate(commandBuilder, eventBuilder, false);
            return;
        }
        if (data.searchResult != null) {
            final Path resolvedPath = this.browser.resolveAssetPackPath(data.searchResult);
            if (resolvedPath != null && this.isInstance(resolvedPath)) {
                this.updateSelection(data.searchResult);
            }
            return;
        }
        if (data.file == null) {
            if (data.getAction() != null) {
                switch (data.getAction().ordinal()) {
                    case 1: {
                        if (this.selectedInstance != null) {
                            this.load(ref, store);
                            this.close();
                            break;
                        }
                        break;
                    }
                    case 2: {
                        if (this.selectedInstance != null) {
                            this.spawn(ref, store);
                            this.close();
                            break;
                        }
                        break;
                    }
                }
            }
            return;
        }
        final String fileName = data.file;
        if ("..".equals(fileName)) {
            this.browser.navigateUp();
            this.selectedInstance = null;
            final UICommandBuilder commandBuilder2 = new UICommandBuilder();
            final UIEventBuilder eventBuilder2 = new UIEventBuilder();
            this.browser.buildCurrentPath(commandBuilder2);
            this.browser.buildFileList(commandBuilder2, eventBuilder2);
            commandBuilder2.set("#Name.Text", "");
            commandBuilder2.set("#Name.Visible", false);
            commandBuilder2.set("#Spawn.Disabled", true);
            commandBuilder2.set("#Load.Disabled", true);
            this.sendUpdate(commandBuilder2, eventBuilder2, false);
            return;
        }
        if (this.browser.handleEvent(FileBrowserEventData.file(fileName))) {
            this.selectedInstance = null;
            final UICommandBuilder commandBuilder2 = new UICommandBuilder();
            final UIEventBuilder eventBuilder2 = new UIEventBuilder();
            this.browser.buildCurrentPath(commandBuilder2);
            this.browser.buildFileList(commandBuilder2, eventBuilder2);
            commandBuilder2.set("#Name.Text", "");
            commandBuilder2.set("#Name.Visible", false);
            commandBuilder2.set("#Spawn.Disabled", true);
            commandBuilder2.set("#Load.Disabled", true);
            this.sendUpdate(commandBuilder2, eventBuilder2, false);
        }
        else {
            final String virtualPath = this.browser.getAssetPackCurrentPath().isEmpty() ? fileName : (this.browser.getAssetPackCurrentPath() + "/" + fileName);
            final Path resolvedPath2 = this.browser.resolveAssetPackPath(virtualPath);
            if (resolvedPath2 != null && this.isInstance(resolvedPath2)) {
                this.updateSelection(virtualPath);
            }
        }
    }
    
    private boolean isInstance(@Nonnull final Path path) {
        return Files.isDirectory(path, new LinkOption[0]) && Files.exists(path.resolve("instance.bson"), new LinkOption[0]);
    }
    
    private void load(@Nonnull final Ref<EntityStore> ref, @Nonnull final Store<EntityStore> store) {
        final String instanceName = this.getInstanceNameFromVirtualPath(this.selectedInstance);
        if (instanceName == null) {
            return;
        }
        InstancesPlugin.get();
        InstancesPlugin.loadInstanceAssetForEdit(instanceName).thenAccept(world -> {
            final Store<EntityStore> playerStore = ref.getStore();
            final World playerWorld = playerStore.getExternalData().getWorld();
            playerWorld.execute(() -> {
                final Transform spawnTransform = world.getWorldConfig().getSpawnProvider().getSpawnPoint(ref, playerStore);
                final Teleport teleportComponent = Teleport.createForPlayer(world, spawnTransform);
                playerStore.addComponent(ref, Teleport.getComponentType(), teleportComponent);
            });
        }).exceptionally(ex -> {
            ex.printStackTrace();
            return null;
        });
    }
    
    private void spawn(@Nonnull final Ref<EntityStore> ref, @Nonnull final Store<EntityStore> store) {
        final String instanceName = this.getInstanceNameFromVirtualPath(this.selectedInstance);
        if (instanceName == null) {
            return;
        }
        final World world = store.getExternalData().getWorld();
        world.execute(() -> {
            final TransformComponent transformComponent = store.getComponent(ref, TransformComponent.getComponentType());
            final HeadRotation headRotationComponent = store.getComponent(ref, HeadRotation.getComponentType());
            if (!InstanceListPage.$assertionsDisabled && transformComponent == null) {
                throw new AssertionError();
            }
            else {
                final Vector3d position = transformComponent.getPosition();
                final Transform returnLocation = new Transform(position.clone(), headRotationComponent.getRotation().clone());
                final CompletableFuture<World> instanceWorld = InstancesPlugin.get().spawnInstance(instanceName, world, returnLocation);
                InstancesPlugin.teleportPlayerToLoadingInstance(ref, store, instanceWorld, null);
            }
        });
    }
    
    @Nullable
    private String getInstanceNameFromVirtualPath(@Nullable final String virtualPath) {
        if (virtualPath == null || virtualPath.isEmpty()) {
            return null;
        }
        final String normalizedPath = virtualPath.replace('\\', '/');
        final String[] parts = normalizedPath.split("/", 2);
        return (parts.length > 1) ? parts[1] : normalizedPath;
    }
    
    private void updateSelection(@Nonnull final String virtualPath) {
        this.selectedInstance = virtualPath;
        final UICommandBuilder commandBuilder = new UICommandBuilder();
        final String displayName = virtualPath.contains("/") ? virtualPath.substring(virtualPath.lastIndexOf(47) + 1) : virtualPath;
        commandBuilder.set("#Name.Text", displayName);
        commandBuilder.set("#Name.Visible", true);
        commandBuilder.set("#Spawn.Disabled", false);
        commandBuilder.set("#Load.Disabled", false);
        this.sendUpdate(commandBuilder, false);
    }
    
    static {
        BUTTON_LABEL_STYLE = Value.ref("Pages/BasicTextButton.ui", "LabelStyle");
        BUTTON_LABEL_STYLE_SELECTED = Value.ref("Pages/BasicTextButton.ui", "SelectedLabelStyle");
    }
    
    public static class PageData
    {
        public static final String KEY_INSTANCE = "Instance";
        public static final String KEY_ACTION = "Action";
        public static final BuilderCodec<PageData> CODEC;
        private String instance;
        private Action action;
        @Nullable
        private String file;
        @Nullable
        private String searchQuery;
        @Nullable
        private String searchResult;
        
        public String getInstance() {
            return this.instance;
        }
        
        public Action getAction() {
            return this.action;
        }
        
        static {
            // 
            // This method could not be decompiled.
            // 
            // Original Bytecode:
            // 
            //     2: invokedynamic   BootstrapMethod #0, get:()Ljava/util/function/Supplier;
            //     7: invokestatic    com/hypixel/hytale/codec/builder/BuilderCodec.builder:(Ljava/lang/Class;Ljava/util/function/Supplier;)Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //    10: new             Lcom/hypixel/hytale/codec/KeyedCodec;
            //    13: dup            
            //    14: ldc             "Instance"
            //    16: getstatic       com/hypixel/hytale/codec/builder/BuilderCodec.STRING:Lcom/hypixel/hytale/codec/codecs/simple/StringCodec;
            //    19: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
            //    22: invokedynamic   BootstrapMethod #1, accept:()Ljava/util/function/BiConsumer;
            //    27: invokedynamic   BootstrapMethod #2, apply:()Ljava/util/function/Function;
            //    32: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.addField:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
            //    35: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //    38: new             Lcom/hypixel/hytale/codec/KeyedCodec;
            //    41: dup            
            //    42: ldc             "Action"
            //    44: new             Lcom/hypixel/hytale/codec/codecs/EnumCodec;
            //    47: dup            
            //    48: ldc             Lcom/hypixel/hytale/builtin/instances/page/InstanceListPage$Action;.class
            //    50: invokespecial   com/hypixel/hytale/codec/codecs/EnumCodec.<init>:(Ljava/lang/Class;)V
            //    53: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
            //    56: invokedynamic   BootstrapMethod #3, accept:()Ljava/util/function/BiConsumer;
            //    61: invokedynamic   BootstrapMethod #4, apply:()Ljava/util/function/Function;
            //    66: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.addField:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
            //    69: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //    72: new             Lcom/hypixel/hytale/codec/KeyedCodec;
            //    75: dup            
            //    76: ldc             "File"
            //    78: getstatic       com/hypixel/hytale/codec/Codec.STRING:Lcom/hypixel/hytale/codec/codecs/simple/StringCodec;
            //    81: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
            //    84: invokedynamic   BootstrapMethod #5, accept:()Ljava/util/function/BiConsumer;
            //    89: invokedynamic   BootstrapMethod #6, apply:()Ljava/util/function/Function;
            //    94: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.addField:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
            //    97: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //   100: new             Lcom/hypixel/hytale/codec/KeyedCodec;
            //   103: dup            
            //   104: ldc             "@SearchQuery"
            //   106: getstatic       com/hypixel/hytale/codec/Codec.STRING:Lcom/hypixel/hytale/codec/codecs/simple/StringCodec;
            //   109: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
            //   112: invokedynamic   BootstrapMethod #7, accept:()Ljava/util/function/BiConsumer;
            //   117: invokedynamic   BootstrapMethod #8, apply:()Ljava/util/function/Function;
            //   122: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.addField:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
            //   125: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //   128: new             Lcom/hypixel/hytale/codec/KeyedCodec;
            //   131: dup            
            //   132: ldc             "SearchResult"
            //   134: getstatic       com/hypixel/hytale/codec/Codec.STRING:Lcom/hypixel/hytale/codec/codecs/simple/StringCodec;
            //   137: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
            //   140: invokedynamic   BootstrapMethod #9, accept:()Ljava/util/function/BiConsumer;
            //   145: invokedynamic   BootstrapMethod #10, apply:()Ljava/util/function/Function;
            //   150: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.addField:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
            //   153: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //   156: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.build:()Lcom/hypixel/hytale/codec/builder/BuilderCodec;
            //   159: putstatic       com/hypixel/hytale/builtin/instances/page/InstanceListPage$PageData.CODEC:Lcom/hypixel/hytale/codec/builder/BuilderCodec;
            //   162: return         
            // 
            // The error that occurred was:
            // 
            // java.lang.UnsupportedOperationException: The requested operation is not supported.
            //     at com.strobel.util.ContractUtils.unsupported(ContractUtils.java:27)
            //     at com.strobel.assembler.metadata.TypeReference.getRawType(TypeReference.java:284)
            //     at com.strobel.assembler.metadata.TypeReference.getRawType(TypeReference.java:279)
            //     at com.strobel.assembler.metadata.TypeReference.makeGenericType(TypeReference.java:154)
            //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitParameterizedType(TypeSubstitutionVisitor.java:225)
            //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitParameterizedType(TypeSubstitutionVisitor.java:25)
            //     at com.strobel.assembler.metadata.ParameterizedType.accept(ParameterizedType.java:103)
            //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visit(TypeSubstitutionVisitor.java:40)
            //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitMethod(TypeSubstitutionVisitor.java:314)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2611)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1083)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.runInference(TypeAnalysis.java:684)
            //     at com.strobel.decompiler.ast.TypeAnalysis.runInference(TypeAnalysis.java:667)
            //     at com.strobel.decompiler.ast.TypeAnalysis.runInference(TypeAnalysis.java:373)
            //     at com.strobel.decompiler.ast.TypeAnalysis.run(TypeAnalysis.java:95)
            //     at com.strobel.decompiler.ast.AstOptimizer.optimize(AstOptimizer.java:344)
            //     at com.strobel.decompiler.ast.AstOptimizer.optimize(AstOptimizer.java:42)
            //     at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.createMethodBody(AstMethodBodyBuilder.java:206)
            //     at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.createMethodBody(AstMethodBodyBuilder.java:93)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createMethodBody(AstBuilder.java:868)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createMethod(AstBuilder.java:761)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.addTypeMembers(AstBuilder.java:638)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeCore(AstBuilder.java:605)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeNoCache(AstBuilder.java:195)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.addTypeMembers(AstBuilder.java:662)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeCore(AstBuilder.java:605)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeNoCache(AstBuilder.java:195)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createType(AstBuilder.java:162)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.addType(AstBuilder.java:137)
            //     at com.strobel.decompiler.languages.java.JavaLanguage.buildAst(JavaLanguage.java:71)
            //     at com.strobel.decompiler.languages.java.JavaLanguage.decompileType(JavaLanguage.java:59)
            //     at com.strobel.decompiler.DecompilerDriver.decompileType(DecompilerDriver.java:333)
            //     at com.strobel.decompiler.DecompilerDriver.decompileJar(DecompilerDriver.java:254)
            //     at com.strobel.decompiler.DecompilerDriver.main(DecompilerDriver.java:129)
            // 
            throw new IllegalStateException("An error occurred while decompiling this method.");
        }
    }
    
    public enum Action
    {
        Select, 
        Load, 
        Spawn;
    }
}
