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

package com.hypixel.hytale.builtin.buildertools.prefabeditor.ui;

import com.hypixel.hytale.codec.builder.BuilderCodec;
import com.hypixel.hytale.server.core.prefab.PrefabStore;
import java.util.stream.Stream;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import java.util.Map;
import java.util.function.ToIntFunction;
import java.util.Comparator;
import java.util.Objects;
import com.hypixel.hytale.common.util.StringCompareUtil;
import java.util.Locale;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import java.nio.file.Path;
import com.hypixel.hytale.server.core.universe.world.World;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import com.hypixel.hytale.protocol.packets.interface_.Page;
import com.hypixel.hytale.server.core.command.system.CommandSender;
import com.hypixel.hytale.builtin.buildertools.prefabeditor.saving.PrefabSaver;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.CompletableFuture;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import com.hypixel.hytale.builtin.buildertools.prefabeditor.saving.PrefabSaverSettings;
import com.hypixel.hytale.server.core.entity.entities.Player;
import com.hypixel.hytale.builtin.buildertools.prefabeditor.PrefabEditingMetadata;
import com.hypixel.hytale.server.core.ui.builder.EventData;
import com.hypixel.hytale.protocol.packets.interface_.CustomUIEventBindingType;
import com.hypixel.hytale.server.core.Message;
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.util.HashSet;
import com.hypixel.hytale.protocol.packets.interface_.CustomPageLifetime;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import java.util.UUID;
import java.util.Set;
import javax.annotation.Nonnull;
import com.hypixel.hytale.builtin.buildertools.prefabeditor.PrefabEditSession;
import com.hypixel.hytale.server.core.ui.Value;
import com.hypixel.hytale.logger.HytaleLogger;
import com.hypixel.hytale.server.core.entity.entities.player.pages.InteractiveCustomUIPage;

public class PrefabEditorSaveSettingsPage extends InteractiveCustomUIPage<PageData>
{
    private static final HytaleLogger LOGGER;
    private static final Value<String> BUTTON_HIGHLIGHTED;
    private static final Value<String> BUTTON_SELECTED;
    @Nonnull
    private final PrefabEditSession prefabEditSession;
    private volatile boolean isSaving;
    private volatile long lastProgressUpdateTime;
    private static final long PROGRESS_UPDATE_INTERVAL_MS = 100L;
    @Nonnull
    private String browserSearchQuery;
    private final Set<UUID> selectedPrefabUuids;
    
    public PrefabEditorSaveSettingsPage(@Nonnull final PlayerRef playerRef, @Nonnull final PrefabEditSession prefabEditSession) {
        super(playerRef, CustomPageLifetime.CanDismissOrCloseThroughInteraction, PageData.CODEC);
        this.isSaving = false;
        this.lastProgressUpdateTime = 0L;
        this.browserSearchQuery = "";
        this.selectedPrefabUuids = new HashSet<UUID>();
        this.prefabEditSession = prefabEditSession;
    }
    
    @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/PrefabEditorSaveSettings.ui");
        final PrefabEditingMetadata selectedPrefab = this.prefabEditSession.getSelectedPrefab(this.playerRef.getUuid());
        if (selectedPrefab != null) {
            final String prefabPath = selectedPrefab.getPrefabPath().toString().replace('\\', '/');
            commandBuilder.set("#MainPage #PrefabsToSave #Input.Value", prefabPath);
            this.selectedPrefabUuids.add(selectedPrefab.getUuid());
        }
        commandBuilder.set("#MainPage #Entities #CheckBox.Value", true);
        commandBuilder.set("#MainPage #Empty #CheckBox.Value", false);
        commandBuilder.set("#MainPage #Overwrite #CheckBox.Value", true);
        commandBuilder.set("#SavingPage.Visible", false);
        commandBuilder.set("#SavingPage #ProgressBar.Value", 0.0f);
        commandBuilder.set("#SavingPage #StatusText.TextSpans", Message.translation("server.commands.editprefab.save.saving"));
        commandBuilder.set("#SavingPage #ErrorText.Visible", false);
        eventBuilder.addEventBinding(CustomUIEventBindingType.Activating, "#MainPage #SaveButton", new EventData().append("Action", Action.Save.name()).append("@PrefabsToSave", "#MainPage #PrefabsToSave #Input.Value").append("@Entities", "#MainPage #Entities #CheckBox.Value").append("@Empty", "#MainPage #Empty #CheckBox.Value").append("@Overwrite", "#MainPage #Overwrite #CheckBox.Value"));
        eventBuilder.addEventBinding(CustomUIEventBindingType.Activating, "#MainPage #CancelButton", new EventData().append("Action", Action.Cancel.name()));
        eventBuilder.addEventBinding(CustomUIEventBindingType.Activating, "#MainPage #PrefabsToSave #BrowseButton", new EventData().append("Action", Action.OpenBrowser.name()));
        eventBuilder.addEventBinding(CustomUIEventBindingType.Activating, "#MainPage #PrefabsToSave #SelectAllButton", new EventData().append("Action", Action.SelectAll.name()));
        eventBuilder.addEventBinding(CustomUIEventBindingType.Activating, "#MainPage #PrefabsToSave #SelectEditedButton", new EventData().append("Action", Action.SelectEdited.name()));
        eventBuilder.addEventBinding(CustomUIEventBindingType.ValueChanged, "#BrowserPage #SearchInput", new EventData().append("Action", Action.BrowserSearch.name()).append("@BrowserSearch", "#BrowserPage #SearchInput.Value"), false);
        eventBuilder.addEventBinding(CustomUIEventBindingType.Activating, "#BrowserPage #BrowserButtons #SelectAllBrowserButton", new EventData().append("Action", Action.BrowserSelectAll.name()));
        eventBuilder.addEventBinding(CustomUIEventBindingType.Activating, "#BrowserPage #BrowserButtons #ConfirmButton", new EventData().append("Action", Action.ConfirmBrowser.name()));
        eventBuilder.addEventBinding(CustomUIEventBindingType.Activating, "#BrowserPage #BrowserButtons #CancelButton", new EventData().append("Action", Action.CancelBrowser.name()));
        eventBuilder.addEventBinding(CustomUIEventBindingType.Activating, "#SavingPage #BackButton", new EventData().append("Action", Action.BackFromSaving.name()));
        commandBuilder.set("#BrowserPage.Visible", false);
    }
    
    @Override
    public void handleDataEvent(@Nonnull final Ref<EntityStore> ref, @Nonnull final Store<EntityStore> store, @Nonnull final PageData data) {
        final Player playerComponent = store.getComponent(ref, Player.getComponentType());
        assert playerComponent != null;
        switch (data.action.ordinal()) {
            case 0: {
                if (this.isSaving) {
                    return;
                }
                final String prefabsToSaveStr = data.prefabsToSave;
                if (prefabsToSaveStr == null || prefabsToSaveStr.isBlank()) {
                    this.playerRef.sendMessage(Message.translation("server.commands.editprefab.save.noPrefabsSelected"));
                    return;
                }
                this.isSaving = true;
                final UICommandBuilder showSavingBuilder = new UICommandBuilder();
                showSavingBuilder.set("#MainPage.Visible", false);
                showSavingBuilder.set("#BrowserPage.Visible", false);
                showSavingBuilder.set("#SavingPage.Visible", true);
                showSavingBuilder.set("#SavingPage #ProgressBar.Value", 0.0f);
                showSavingBuilder.set("#SavingPage #StatusText.TextSpans", Message.translation("server.commands.editprefab.save.saving"));
                showSavingBuilder.set("#SavingPage #ErrorText.Visible", false);
                showSavingBuilder.set("#SavingPage #BackButton.Visible", false);
                this.sendUpdate(showSavingBuilder);
                final PrefabSaverSettings prefabSaverSettings = new PrefabSaverSettings();
                prefabSaverSettings.setBlocks(true);
                prefabSaverSettings.setEntities(data.entities);
                prefabSaverSettings.setEmpty(data.empty);
                prefabSaverSettings.setOverwriteExisting(data.overwrite);
                final String[] prefabPaths = prefabsToSaveStr.split(",");
                final List<PrefabEditingMetadata> prefabsToSave = new ObjectArrayList<PrefabEditingMetadata>();
                for (String pathStr : prefabPaths) {
                    pathStr = pathStr.trim();
                    if (!pathStr.isEmpty()) {
                        for (final PrefabEditingMetadata metadata : this.prefabEditSession.getLoadedPrefabMetadata().values()) {
                            final String prefabPath = metadata.getPrefabPath().toString().replace('\\', '/');
                            if (prefabPath.equals(pathStr) || prefabPath.endsWith(pathStr)) {
                                prefabsToSave.add(metadata);
                                break;
                            }
                        }
                    }
                }
                if (prefabsToSave.isEmpty()) {
                    this.onSavingFailed(Message.translation("server.commands.editprefab.save.noPrefabsFound"));
                    return;
                }
                int readOnlyCount = 0;
                for (final PrefabEditingMetadata metadata2 : prefabsToSave) {
                    if (metadata2.isReadOnly()) {
                        ++readOnlyCount;
                    }
                }
                if (readOnlyCount > 0) {
                    this.playerRef.sendMessage(Message.translation("server.commands.editprefab.save.readOnlyRedirect").param("count", readOnlyCount));
                }
                final World world = store.getExternalData().getWorld();
                final int totalPrefabs = prefabsToSave.size();
                final CompletableFuture<Boolean>[] saveFutures = new CompletableFuture[totalPrefabs];
                final AtomicInteger completedCount = new AtomicInteger(0);
                this.lastProgressUpdateTime = 0L;
                for (int i = 0; i < totalPrefabs; ++i) {
                    final PrefabEditingMetadata metadata3 = prefabsToSave.get(i);
                    final Path savePath = this.getWritableSavePath(metadata3);
                    saveFutures[i] = PrefabSaver.savePrefab(playerComponent, world, savePath, metadata3.getAnchorPoint(), metadata3.getMinPoint(), metadata3.getMaxPoint(), metadata3.getPastePosition(), metadata3.getOriginalFileAnchor(), prefabSaverSettings).thenApply(success -> {
                        final int completed = completedCount.incrementAndGet();
                        final long now = System.currentTimeMillis();
                        if (now - this.lastProgressUpdateTime >= 100L || completed == totalPrefabs) {
                            this.lastProgressUpdateTime = now;
                            final float progress = completed / (float)totalPrefabs;
                            final UICommandBuilder progressBuilder = new UICommandBuilder();
                            progressBuilder.set("#SavingPage #ProgressBar.Value", progress);
                            progressBuilder.set("#SavingPage #StatusText.TextSpans", Message.translation("server.commands.editprefab.save.progress").param("current", completed).param("total", totalPrefabs));
                            this.sendUpdate(progressBuilder);
                        }
                        return success;
                    });
                }
                CompletableFuture.allOf((CompletableFuture<?>[])saveFutures).thenAccept(unused -> {
                    int successes = 0;
                    int failures = 0;
                    for (final CompletableFuture<Boolean> future : saveFutures) {
                        if (future.join()) {
                            ++successes;
                        }
                        else {
                            ++failures;
                        }
                    }
                    this.isSaving = false;
                    if (failures == 0) {
                        this.playerRef.sendMessage(Message.translation("server.commands.editprefab.save.saveAll.success").param("successes", successes).param("failures", failures));
                        playerComponent.getPageManager().setPage(ref, store, Page.None);
                    }
                    else {
                        this.onSavingFailed(Message.translation("server.commands.editprefab.save.saveAll.success").param("successes", successes).param("failures", failures));
                    }
                    return;
                }).exceptionally(throwable -> {
                    this.isSaving = false;
                    PrefabEditorSaveSettingsPage.LOGGER.atWarning().withCause(throwable).log("Error saving prefabs");
                    this.onSavingFailed(Message.raw((throwable.getMessage() != null) ? throwable.getMessage() : "Unknown error"));
                    return null;
                });
                break;
            }
            case 1: {
                playerComponent.getPageManager().setPage(ref, store, Page.None);
                break;
            }
            case 2: {
                final String allPaths = this.prefabEditSession.getLoadedPrefabMetadata().values().stream().map(m -> m.getPrefabPath().toString().replace('\\', '/')).collect((Collector<? super Object, ?, String>)Collectors.joining(","));
                final UICommandBuilder commandBuilder = new UICommandBuilder();
                commandBuilder.set("#MainPage #PrefabsToSave #Input.Value", allPaths);
                this.sendUpdate(commandBuilder);
                break;
            }
            case 3: {
                final String editedPaths = this.prefabEditSession.getLoadedPrefabMetadata().values().stream().filter(PrefabEditingMetadata::isDirty).map(m -> m.getPrefabPath().toString().replace('\\', '/')).collect((Collector<? super Object, ?, String>)Collectors.joining(","));
                final UICommandBuilder commandBuilder = new UICommandBuilder();
                commandBuilder.set("#MainPage #PrefabsToSave #Input.Value", editedPaths);
                this.sendUpdate(commandBuilder);
                if (editedPaths.isEmpty()) {
                    this.playerRef.sendMessage(Message.translation("server.commands.editprefab.save.noEditedPrefabs"));
                }
                break;
            }
            case 4: {
                this.browserSearchQuery = "";
                this.selectedPrefabUuids.clear();
                final UICommandBuilder commandBuilder2 = new UICommandBuilder();
                final UIEventBuilder eventBuilder = new UIEventBuilder();
                commandBuilder2.set("#MainPage.Visible", false);
                commandBuilder2.set("#BrowserPage.Visible", true);
                commandBuilder2.set("#BrowserPage #SearchInput.Value", "");
                this.buildPrefabList(commandBuilder2, eventBuilder);
                this.sendUpdate(commandBuilder2, eventBuilder, false);
                break;
            }
            case 5: {
                this.browserSearchQuery = ((data.browserSearchStr != null) ? data.browserSearchStr.trim().toLowerCase() : "");
                final UICommandBuilder commandBuilder2 = new UICommandBuilder();
                final UIEventBuilder eventBuilder = new UIEventBuilder();
                this.buildPrefabList(commandBuilder2, eventBuilder);
                this.sendUpdate(commandBuilder2, eventBuilder, false);
                break;
            }
            case 6: {
                if (data.prefabUuid != null) {
                    try {
                        final UUID uuid = UUID.fromString(data.prefabUuid);
                        if (this.selectedPrefabUuids.contains(uuid)) {
                            this.selectedPrefabUuids.remove(uuid);
                        }
                        else {
                            this.selectedPrefabUuids.add(uuid);
                        }
                        final UICommandBuilder commandBuilder = new UICommandBuilder();
                        final UIEventBuilder eventBuilder2 = new UIEventBuilder();
                        this.buildPrefabList(commandBuilder, eventBuilder2);
                        this.sendUpdate(commandBuilder, eventBuilder2, false);
                    }
                    catch (final IllegalArgumentException ex) {}
                    break;
                }
                break;
            }
            case 7: {
                this.selectedPrefabUuids.clear();
                for (final PrefabEditingMetadata metadata4 : this.prefabEditSession.getLoadedPrefabMetadata().values()) {
                    this.selectedPrefabUuids.add(metadata4.getUuid());
                }
                final UICommandBuilder commandBuilder2 = new UICommandBuilder();
                final UIEventBuilder eventBuilder = new UIEventBuilder();
                this.buildPrefabList(commandBuilder2, eventBuilder);
                this.sendUpdate(commandBuilder2, eventBuilder, false);
                break;
            }
            case 8: {
                final List<String> selectedPaths = new ObjectArrayList<String>();
                for (final PrefabEditingMetadata metadata5 : this.prefabEditSession.getLoadedPrefabMetadata().values()) {
                    if (this.selectedPrefabUuids.contains(metadata5.getUuid())) {
                        selectedPaths.add(metadata5.getPrefabPath().toString().replace('\\', '/'));
                    }
                }
                final UICommandBuilder commandBuilder = new UICommandBuilder();
                commandBuilder.set("#MainPage #PrefabsToSave #Input.Value", String.join(",", selectedPaths));
                commandBuilder.set("#BrowserPage.Visible", false);
                commandBuilder.set("#MainPage.Visible", true);
                this.sendUpdate(commandBuilder);
                break;
            }
            case 9: {
                final UICommandBuilder commandBuilder2 = new UICommandBuilder();
                commandBuilder2.set("#BrowserPage.Visible", false);
                commandBuilder2.set("#MainPage.Visible", true);
                this.sendUpdate(commandBuilder2);
                break;
            }
            case 10: {
                this.isSaving = false;
                final UICommandBuilder commandBuilder2 = new UICommandBuilder();
                commandBuilder2.set("#SavingPage.Visible", false);
                commandBuilder2.set("#MainPage.Visible", true);
                this.sendUpdate(commandBuilder2);
                break;
            }
        }
    }
    
    private void buildPrefabList(@Nonnull final UICommandBuilder commandBuilder, @Nonnull final UIEventBuilder eventBuilder) {
        commandBuilder.clear("#BrowserPage #FileList");
        final Map<UUID, PrefabEditingMetadata> loadedPrefabs = this.prefabEditSession.getLoadedPrefabMetadata();
        if (loadedPrefabs.isEmpty()) {
            return;
        }
        List<PrefabEditingMetadata> prefabsToDisplay;
        if (!this.browserSearchQuery.isEmpty()) {
            final Object2IntMap<PrefabEditingMetadata> matchScores = new Object2IntOpenHashMap<PrefabEditingMetadata>(loadedPrefabs.size());
            for (final PrefabEditingMetadata metadata : loadedPrefabs.values()) {
                final String fileName = metadata.getPrefabPath().getFileName().toString();
                final String baseName = fileName.endsWith(".prefab.json") ? fileName.substring(0, fileName.length() - ".prefab.json".length()) : fileName;
                final int fuzzyDistance = StringCompareUtil.getFuzzyDistance(baseName, this.browserSearchQuery, Locale.ENGLISH);
                if (fuzzyDistance > 0) {
                    matchScores.put(metadata, fuzzyDistance);
                }
            }
            final Stream<Object> stream = matchScores.keySet().stream();
            final Object2IntMap<PrefabEditingMetadata> obj = matchScores;
            Objects.requireNonNull((Object2IntOpenHashMap)obj);
            prefabsToDisplay = stream.sorted(Comparator.comparingInt(obj::getInt).reversed()).collect((Collector<? super Object, ?, List<PrefabEditingMetadata>>)Collectors.toList());
        }
        else {
            prefabsToDisplay = loadedPrefabs.values().stream().sorted(Comparator.comparing(m -> m.getPrefabPath().getFileName().toString().toLowerCase())).collect((Collector<? super PrefabEditingMetadata, ?, List<PrefabEditingMetadata>>)Collectors.toList());
        }
        int buttonIndex = 0;
        for (PrefabEditingMetadata metadata : prefabsToDisplay) {
            final Path prefabPath = metadata.getPrefabPath();
            final String fileName2 = prefabPath.getFileName().toString();
            final String displayName = fileName2.endsWith(".prefab.json") ? fileName2.substring(0, fileName2.length() - ".prefab.json".length()) : fileName2;
            final boolean isSelected = this.selectedPrefabUuids.contains(metadata.getUuid());
            final boolean isReadOnly = metadata.isReadOnly();
            final String checkPrefix = isSelected ? "[x] " : "[ ] ";
            final String readOnlySuffix = isReadOnly ? " (read-only)" : "";
            final String displayText = checkPrefix + displayName + readOnlySuffix;
            final String relativePath = prefabPath.toString().replace('\\', '/');
            final String tooltipText = isReadOnly ? (relativePath + "\n(Will save to Server/Prefabs)") : relativePath;
            commandBuilder.append("#BrowserPage #FileList", "Pages/BasicTextButton.ui");
            commandBuilder.set("#BrowserPage #FileList[" + buttonIndex + "].Text", displayText);
            commandBuilder.set("#BrowserPage #FileList[" + buttonIndex + "].TooltipText", tooltipText);
            if (isSelected) {
                commandBuilder.set("#BrowserPage #FileList[" + buttonIndex + "].Style", PrefabEditorSaveSettingsPage.BUTTON_SELECTED);
            }
            eventBuilder.addEventBinding(CustomUIEventBindingType.Activating, "#BrowserPage #FileList[" + buttonIndex, new EventData().append("Action", Action.BrowserTogglePrefab.name()).append("PrefabUuid", metadata.getUuid().toString()));
            ++buttonIndex;
        }
    }
    
    @Nonnull
    private Path getWritableSavePath(@Nonnull final PrefabEditingMetadata metadata) {
        if (!metadata.isReadOnly()) {
            return metadata.getPrefabPath();
        }
        final Path originalPath = metadata.getPrefabPath();
        final String fileName = originalPath.getFileName().toString();
        final Path parent = originalPath.getParent();
        if (parent != null && parent.getFileName() != null) {
            final String parentName = parent.getFileName().toString();
            return PrefabStore.get().getServerPrefabsPath().resolve(parentName).resolve(fileName);
        }
        return PrefabStore.get().getServerPrefabsPath().resolve(fileName);
    }
    
    private void onSavingFailed(@Nonnull final Message errorMessage) {
        this.isSaving = false;
        final UICommandBuilder builder = new UICommandBuilder();
        builder.set("#SavingPage #ProgressBar.Value", 0.0f);
        builder.set("#SavingPage #StatusText.TextSpans", Message.translation("server.commands.editprefab.save.error"));
        builder.set("#SavingPage #ErrorText.Visible", true);
        builder.set("#SavingPage #ErrorText.TextSpans", errorMessage);
        builder.set("#SavingPage #BackButton.Visible", true);
        this.sendUpdate(builder);
    }
    
    static {
        LOGGER = HytaleLogger.forEnclosingClass();
        BUTTON_HIGHLIGHTED = Value.ref("Pages/BasicTextButton.ui", "SelectedLabelStyle");
        BUTTON_SELECTED = Value.ref("Pages/BasicTextButton.ui", "SelectedLabelStyle");
    }
    
    protected static class PageData
    {
        public static final String PREFABS_TO_SAVE = "@PrefabsToSave";
        public static final String ENTITIES = "@Entities";
        public static final String EMPTY = "@Empty";
        public static final String OVERWRITE = "@Overwrite";
        public static final String BROWSER_SEARCH = "@BrowserSearch";
        public static final String PREFAB_UUID = "PrefabUuid";
        public static final BuilderCodec<PageData> CODEC;
        public Action action;
        public String prefabsToSave;
        public boolean entities;
        public boolean empty;
        public boolean overwrite;
        public String browserSearchStr;
        public String prefabUuid;
        
        public PageData() {
            this.entities = true;
            this.empty = false;
            this.overwrite = true;
        }
        
        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             "Action"
            //    16: new             Lcom/hypixel/hytale/codec/codecs/EnumCodec;
            //    19: dup            
            //    20: ldc             Lcom/hypixel/hytale/builtin/buildertools/prefabeditor/ui/PrefabEditorSaveSettingsPage$Action;.class
            //    22: getstatic       com/hypixel/hytale/codec/codecs/EnumCodec$EnumStyle.LEGACY:Lcom/hypixel/hytale/codec/codecs/EnumCodec$EnumStyle;
            //    25: invokespecial   com/hypixel/hytale/codec/codecs/EnumCodec.<init>:(Ljava/lang/Class;Lcom/hypixel/hytale/codec/codecs/EnumCodec$EnumStyle;)V
            //    28: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
            //    31: invokedynamic   BootstrapMethod #1, accept:()Ljava/util/function/BiConsumer;
            //    36: invokedynamic   BootstrapMethod #2, apply:()Ljava/util/function/Function;
            //    41: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
            //    44: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
            //    47: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //    50: new             Lcom/hypixel/hytale/codec/KeyedCodec;
            //    53: dup            
            //    54: ldc             "@PrefabsToSave"
            //    56: getstatic       com/hypixel/hytale/codec/Codec.STRING:Lcom/hypixel/hytale/codec/codecs/simple/StringCodec;
            //    59: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
            //    62: invokedynamic   BootstrapMethod #3, accept:()Ljava/util/function/BiConsumer;
            //    67: invokedynamic   BootstrapMethod #4, apply:()Ljava/util/function/Function;
            //    72: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
            //    75: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
            //    78: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //    81: new             Lcom/hypixel/hytale/codec/KeyedCodec;
            //    84: dup            
            //    85: ldc             "@Entities"
            //    87: getstatic       com/hypixel/hytale/codec/Codec.BOOLEAN:Lcom/hypixel/hytale/codec/codecs/simple/BooleanCodec;
            //    90: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
            //    93: invokedynamic   BootstrapMethod #5, accept:()Ljava/util/function/BiConsumer;
            //    98: invokedynamic   BootstrapMethod #6, apply:()Ljava/util/function/Function;
            //   103: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
            //   106: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
            //   109: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //   112: new             Lcom/hypixel/hytale/codec/KeyedCodec;
            //   115: dup            
            //   116: ldc             "@Empty"
            //   118: getstatic       com/hypixel/hytale/codec/Codec.BOOLEAN:Lcom/hypixel/hytale/codec/codecs/simple/BooleanCodec;
            //   121: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
            //   124: invokedynamic   BootstrapMethod #7, accept:()Ljava/util/function/BiConsumer;
            //   129: invokedynamic   BootstrapMethod #8, apply:()Ljava/util/function/Function;
            //   134: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
            //   137: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
            //   140: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //   143: new             Lcom/hypixel/hytale/codec/KeyedCodec;
            //   146: dup            
            //   147: ldc             "@Overwrite"
            //   149: getstatic       com/hypixel/hytale/codec/Codec.BOOLEAN:Lcom/hypixel/hytale/codec/codecs/simple/BooleanCodec;
            //   152: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
            //   155: invokedynamic   BootstrapMethod #9, accept:()Ljava/util/function/BiConsumer;
            //   160: invokedynamic   BootstrapMethod #10, apply:()Ljava/util/function/Function;
            //   165: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
            //   168: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
            //   171: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //   174: new             Lcom/hypixel/hytale/codec/KeyedCodec;
            //   177: dup            
            //   178: ldc             "@BrowserSearch"
            //   180: getstatic       com/hypixel/hytale/codec/Codec.STRING:Lcom/hypixel/hytale/codec/codecs/simple/StringCodec;
            //   183: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
            //   186: invokedynamic   BootstrapMethod #11, accept:()Ljava/util/function/BiConsumer;
            //   191: invokedynamic   BootstrapMethod #12, apply:()Ljava/util/function/Function;
            //   196: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
            //   199: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
            //   202: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //   205: new             Lcom/hypixel/hytale/codec/KeyedCodec;
            //   208: dup            
            //   209: ldc             "PrefabUuid"
            //   211: getstatic       com/hypixel/hytale/codec/Codec.STRING:Lcom/hypixel/hytale/codec/codecs/simple/StringCodec;
            //   214: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
            //   217: invokedynamic   BootstrapMethod #13, accept:()Ljava/util/function/BiConsumer;
            //   222: invokedynamic   BootstrapMethod #14, apply:()Ljava/util/function/Function;
            //   227: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
            //   230: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
            //   233: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //   236: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.build:()Lcom/hypixel/hytale/codec/builder/BuilderCodec;
            //   239: putstatic       com/hypixel/hytale/builtin/buildertools/prefabeditor/ui/PrefabEditorSaveSettingsPage$PageData.CODEC:Lcom/hypixel/hytale/codec/builder/BuilderCodec;
            //   242: 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.visitClassType(TypeSubstitutionVisitor.java:267)
            //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitClassType(TypeSubstitutionVisitor.java:25)
            //     at com.strobel.assembler.metadata.TypeDefinition.accept(TypeDefinition.java:189)
            //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visit(TypeSubstitutionVisitor.java:40)
            //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitMethod(TypeSubstitutionVisitor.java:324)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2586)
            //     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: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: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: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: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: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.inferCall(TypeAnalysis.java:2483)
            //     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:782)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2483)
            //     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
    {
        Save, 
        Cancel, 
        SelectAll, 
        SelectEdited, 
        OpenBrowser, 
        BrowserSearch, 
        BrowserTogglePrefab, 
        BrowserSelectAll, 
        ConfirmBrowser, 
        CancelBrowser, 
        BackFromSaving;
    }
}
