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

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

import com.hypixel.hytale.codec.builder.BuilderCodec;
import com.hypixel.hytale.protocol.packets.interface_.Page;
import com.hypixel.hytale.server.core.universe.world.chunk.BlockComponentChunk;
import com.hypixel.hytale.server.core.modules.block.BlockModule;
import com.hypixel.hytale.server.core.entity.entities.Player;
import java.util.Iterator;
import com.hypixel.hytale.server.core.ui.builder.EventData;
import com.hypixel.hytale.protocol.packets.interface_.CustomUIEventBindingType;
import java.util.List;
import com.hypixel.hytale.builtin.instances.InstancesPlugin;
import com.hypixel.hytale.server.core.ui.LocalizableString;
import com.hypixel.hytale.server.core.ui.DropdownEntryInfo;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
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.protocol.packets.interface_.CustomPageLifetime;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import com.hypixel.hytale.math.vector.Vector3f;
import javax.annotation.Nullable;
import com.hypixel.hytale.math.vector.Vector3d;
import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore;
import com.hypixel.hytale.component.Ref;
import javax.annotation.Nonnull;
import com.hypixel.hytale.builtin.instances.blocks.ConfigurableInstanceBlock;
import com.hypixel.hytale.server.core.entity.entities.player.pages.InteractiveCustomUIPage;

public class ConfigureInstanceBlockPage extends InteractiveCustomUIPage<PageData>
{
    @Nonnull
    private final ConfigurableInstanceBlock instanceBlock;
    @Nonnull
    private final Ref<ChunkStore> ref;
    @Nullable
    private Vector3d positionOffset;
    @Nullable
    private Vector3f rotation;
    
    public ConfigureInstanceBlockPage(@Nonnull final PlayerRef playerRef, @Nonnull final Ref<ChunkStore> ref) {
        super(playerRef, CustomPageLifetime.CanDismissOrCloseThroughInteraction, PageData.CODEC);
        this.instanceBlock = ref.getStore().getComponent(ref, ConfigurableInstanceBlock.getComponentType());
        this.ref = ref;
        this.positionOffset = ((this.instanceBlock.getPositionOffset() != null) ? this.instanceBlock.getPositionOffset().clone() : null);
        this.rotation = ((this.instanceBlock.getRotation() != null) ? this.instanceBlock.getRotation().clone() : null);
    }
    
    @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/ConfigureInstanceBlockPage.ui");
        final ObjectArrayList<DropdownEntryInfo> worlds = new ObjectArrayList<DropdownEntryInfo>();
        worlds.add(new DropdownEntryInfo(LocalizableString.fromMessageId("server.customUI.configureInstanceBlockPage.noInstances"), ""));
        final List<String> instances = InstancesPlugin.get().getInstanceAssets();
        instances.sort(String::compareToIgnoreCase);
        for (final String instance : instances) {
            worlds.add(new DropdownEntryInfo(LocalizableString.fromString(instance), instance));
        }
        commandBuilder.set("#Instance #Input.Entries", worlds);
        commandBuilder.set("#Instance #Input.Value", (this.instanceBlock.getInstanceName() == null) ? "" : this.instanceBlock.getInstanceName());
        this.buildPositionOffset(commandBuilder);
        eventBuilder.addEventBinding(CustomUIEventBindingType.ValueChanged, "#PositionOffset #Use #CheckBox", new EventData().append("Action", Action.PositionOffset.name()).append("@PositionOffset", "#PositionOffset #Use #CheckBox.Value"), false);
        this.buildRotation(commandBuilder);
        eventBuilder.addEventBinding(CustomUIEventBindingType.ValueChanged, "#Rotation #Use #CheckBox", new EventData().append("Action", Action.Rotation.name()).append("@Rotation", "#Rotation #Use #CheckBox.Value"), false);
        commandBuilder.set("#InstanceKey #Input.Value", (this.instanceBlock.getInstanceKey() == null) ? "" : this.instanceBlock.getInstanceKey());
        commandBuilder.set("#PersonalReturnPoint #CheckBox.Value", this.instanceBlock.isPersonalReturnPoint());
        commandBuilder.set("#CloseOnBlockRemove #CheckBox.Value", this.instanceBlock.isCloseOnRemove());
        commandBuilder.set("#RemoveBlockAfter #Input.Value", this.instanceBlock.getRemoveBlockAfter());
        eventBuilder.addEventBinding(CustomUIEventBindingType.Activating, "#SaveButton", new EventData().append("Action", Action.Save.name()).append("@Instance", "#Instance #Input.Value").append("@InstanceKey", "#InstanceKey #Input.Value").append("@PositionOffset", "#PositionOffset #Use #CheckBox.Value").append("@PositionOffsetX", "#PositionOffset #X #Input.Value").append("@PositionOffsetY", "#PositionOffset #Y #Input.Value").append("@PositionOffsetZ", "#PositionOffset #Z #Input.Value").append("@Rotation", "#Rotation #Use #CheckBox.Value").append("@RotationPitch", "#Rotation #Pitch #Input.Value").append("@RotationYaw", "#Rotation #Yaw #Input.Value").append("@RotationRoll", "#Rotation #Roll #Input.Value").append("@PersonalReturnPoint", "#PersonalReturnPoint #CheckBox.Value").append("@CloseOnBlockRemove", "#CloseOnBlockRemove #CheckBox.Value").append("@RemoveBlockAfter", "#RemoveBlockAfter #Input.Value"));
    }
    
    @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());
        final BlockModule.BlockStateInfo info = this.ref.getStore().getComponent(this.ref, BlockModule.BlockStateInfo.getComponentType());
        final BlockComponentChunk blockComponentChunk = this.ref.getStore().getComponent(info.getChunkRef(), BlockComponentChunk.getComponentType());
        assert blockComponentChunk != null;
        switch (data.action.ordinal()) {
            case 0: {
                this.instanceBlock.setInstanceName(this.emptyToNull(data.instance));
                this.instanceBlock.setInstanceKey(this.emptyToNull(data.instanceKey));
                this.instanceBlock.setPersonalReturnPoint(data.personalReturnPoint);
                this.instanceBlock.setCloseOnRemove(data.closeOnBlockRemove);
                this.instanceBlock.setRemoveBlockAfter(data.removeBlockAfter);
                if (data.positionOffset) {
                    this.instanceBlock.setPositionOffset(new Vector3d(data.positionX, data.positionY, data.positionZ));
                }
                else {
                    this.instanceBlock.setPositionOffset(null);
                }
                if (data.rotation) {
                    this.instanceBlock.setRotation(new Vector3f(data.rotationPitch * 0.017453292f, data.rotationYaw * 0.017453292f, data.rotationRoll * 0.017453292f));
                }
                else {
                    this.instanceBlock.setRotation(null);
                }
                blockComponentChunk.markNeedsSaving();
                playerComponent.getPageManager().setPage(ref, store, Page.None);
                break;
            }
            case 1: {
                if (data.positionOffset) {
                    this.positionOffset = new Vector3d();
                }
                else {
                    this.positionOffset = null;
                }
                blockComponentChunk.markNeedsSaving();
                final UICommandBuilder commandBuilder = new UICommandBuilder();
                this.buildPositionOffset(commandBuilder);
                this.sendUpdate(commandBuilder);
                break;
            }
            case 2: {
                if (data.rotation) {
                    this.rotation = new Vector3f();
                }
                else {
                    this.rotation = null;
                }
                blockComponentChunk.markNeedsSaving();
                final UICommandBuilder commandBuilder = new UICommandBuilder();
                this.buildRotation(commandBuilder);
                this.sendUpdate(commandBuilder);
                break;
            }
        }
    }
    
    private String emptyToNull(@Nullable final String s) {
        return (s == null || s.isEmpty()) ? null : s;
    }
    
    private void buildPositionOffset(@Nonnull final UICommandBuilder commandBuilder) {
        final boolean hasPosition = this.positionOffset != null;
        commandBuilder.set("#PositionOffset #Use #CheckBox.Value", hasPosition);
        commandBuilder.set("#PositionOffset #X.Visible", hasPosition);
        commandBuilder.set("#PositionOffset #Y.Visible", hasPosition);
        commandBuilder.set("#PositionOffset #Z.Visible", hasPosition);
        if (hasPosition) {
            commandBuilder.set("#PositionOffset #X #Input.Value", this.positionOffset.x);
            commandBuilder.set("#PositionOffset #Y #Input.Value", this.positionOffset.y);
            commandBuilder.set("#PositionOffset #Z #Input.Value", this.positionOffset.z);
        }
    }
    
    private void buildRotation(@Nonnull final UICommandBuilder commandBuilder) {
        final boolean hasRotation = this.rotation != null;
        commandBuilder.set("#Rotation #Use #CheckBox.Value", hasRotation);
        commandBuilder.set("#Rotation #Pitch.Visible", hasRotation);
        commandBuilder.set("#Rotation #Yaw.Visible", hasRotation);
        commandBuilder.set("#Rotation #Roll.Visible", hasRotation);
        if (hasRotation) {
            commandBuilder.set("#Rotation #Pitch #Input.Value", this.rotation.x * 57.295776f);
            commandBuilder.set("#Rotation #Yaw #Input.Value", this.rotation.y * 57.295776f);
            commandBuilder.set("#Rotation #Roll #Input.Value", this.rotation.z * 57.295776f);
        }
    }
    
    public static class PageData
    {
        public static final String INSTANCE = "@Instance";
        public static final String INSTANCE_KEY = "@InstanceKey";
        public static final String POSITION_OFFSET = "@PositionOffset";
        public static final String POSITION_OFFSET_X = "@PositionOffsetX";
        public static final String POSITION_OFFSET_Y = "@PositionOffsetY";
        public static final String POSITION_OFFSET_Z = "@PositionOffsetZ";
        public static final String ROTATION = "@Rotation";
        public static final String ROTATION_PITCH = "@RotationPitch";
        public static final String ROTATION_YAW = "@RotationYaw";
        public static final String ROTATION_ROLL = "@RotationRoll";
        public static final String PERSONAL_RETURN_POINT = "@PersonalReturnPoint";
        public static final String CLOSE_ON_BLOCK_REMOVE = "@CloseOnBlockRemove";
        public static final String REMOVE_BLOCK_AFTER = "@RemoveBlockAfter";
        public static final BuilderCodec<PageData> CODEC;
        public Action action;
        public String instance;
        public String instanceKey;
        public boolean positionOffset;
        public double positionX;
        public double positionY;
        public double positionZ;
        public boolean rotation;
        public float rotationPitch;
        public float rotationYaw;
        public float rotationRoll;
        public boolean personalReturnPoint;
        public boolean closeOnBlockRemove;
        public double removeBlockAfter;
        
        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/instances/page/ConfigureInstanceBlockPage$Action;.class
            //    22: invokespecial   com/hypixel/hytale/codec/codecs/EnumCodec.<init>:(Ljava/lang/Class;)V
            //    25: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
            //    28: invokedynamic   BootstrapMethod #1, accept:()Ljava/util/function/BiConsumer;
            //    33: invokedynamic   BootstrapMethod #2, apply:()Ljava/util/function/Function;
            //    38: 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;
            //    41: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //    44: new             Lcom/hypixel/hytale/codec/KeyedCodec;
            //    47: dup            
            //    48: ldc             "@Instance"
            //    50: getstatic       com/hypixel/hytale/codec/Codec.STRING:Lcom/hypixel/hytale/codec/codecs/simple/StringCodec;
            //    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             "@InstanceKey"
            //    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             "@PositionOffset"
            //   106: getstatic       com/hypixel/hytale/codec/Codec.BOOLEAN:Lcom/hypixel/hytale/codec/codecs/simple/BooleanCodec;
            //   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             "@PositionOffsetX"
            //   134: getstatic       com/hypixel/hytale/codec/Codec.DOUBLE:Lcom/hypixel/hytale/codec/codecs/simple/DoubleCodec;
            //   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: new             Lcom/hypixel/hytale/codec/KeyedCodec;
            //   159: dup            
            //   160: ldc             "@PositionOffsetY"
            //   162: getstatic       com/hypixel/hytale/codec/Codec.DOUBLE:Lcom/hypixel/hytale/codec/codecs/simple/DoubleCodec;
            //   165: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
            //   168: invokedynamic   BootstrapMethod #11, accept:()Ljava/util/function/BiConsumer;
            //   173: invokedynamic   BootstrapMethod #12, apply:()Ljava/util/function/Function;
            //   178: 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;
            //   181: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //   184: new             Lcom/hypixel/hytale/codec/KeyedCodec;
            //   187: dup            
            //   188: ldc             "@PositionOffsetZ"
            //   190: getstatic       com/hypixel/hytale/codec/Codec.DOUBLE:Lcom/hypixel/hytale/codec/codecs/simple/DoubleCodec;
            //   193: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
            //   196: invokedynamic   BootstrapMethod #13, accept:()Ljava/util/function/BiConsumer;
            //   201: invokedynamic   BootstrapMethod #14, apply:()Ljava/util/function/Function;
            //   206: 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;
            //   209: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //   212: new             Lcom/hypixel/hytale/codec/KeyedCodec;
            //   215: dup            
            //   216: ldc             "@Rotation"
            //   218: getstatic       com/hypixel/hytale/codec/Codec.BOOLEAN:Lcom/hypixel/hytale/codec/codecs/simple/BooleanCodec;
            //   221: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
            //   224: invokedynamic   BootstrapMethod #15, accept:()Ljava/util/function/BiConsumer;
            //   229: invokedynamic   BootstrapMethod #16, apply:()Ljava/util/function/Function;
            //   234: 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;
            //   237: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //   240: new             Lcom/hypixel/hytale/codec/KeyedCodec;
            //   243: dup            
            //   244: ldc             "@RotationPitch"
            //   246: getstatic       com/hypixel/hytale/codec/Codec.FLOAT:Lcom/hypixel/hytale/codec/codecs/simple/FloatCodec;
            //   249: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
            //   252: invokedynamic   BootstrapMethod #17, accept:()Ljava/util/function/BiConsumer;
            //   257: invokedynamic   BootstrapMethod #18, apply:()Ljava/util/function/Function;
            //   262: 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;
            //   265: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //   268: new             Lcom/hypixel/hytale/codec/KeyedCodec;
            //   271: dup            
            //   272: ldc             "@RotationYaw"
            //   274: getstatic       com/hypixel/hytale/codec/Codec.FLOAT:Lcom/hypixel/hytale/codec/codecs/simple/FloatCodec;
            //   277: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
            //   280: invokedynamic   BootstrapMethod #19, accept:()Ljava/util/function/BiConsumer;
            //   285: invokedynamic   BootstrapMethod #20, apply:()Ljava/util/function/Function;
            //   290: 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;
            //   293: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //   296: new             Lcom/hypixel/hytale/codec/KeyedCodec;
            //   299: dup            
            //   300: ldc             "@RotationRoll"
            //   302: getstatic       com/hypixel/hytale/codec/Codec.FLOAT:Lcom/hypixel/hytale/codec/codecs/simple/FloatCodec;
            //   305: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
            //   308: invokedynamic   BootstrapMethod #21, accept:()Ljava/util/function/BiConsumer;
            //   313: invokedynamic   BootstrapMethod #22, apply:()Ljava/util/function/Function;
            //   318: 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;
            //   321: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //   324: new             Lcom/hypixel/hytale/codec/KeyedCodec;
            //   327: dup            
            //   328: ldc             "@PersonalReturnPoint"
            //   330: getstatic       com/hypixel/hytale/codec/Codec.BOOLEAN:Lcom/hypixel/hytale/codec/codecs/simple/BooleanCodec;
            //   333: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
            //   336: invokedynamic   BootstrapMethod #23, accept:()Ljava/util/function/BiConsumer;
            //   341: invokedynamic   BootstrapMethod #24, apply:()Ljava/util/function/Function;
            //   346: 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;
            //   349: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //   352: new             Lcom/hypixel/hytale/codec/KeyedCodec;
            //   355: dup            
            //   356: ldc             "@CloseOnBlockRemove"
            //   358: getstatic       com/hypixel/hytale/codec/Codec.BOOLEAN:Lcom/hypixel/hytale/codec/codecs/simple/BooleanCodec;
            //   361: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
            //   364: invokedynamic   BootstrapMethod #25, accept:()Ljava/util/function/BiConsumer;
            //   369: invokedynamic   BootstrapMethod #26, apply:()Ljava/util/function/Function;
            //   374: 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;
            //   377: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //   380: new             Lcom/hypixel/hytale/codec/KeyedCodec;
            //   383: dup            
            //   384: ldc             "@RemoveBlockAfter"
            //   386: getstatic       com/hypixel/hytale/codec/Codec.DOUBLE:Lcom/hypixel/hytale/codec/codecs/simple/DoubleCodec;
            //   389: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
            //   392: invokedynamic   BootstrapMethod #27, accept:()Ljava/util/function/BiConsumer;
            //   397: invokedynamic   BootstrapMethod #28, apply:()Ljava/util/function/Function;
            //   402: 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;
            //   405: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //   408: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.build:()Lcom/hypixel/hytale/codec/builder/BuilderCodec;
            //   411: putstatic       com/hypixel/hytale/builtin/instances/page/ConfigureInstanceBlockPage$PageData.CODEC:Lcom/hypixel/hytale/codec/builder/BuilderCodec;
            //   414: 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: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: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: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: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: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: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: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: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: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: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, 
        PositionOffset, 
        Rotation;
    }
}
