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

package com.hypixel.hytale.server.core.plugin.pages;

import com.hypixel.hytale.codec.builder.BuilderCodec;
import com.hypixel.hytale.server.core.command.system.CommandManager;
import it.unimi.dsi.fastutil.objects.ObjectListIterator;
import com.hypixel.hytale.server.core.plugin.PluginBase;
import com.hypixel.hytale.common.plugin.PluginManifest;
import com.hypixel.hytale.common.plugin.PluginIdentifier;
import java.util.Map;
import com.hypixel.hytale.server.core.plugin.PluginManager;
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 it.unimi.dsi.fastutil.objects.ObjectArrayList;
import com.hypixel.hytale.protocol.packets.interface_.CustomPageLifetime;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import com.hypixel.hytale.server.core.plugin.PluginListPageManager;
import javax.annotation.Nonnull;
import it.unimi.dsi.fastutil.objects.ObjectList;
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 PluginListPage extends InteractiveCustomUIPage<PluginListPageEventData>
{
    private static final Value<String> BUTTON_LABEL_STYLE;
    private static final Value<String> BUTTON_LABEL_STYLE_SELECTED;
    @Nullable
    private PluginDetails selectedPlugin;
    @Nonnull
    private final ObjectList<PluginDetails> availablePlugins;
    @Nonnull
    private final ObjectList<PluginDetails> visiblePlugins;
    @Nullable
    private PluginListPageManager.SessionSettings playerSessionSettings;
    
    public PluginListPage(@Nonnull final PlayerRef playerRef) {
        super(playerRef, CustomPageLifetime.CanDismiss, PluginListPageEventData.CODEC);
        this.availablePlugins = new ObjectArrayList<PluginDetails>();
        this.visiblePlugins = new ObjectArrayList<PluginDetails>();
    }
    
    @Override
    public void build(@Nonnull final Ref<EntityStore> ref, @Nonnull final UICommandBuilder commandBuilder, @Nonnull final UIEventBuilder eventBuilder, @Nonnull final Store<EntityStore> store) {
        final PluginListPageManager pageManager = PluginListPageManager.get();
        pageManager.registerPluginListPage(this);
        this.playerSessionSettings = store.ensureAndGetComponent(ref, PluginListPageManager.SessionSettings.getComponentType());
        commandBuilder.append("Pages/PluginListPage.ui");
        this.buildPluginList(commandBuilder, eventBuilder);
        eventBuilder.addEventBinding(CustomUIEventBindingType.ValueChanged, "#DescriptiveOnlyOption #CheckBox", new EventData().append("Option", "DescriptiveOnly"));
        if (!this.visiblePlugins.isEmpty()) {
            this.selectPlugin(this.visiblePlugins.getFirst().identifier.toString(), commandBuilder);
        }
        commandBuilder.set("#DescriptiveOnlyOption #CheckBox.Value", this.playerSessionSettings.descriptiveOnly);
    }
    
    @Override
    public void handleDataEvent(@Nonnull final Ref<EntityStore> ref, @Nonnull final Store<EntityStore> store, @Nonnull final PluginListPageEventData data) {
        assert this.playerSessionSettings != null;
        final UICommandBuilder commandBuilder = new UICommandBuilder();
        final UIEventBuilder eventBuilder = new UIEventBuilder();
        if (data.plugin != null) {
            final String type = data.type;
            switch (type) {
                case "Select": {
                    this.selectPlugin(data.plugin, commandBuilder);
                    break;
                }
                case "Toggle": {
                    this.checkBoxChanged(data.plugin, commandBuilder);
                    break;
                }
            }
            this.sendUpdate(commandBuilder, null, false);
        }
        else if (data.option != null) {
            final String option = data.option;
            switch (option) {
                case "DescriptiveOnly": {
                    this.playerSessionSettings.descriptiveOnly = !this.playerSessionSettings.descriptiveOnly;
                    this.buildPluginList(commandBuilder, eventBuilder);
                    if (!this.visiblePlugins.isEmpty()) {
                        this.selectPlugin(this.visiblePlugins.getFirst().identifier.toString(), commandBuilder);
                        break;
                    }
                    break;
                }
            }
            this.sendUpdate(commandBuilder, eventBuilder, false);
        }
    }
    
    @Override
    public void onDismiss(@Nonnull final Ref<EntityStore> ref, @Nonnull final Store<EntityStore> store) {
        PluginListPageManager.get().deregisterPluginListPage(this);
    }
    
    private void buildPluginList(@Nonnull final UICommandBuilder commandBuilder, @Nonnull final UIEventBuilder eventBuilder) {
        assert this.playerSessionSettings != null;
        commandBuilder.clear("#PluginList");
        this.visiblePlugins.clear();
        this.availablePlugins.clear();
        final PluginManager module = PluginManager.get();
        final Map<PluginIdentifier, PluginManifest> loadedPlugins = module.getAvailablePlugins();
        PluginIdentifier identifier = null;
        loadedPlugins.forEach((identifier, manifest) -> this.availablePlugins.add(new PluginDetails(manifest, identifier)));
        for (int i = 0, bound = this.availablePlugins.size(); i < bound; ++i) {
            final PluginDetails plugin = this.availablePlugins.get(i);
            final String desc = plugin.manifest.getDescription();
            if (this.playerSessionSettings.descriptiveOnly) {
                if (desc == null) {
                    continue;
                }
                if (desc.isEmpty()) {
                    continue;
                }
            }
            this.visiblePlugins.add(plugin);
        }
        for (int i = 0, bound = this.visiblePlugins.size(); i < bound; ++i) {
            identifier = this.visiblePlugins.get(i).identifier;
            final String id = identifier.toString();
            boolean enabled = false;
            final PluginBase loadedPlugin = module.getPlugin(identifier);
            if (loadedPlugin != null) {
                enabled = loadedPlugin.isEnabled();
            }
            final String selector = "#PluginList[" + i;
            commandBuilder.append("#PluginList", "Pages/PluginListButton.ui");
            commandBuilder.set(selector + " #Button.Text", id);
            commandBuilder.set(selector + " #CheckBox.Value", enabled);
            eventBuilder.addEventBinding(CustomUIEventBindingType.Activating, selector + " #Button", new EventData().append("Plugin", id).append("Type", "Select"), false);
            eventBuilder.addEventBinding(CustomUIEventBindingType.ValueChanged, selector + " #CheckBox", new EventData().append("Plugin", id).append("Type", "Toggle"), false);
        }
    }
    
    private void selectPlugin(@Nonnull final String playerSelectedPlugin, @Nonnull final UICommandBuilder commandBuilder) {
        PluginDetails nextSelectedPlugin = null;
        for (final PluginDetails plugin : this.visiblePlugins) {
            if (playerSelectedPlugin.equals(plugin.identifier.toString())) {
                nextSelectedPlugin = plugin;
                break;
            }
        }
        if (nextSelectedPlugin == null) {
            return;
        }
        if (this.selectedPlugin != null && this.visiblePlugins.contains(this.selectedPlugin)) {
            commandBuilder.set("#PluginList[" + this.visiblePlugins.indexOf(this.selectedPlugin) + "] #Button.Style", PluginListPage.BUTTON_LABEL_STYLE);
        }
        commandBuilder.set("#PluginList[" + this.visiblePlugins.indexOf(nextSelectedPlugin) + "] #Button.Style", PluginListPage.BUTTON_LABEL_STYLE_SELECTED);
        commandBuilder.set("#PluginName.Text", nextSelectedPlugin.manifest.getName());
        commandBuilder.set("#PluginIdentifier.Text", nextSelectedPlugin.identifier.toString());
        if (nextSelectedPlugin.manifest.getVersion() != null) {
            commandBuilder.set("#PluginVersion.Text", nextSelectedPlugin.manifest.getVersion().toString());
        }
        else {
            commandBuilder.set("#PluginVersion.Text", "");
        }
        if (nextSelectedPlugin.manifest.getDescription() != null) {
            commandBuilder.set("#PluginDescription.Text", nextSelectedPlugin.manifest.getDescription());
        }
        else {
            commandBuilder.set("#PluginDescription.Text", "");
        }
        this.selectedPlugin = nextSelectedPlugin;
    }
    
    private void checkBoxChanged(@Nonnull final String pluginName, @Nonnull final UICommandBuilder commandBuilder) {
        PluginDetails changedPlugin = null;
        for (final PluginDetails plugin : this.visiblePlugins) {
            if (!pluginName.equals(plugin.identifier.toString())) {
                continue;
            }
            changedPlugin = plugin;
            break;
        }
        if (changedPlugin == null) {
            return;
        }
        final PluginManager module = PluginManager.get();
        final PluginBase activePlugin = module.getPlugin(changedPlugin.identifier);
        final CommandManager commandManager = CommandManager.get();
        if (activePlugin != null && activePlugin.isEnabled()) {
            commandManager.handleCommand(this.playerRef, "plugin unload " + String.valueOf(changedPlugin.identifier));
        }
        else {
            commandManager.handleCommand(this.playerRef, "plugin load " + String.valueOf(changedPlugin.identifier));
        }
    }
    
    public void handlePluginChangeEvent(@Nonnull final PluginIdentifier plugin, final boolean activeState) {
        final UICommandBuilder commandBuilder = new UICommandBuilder();
        final UIEventBuilder eventBuilder = new UIEventBuilder();
        PluginDetails key = null;
        for (int i = 0, bound = this.visiblePlugins.size(); i < bound; ++i) {
            final PluginDetails details = this.visiblePlugins.get(i);
            if (details.identifier.equals(plugin)) {
                key = details;
                break;
            }
        }
        if (key == null) {
            return;
        }
        final String selector = "#PluginList[" + this.visiblePlugins.indexOf(key);
        commandBuilder.set(selector + " #CheckBox.Value", activeState);
        this.sendUpdate(commandBuilder, eventBuilder, false);
    }
    
    static {
        BUTTON_LABEL_STYLE = Value.ref("Pages/PluginListButton.ui", "LabelStyle");
        BUTTON_LABEL_STYLE_SELECTED = Value.ref("Pages/PluginListButton.ui", "SelectedLabelStyle");
    }
    
    public static class PluginListPageEventData
    {
        static final String KEY_PLUGIN = "Plugin";
        static final String TYPE_KEY = "Type";
        static final String KEY_OPTION = "Option";
        public static final BuilderCodec<PluginListPageEventData> CODEC;
        private String plugin;
        private String option;
        private String type;
        
        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             "Plugin"
            //    16: getstatic       com/hypixel/hytale/codec/Codec.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.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
            //    35: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
            //    38: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //    41: new             Lcom/hypixel/hytale/codec/KeyedCodec;
            //    44: dup            
            //    45: ldc             "Option"
            //    47: getstatic       com/hypixel/hytale/codec/Codec.STRING:Lcom/hypixel/hytale/codec/codecs/simple/StringCodec;
            //    50: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
            //    53: invokedynamic   BootstrapMethod #3, accept:()Ljava/util/function/BiConsumer;
            //    58: invokedynamic   BootstrapMethod #4, apply:()Ljava/util/function/Function;
            //    63: 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;
            //    66: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()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             "Type"
            //    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.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
            //    97: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
            //   100: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //   103: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.build:()Lcom/hypixel/hytale/codec/builder/BuilderCodec;
            //   106: putstatic       com/hypixel/hytale/server/core/plugin/pages/PluginListPage$PluginListPageEventData.CODEC:Lcom/hypixel/hytale/codec/builder/BuilderCodec;
            //   109: 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.visitParameterizedType(TypeSubstitutionVisitor.java:211)
            //     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: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.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.");
        }
    }
    
    private static class PluginDetails
    {
        @Nonnull
        private final PluginManifest manifest;
        @Nonnull
        private final PluginIdentifier identifier;
        
        public PluginDetails(@Nonnull final PluginManifest manifest, @Nonnull final PluginIdentifier identifier) {
            this.identifier = identifier;
            this.manifest = manifest;
        }
    }
}
