package wtf.opal.client.feature.module.impl.crucifix;

import dev.crucifixbeta.CrucifixBeta;
import dev.crucifixbeta.api.utils.i18n.LangUtil;
import dev.crucifixbeta.mod.modules.impl.client.ClientSetting;
import dev.crucifixbeta.mod.modules.impl.misc.AddFriend;
import dev.crucifixbeta.mod.modules.settings.Setting;
import dev.crucifixbeta.mod.modules.settings.impl.BindSetting;
import dev.crucifixbeta.mod.modules.settings.impl.BooleanSetting;
import dev.crucifixbeta.mod.modules.settings.impl.ColorSetting;
import dev.crucifixbeta.mod.modules.settings.impl.EnumSetting;
import dev.crucifixbeta.mod.modules.settings.impl.SliderSetting;
import dev.crucifixbeta.mod.modules.settings.impl.StringSetting;
import java.awt.Color;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.input.KeyInput;
import net.minecraft.client.util.InputUtil;
import wtf.opal.client.feature.module.Module;
import wtf.opal.client.feature.module.ModuleCategory;
import wtf.opal.client.feature.module.property.Property;
import wtf.opal.client.renderer.NVGRenderer;
import wtf.opal.client.renderer.component.ToggleSwitchComponent;
import wtf.opal.client.renderer.repository.FontRepository;
import wtf.opal.client.screen.click.dropdown.ClickGuiAnimationConfig;
import wtf.opal.client.screen.click.dropdown.DropdownClickGUI;
import wtf.opal.client.screen.click.dropdown.panel.property.PropertyPanel;
import wtf.opal.utility.misc.HoverUtility;
import wtf.opal.utility.misc.math.MathUtility;
import wtf.opal.utility.render.ColorUtility;
import wtf.opal.utility.render.animation.Animation;
import wtf.opal.utility.render.animation.Easing;

@Environment(EnvType.CLIENT)
public final class CrucifixModuleAdapter extends Module {
   private final dev.crucifixbeta.mod.modules.Module delegate;

   public CrucifixModuleAdapter(dev.crucifixbeta.mod.modules.Module delegate) {
      super(
         delegate.getName(), delegate.getDescription() == null ? "" : delegate.getDescription(), mapCategory(delegate.getCategory())
      );
      this.delegate = delegate;

      for (Setting var3 : delegate.getSettings()) {
         Property var4 = this.createProperty(var3);
         if (var4 != null) {
            this.addProperties(new Property[]{var4});
         }
      }

      if (delegate instanceof AddFriend) {
         this.addProperties(new Property[]{new CrucifixModuleAdapter.CrucifixFriendListProperty()});
      }

      if (delegate.isOn()) {
         this.setEnabled(true);
      }
   }

   public void syncEnabledFromDelegate() {
      boolean var1 = this.delegate.isOn();
      if (this.isEnabled() != var1) {
         this.setEnabled(var1);
      }
   }

   @Override
   protected void onEnable() {
      if (!this.delegate.isOn()) {
         this.delegate.enable();
      }
   }

   @Override
   protected void onDisable() {
      if (this.delegate.isOn()) {
         this.delegate.disable();
      }
   }

   @Override
   public String getDisplayName() {
      return this.delegate.getDisplayName();
   }

   private static String displayName(Property<?> property) {
      if (property instanceof CrucifixModuleAdapter.CrucifixBooleanProperty var6) {
         return var6.setting.getDisplayName();
      } else if (property instanceof CrucifixModuleAdapter.CrucifixNumberProperty var5) {
         return var5.setting.getDisplayName();
      } else if (property instanceof CrucifixModuleAdapter.CrucifixStringProperty var4) {
         return var4.setting.getDisplayName();
      } else if (property instanceof CrucifixModuleAdapter.CrucifixEnumProperty var3) {
         return var3.setting.getDisplayName();
      } else if (property instanceof CrucifixModuleAdapter.CrucifixColorProperty var2) {
         return var2.setting.getDisplayName();
      } else if (property instanceof CrucifixModuleAdapter.CrucifixBindProperty var1) {
         return var1.setting.getDisplayName();
      } else {
         return property instanceof CrucifixModuleAdapter.CrucifixFriendListProperty
            ? LangUtil.ui("Friends", "\u597d\u53cb")
            : property.getName();
      }
   }

   private Property<?> createProperty(Setting setting) {
      if (setting instanceof BooleanSetting var7) {
         return new CrucifixModuleAdapter.CrucifixBooleanProperty(var7);
      } else if (setting instanceof SliderSetting var6) {
         return new CrucifixModuleAdapter.CrucifixNumberProperty(var6);
      } else if (setting instanceof StringSetting var5) {
         return new CrucifixModuleAdapter.CrucifixStringProperty(var5);
      } else if (setting instanceof EnumSetting var4) {
         return new CrucifixModuleAdapter.CrucifixEnumProperty(var4);
      } else if (setting instanceof ColorSetting var3) {
         return new CrucifixModuleAdapter.CrucifixColorProperty(var3);
      } else {
         return setting instanceof BindSetting var2 ? new CrucifixModuleAdapter.CrucifixBindProperty(var2) : null;
      }
   }

   private static ModuleCategory mapCategory(dev.crucifixbeta.mod.modules.Module.Category category) {
      return switch (category) {
         case Combat -> ModuleCategory.COMBAT;
         case Misc -> ModuleCategory.MISC;
         case Render -> ModuleCategory.RENDER;
         case Movement -> ModuleCategory.MOVEMENT;
         case Player -> ModuleCategory.PLAYER;
         case Exploit -> ModuleCategory.EXPLOIT;
         case Client -> ModuleCategory.CLIENT;
         case Debug -> ModuleCategory.DEBUG;
         case HUD -> ModuleCategory.HUD;
      };
   }
@Environment(EnvType.CLIENT)
   private static final class CrucifixBindProperty extends Property<String> {
      private final BindSetting setting;

      private CrucifixBindProperty(BindSetting setting) {
         super(setting.getDisplayName());
         this.setting = setting;
         this.hideIf(() -> !setting.isVisible());
      }

      public String getValue() {
         return this.setting.getKeyString();
      }

      public BindSetting getBindSetting() {
         return this.setting;
      }

      @Override
      public PropertyPanel<?> createClickGUIComponent() {
         return new CrucifixModuleAdapter.CrucifixLabelComponent(this);
      }
   }

   @Environment(EnvType.CLIENT)
   private static final class CrucifixBooleanComponent extends PropertyPanel<CrucifixModuleAdapter.CrucifixBooleanProperty> {
      private final ToggleSwitchComponent toggleSwitch;

      private CrucifixBooleanComponent(CrucifixModuleAdapter.CrucifixBooleanProperty property) {
         super(property);
         this.toggleSwitch = new ToggleSwitchComponent(property::toggle, property::getValue);
      }

      @Override
      public void render(DrawContext context, int mouseX, int mouseY, float delta) {
         super.render(context, mouseX, mouseY, delta);
         FontRepository.getFont("productsans-medium")
            .drawString(CrucifixModuleAdapter.displayName(this.getProperty()), this.x + 5.0F, this.y + 10.5F, 7.0F, ColorUtility.getEnabledTextColor());
         if (this.getProperty().hasParent()) {
            String var5 = this.getProperty().isOpen() ? "-" : "+";
            FontRepository.getFont("productsans-bold")
               .drawString(var5, this.x + this.width - 31.0F, this.y + 10.5F, 7.0F, ColorUtility.getDisabledTextColor());
         }

         this.toggleSwitch.render(this.x + 88.0F, this.y + 3.8F, 0.85F);
      }

      @Override
      public void mouseClicked(double mouseX, double mouseY, int button) {
         if (button == 0) {
            this.toggleSwitch.mouseClicked(this.x, this.y, this.width, this.height, mouseX, mouseY);
         } else if (button == 1 && this.getProperty().hasParent() && HoverUtility.isHovering(this.x, this.y, this.width, this.height, mouseX, mouseY)) {
            this.getProperty().toggleOpen();
         }
      }
}

   @Environment(EnvType.CLIENT)
   private static final class CrucifixBooleanProperty extends Property<Boolean> {
      private final BooleanSetting setting;

      private CrucifixBooleanProperty(BooleanSetting setting) {
         super(setting.getDisplayName());
         this.setting = setting;
         this.hideIf(() -> !setting.isVisible());
      }

      public Boolean getValue() {
         return this.setting.getValue();
      }

      public void setValue(Boolean value) {
         this.setting.setValue(Boolean.TRUE.equals(value));
         super.setValue(Boolean.TRUE.equals(value));
      }

      public void toggle() {
         this.setValue(!this.getValue());
      }

      public boolean hasParent() {
         return this.setting.hasParent();
      }

      public boolean isOpen() {
         return this.setting.isOpen();
      }

      public void toggleOpen() {
         this.setting.setOpen(!this.setting.isOpen());
      }

      @Override
      public PropertyPanel<?> createClickGUIComponent() {
         return new CrucifixModuleAdapter.CrucifixBooleanComponent(this);
      }
   }

   @Environment(EnvType.CLIENT)
   private static final class CrucifixColorComponent extends PropertyPanel<CrucifixModuleAdapter.CrucifixColorProperty> {
      private boolean expanded;
      private CrucifixModuleAdapter.CrucifixColorComponent.ColorDragType colorDragType = CrucifixModuleAdapter.CrucifixColorComponent.ColorDragType.NONE;
      private final Animation expandAnimation = new Animation(Easing.DECELERATE, 125L);

      private CrucifixColorComponent(CrucifixModuleAdapter.CrucifixColorProperty property) {
         super(property);
      }

      @Override
      public void render(DrawContext context, int mouseX, int mouseY, float delta) {
         super.render(context, mouseX, mouseY, delta);
         ClickGuiAnimationConfig.applyParameterPanel(this.expandAnimation, 125L, Easing.DECELERATE);
         this.expandAnimation.run(this.expanded ? 1.0F : 0.0F);
         FontRepository.getFont("productsans-medium")
            .drawString(CrucifixModuleAdapter.displayName(this.getProperty()), this.x + 5.0F, this.y + 10.5F, 7.0F, ColorUtility.getEnabledTextColor());
         drawCheckerboard(this.x + this.width - 22.0F, this.y + 3.5F, 18.0F, 10.0F, 4);
         NVGRenderer.roundedRect(this.x + this.width - 22.0F, this.y + 3.5F, 18.0F, 10.0F, 3.0F, this.getProperty().getValue());
         float var5 = this.x + 5.0F;
         float var6 = this.y + 17.0F;
         float var7 = 65.0F;
         float var8 = 50.0F;
         float var9 = var5 + 65.0F + 5.0F;
         float var10 = 8.0F;
         float var11 = var6 + 50.0F + 5.0F;
         float var12 = 7.0F;
         float var13 = 67.0F;
         NVGRenderer.scissor(
            this.x,
            this.y,
            this.width,
            this.height,
            () -> {
               if (this.expandAnimation.getValue() > 0.0F) {
                  this.applyDrag(mouseX, mouseY, var5, var6, 65.0F, 50.0F, var9, var11);
                  float[] var7x = this.getProperty().getHSB();
                  int var8x = Color.getHSBColor(var7x[0], 1.0F, 1.0F).getRGB();
                  int var9x = Color.HSBtoRGB(var7x[0], var7x[1], var7x[2]);
                  NVGRenderer.rect(var5, var6, 65.0F, 50.0F, var8x);
                  NVGRenderer.rectGradient(
                     var5,
                     var6,
                     65.0F,
                     50.0F,
                     Color.getHSBColor(var7x[0], 0.0F, 1.0F).getRGB(),
                     ColorUtility.applyOpacity(Color.getHSBColor(var7x[0], 0.0F, 1.0F).getRGB(), 0),
                     0.0F
                  );
                  NVGRenderer.rectGradient(var5, var6, 65.0F, 50.0F, ColorUtility.applyOpacity(Color.BLACK.getRGB(), 0), Color.BLACK.getRGB(), 90.0F);
                  NVGRenderer.rainbowRect(var9, var6, 8.0F, 50.0F);
                  drawCheckerboard(var5, var11, 78.0F, 7.0F, 4);
                  NVGRenderer.rectGradient(var5, var11, 78.0F, 7.0F, ColorUtility.applyOpacity(var9x, 1.0F), ColorUtility.applyOpacity(var9x, 0), 0.0F);
                  float var10x = var5 + 65.0F * var7x[1];
                  float var11x = var6 + 50.0F * (1.0F - var7x[2]);
                  NVGRenderer.roundedRect(var10x - 2.0F, var11x - 2.0F, 4.0F, 4.0F, 2.0F, -1);
                  NVGRenderer.roundedRectOutline(var10x - 2.0F, var11x - 2.0F, 4.0F, 4.0F, 2.0F, 0.75F, -16777216);
                  float var12x = var6 + 50.0F * var7x[0];
                  NVGRenderer.rect(var9 - 1.0F, var12x - 1.0F, 10.0F, 2.0F, -1);
                  NVGRenderer.rectOutline(var9 - 1.0F, var12x - 1.0F, 10.0F, 2.0F, 0.75F, -16777216);
                  float var13x = var5 + 78.0F * (1.0F - this.getProperty().getAlpha());
                  NVGRenderer.rect(var13x - 1.0F, var11 - 1.0F, 2.0F, 9.0F, -1);
                  NVGRenderer.rectOutline(var13x - 1.0F, var11 - 1.0F, 2.0F, 9.0F, 0.75F, -16777216);
               }

               this.setHeight(17.0F + 67.0F * this.expandAnimation.getValue());
            }
         );
      }

      @Override
      public void mouseClicked(double mouseX, double mouseY, int button) {
         if (!HoverUtility.isHovering(this.x, this.y, this.width, 17.0F, mouseX, mouseY) || button != 1 && button != 0) {
            if (this.expanded && button == 0) {
               float var6 = this.x + 5.0F;
               float var7 = this.y + 17.0F;
               float var8 = 65.0F;
               float var9 = 50.0F;
               float var10 = var6 + 65.0F + 5.0F;
               float var11 = 8.0F;
               float var12 = var7 + 50.0F + 5.0F;
               float var13 = 7.0F;
               if (HoverUtility.isHovering(var6, var7, 65.0F, 50.0F, mouseX, mouseY)) {
                  this.colorDragType = CrucifixModuleAdapter.CrucifixColorComponent.ColorDragType.PICKER;
                  this.applyDrag((int)mouseX, (int)mouseY, var6, var7, 65.0F, 50.0F, var10, var12);
               } else if (HoverUtility.isHovering(var10, var7, 8.0F, 50.0F, mouseX, mouseY)) {
                  this.colorDragType = CrucifixModuleAdapter.CrucifixColorComponent.ColorDragType.HUE;
                  this.applyDrag((int)mouseX, (int)mouseY, var6, var7, 65.0F, 50.0F, var10, var12);
               } else if (HoverUtility.isHovering(var6, var12, 78.0F, 7.0F, mouseX, mouseY)) {
                  this.colorDragType = CrucifixModuleAdapter.CrucifixColorComponent.ColorDragType.OPACITY;
                  this.applyDrag((int)mouseX, (int)mouseY, var6, var7, 65.0F, 50.0F, var10, var12);
               }
            }
         } else {
            this.expanded = !this.expanded;
         }
      }

      @Override
      public void mouseReleased(double mouseX, double mouseY, int button) {
         if (button == 0) {
            this.colorDragType = CrucifixModuleAdapter.CrucifixColorComponent.ColorDragType.NONE;
         }
      }

      private void applyDrag(int mouseX, int mouseY, float pickerX, float pickerY, float pickerWidth, float pickerHeight, float hueX, float alphaY) {
         switch (this.colorDragType) {
            case PICKER:
               this.getProperty().setSaturation(clamp01(((float)mouseX - pickerX) / pickerWidth));
               this.getProperty().setBrightness(clamp01(1.0F - ((float)mouseY - pickerY) / pickerHeight));
               this.getProperty().updateValue();
               break;
            case HUE:
               this.getProperty().setHue(clamp01(((float)mouseY - pickerY) / pickerHeight));
               this.getProperty().updateValue();
               break;
            case OPACITY:
               this.getProperty().setAlpha(1.0F - clamp01(((float)mouseX - pickerX) / (pickerWidth + 13.0F)));
            case NONE:
         }
      }

      private static float clamp01(float value) {
         return Math.min(1.0F, Math.max(0.0F, value));
      }

      private static void drawCheckerboard(float x, float y, float width, float height, int squareSize) {
         boolean var5 = false;
         float var6 = y;

         while (var6 < y + height) {
            boolean var7 = var5;

            for (float var8 = x; var8 < x + width; var8 += (float)squareSize) {
               float var9 = Math.min((float)squareSize, x + width - var8);
               float var10 = Math.min((float)squareSize, y + height - var6);
               NVGRenderer.rect(var8, var6, var9, var10, var7 ? -855310 : -6316129);
               var7 = !var7;
            }

            var5 = !var5;
            var6 += (float)squareSize;
         }
      }
@Environment(EnvType.CLIENT)
      private static enum ColorDragType {
         PICKER,
         HUE,
         OPACITY,
         NONE;

}
   }

   @Environment(EnvType.CLIENT)
   private static final class CrucifixColorProperty extends Property<Integer> {
      private final ColorSetting setting;
      private final float[] hsb = new float[3];

      private CrucifixColorProperty(ColorSetting setting) {
         super(setting.getDisplayName());
         this.setting = setting;
         Color var2 = setting.getValue();
         float[] var3 = Color.RGBtoHSB(var2.getRed(), var2.getGreen(), var2.getBlue(), null);
         this.hsb[0] = var3[0];
         this.hsb[1] = var3[1];
         this.hsb[2] = var3[2];
         this.hideIf(() -> !setting.isVisible());
      }

      public Integer getValue() {
         return this.setting.getValue().getRGB();
      }

      public void setValue(Integer value) {
         if (value != null) {
            Color var2 = new Color(value, true);
            this.setting.setValue(var2);
            this.syncHSB(var2);
            super.setValue(var2.getRGB());
         }
      }

      public float[] getHSB() {
         return this.hsb;
      }

      public void setHue(float hue) {
         this.hsb[0] = hue;
      }

      public void setSaturation(float saturation) {
         this.hsb[1] = saturation;
      }

      public void setBrightness(float brightness) {
         this.hsb[2] = brightness;
      }

      public float getAlpha() {
         return (float)this.setting.getValue().getAlpha() / 255.0F;
      }

      public void setAlpha(float alpha) {
         Color var2 = this.setting.getValue();
         int var3 = Math.round(Math.min(1.0F, Math.max(0.0F, alpha)) * 255.0F);
         this.setting.setValue(new Color(var2.getRed(), var2.getGreen(), var2.getBlue(), var3));
         super.setValue(this.setting.getValue().getRGB());
      }

      public void updateValue() {
         Color var1 = new Color(Color.HSBtoRGB(this.hsb[0], this.hsb[1], this.hsb[2]));
         int var2 = this.setting.getValue().getAlpha();
         this.setting.setValue(new Color(var1.getRed(), var1.getGreen(), var1.getBlue(), var2));
         super.setValue(this.setting.getValue().getRGB());
      }

      private void syncHSB(Color color) {
         float[] var2 = Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), null);
         this.hsb[0] = var2[0];
         this.hsb[1] = var2[1];
         this.hsb[2] = var2[2];
      }

      @Override
      public PropertyPanel<?> createClickGUIComponent() {
         return new CrucifixModuleAdapter.CrucifixColorComponent(this);
      }
   }

   @Environment(EnvType.CLIENT)
   private static final class CrucifixEnumComponent extends PropertyPanel<CrucifixModuleAdapter.CrucifixEnumProperty> {
      private static final float OPTION_HEIGHT;
      private final Animation expandAnimation = new Animation(Easing.DECELERATE, 125L);
      private boolean expanded;

      private CrucifixEnumComponent(CrucifixModuleAdapter.CrucifixEnumProperty property) {
         super(property);
         this.setHeight(17.0F);
      }

      @Override
      public void render(DrawContext context, int mouseX, int mouseY, float delta) {
         super.render(context, mouseX, mouseY, delta);
         ClickGuiAnimationConfig.applyParameterPanel(this.expandAnimation, 125L, Easing.DECELERATE);
         this.expandAnimation.run(this.expanded ? 1.0F : 0.0F);
         FontRepository.getFont("productsans-medium")
            .drawString(CrucifixModuleAdapter.displayName(this.getProperty()), this.x + 5.0F, this.y + 10.5F, 7.0F, ColorUtility.getEnabledTextColor());
         String var5 = LangUtil.enumValue(this.getProperty().getValue());
         float var6 = FontRepository.getFont("productsans-medium").getStringWidth(var5, 7.0F);
         FontRepository.getFont("productsans-medium")
            .drawString(var5, this.x + this.width - var6 - 6.0F, this.y + 10.5F, 7.0F, ColorUtility.getDisabledTextColor());
         NVGRenderer.scissor(
            this.x,
            this.y,
            this.width,
            this.height,
            () -> {
               byte var3 = 0;
               if (this.expandAnimation.getValue() > 0.0F) {
                  for (Enum var7 : this.getProperty().getValues()) {
                     if (var7 != null && var7 != this.getProperty().getValue()) {
                        float var8 = this.y + 17.0F + (float)var3;
                        boolean var9 = HoverUtility.isHovering(this.x + 3.0F, var8, this.width - 6.0F, 13.0F, (double)mouseX, (double)mouseY);
                        if (var9) {
                           NVGRenderer.roundedRect(
                              this.x + 3.0F, var8 + 1.0F, this.width - 6.0F, 11.0F, 2.5F, ColorUtility.scaleOpacity(ColorUtility.getModuleHoverColor(), 0.32F)
                           );
                        }

                        FontRepository.getFont("productsans-medium")
                           .drawString(LangUtil.enumValue(var7), this.x + 8.0F, var8 + 9.5F, 7.0F, ColorUtility.getDisabledTextColor());
                        var3 += 13;
                     }
                  }
               }

               this.setHeight(17.0F + (float)var3 * this.expandAnimation.getValue());
            }
         );
      }

      @Override
      public void mouseClicked(double mouseX, double mouseY, int button) {
         Enum[] var6 = this.getProperty().getValues();
         if (this.expanded && button == 0) {
            byte var7 = 0;

            for (Enum var11 : var6) {
               if (var11 != null && var11 != this.getProperty().getValue()) {
                  if (HoverUtility.isHovering(this.x + 3.0F, this.y + 17.0F + (float)var7, this.width - 6.0F, 13.0F, mouseX, mouseY)) {
                     this.getProperty().setValue(var11);
                     this.expanded = false;
                     return;
                  }

                  var7 += 13;
               }
            }
         }

         if (HoverUtility.isHovering(this.x, this.y, this.width, 17.0F, mouseX, mouseY)) {
            if (button == 1) {
               this.expanded = !this.expanded;
            } else if (button == 0) {
               int var12 = this.getProperty().getValue().ordinal();
               int var13 = (var12 + 1) % var6.length;
               this.getProperty().setValue(var6[var13]);
            }
         }
      }

      static {

         OPTION_HEIGHT = 13.0F;
      }
}

   @Environment(EnvType.CLIENT)
   private static final class CrucifixEnumProperty extends Property<Enum<?>> {
      private final EnumSetting<?> setting;
      private final Enum<?>[] values;

      private CrucifixEnumProperty(EnumSetting<?> setting) {
         super(setting.getDisplayName());
         this.setting = setting;
         this.values = (Enum<?>[])setting.getValue().getDeclaringClass().getEnumConstants();
         this.hideIf(() -> !setting.isVisible());
         // $VF: Couldn't be decompiled
         // Please report this to the Vineflower issue tracker, at https://github.com/Vineflower/vineflower/issues with a copy of the class file (if you have the rights to distribute it!)
         // java.lang.NullPointerException: Cannot invoke "org.jetbrains.java.decompiler.struct.gen.VarType.isGeneric()" because "newRet" is null
         //   at org.jetbrains.java.decompiler.modules.decompiler.exps.InvocationExprent.getInferredExprType(InvocationExprent.java:634)
         //   at org.jetbrains.java.decompiler.modules.decompiler.exps.FunctionExprent.getInferredExprType(FunctionExprent.java:243)
         //   at org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor.getCastedExprent(ExprProcessor.java:966)
         //   at org.jetbrains.java.decompiler.modules.decompiler.exps.AssignmentExprent.toJava(AssignmentExprent.java:154)
         //   at org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor.listToJava(ExprProcessor.java:895)
         //   at org.jetbrains.java.decompiler.modules.decompiler.stats.BasicBlockStatement.toJava(BasicBlockStatement.java:90)
         //   at org.jetbrains.java.decompiler.modules.decompiler.stats.RootStatement.toJava(RootStatement.java:36)
         //   at org.jetbrains.java.decompiler.main.ClassWriter.writeMethod(ClassWriter.java:1283)
         //
         // Bytecode:
         // 00: aload 0
         // 01: aload 1
         // 02: invokevirtual dev/crucifixbeta/mod/modules/settings/impl/EnumSetting.getDisplayName ()Ljava/lang/String;
         // 05: invokespecial wtf/opal/client/feature/module/property/Property.<init> (Ljava/lang/String;)V
         // 08: aload 0
         // 09: aload 1
         // 0a: putfield wtf/opal/client/feature/module/impl/crucifix/CrucifixModuleAdapter$CrucifixEnumProperty.setting Ldev/crucifixbeta/mod/modules/settings/impl/EnumSetting;
         // 0d: aload 0
         // 0e: aload 1
         // 0f: invokevirtual dev/crucifixbeta/mod/modules/settings/impl/EnumSetting.getValue ()Ljava/lang/Enum;
         // 12: invokevirtual java/lang/Enum.getDeclaringClass ()Ljava/lang/Class;
         // 15: invokevirtual java/lang/Class.getEnumConstants ()[Ljava/lang/Object;
         // 18: checkcast [Ljava/lang/Enum;
         // 1b: putfield wtf/opal/client/feature/module/impl/crucifix/CrucifixModuleAdapter$CrucifixEnumProperty.values [Ljava/lang/Enum;
         // 1e: aload 0
         // 1f: aload 1
         // 20: invokedynamic getAsBoolean (Ldev/crucifixbeta/mod/modules/settings/impl/EnumSetting;)Ljava/util/function/BooleanSupplier; bsm=java/lang/invoke/LambdaMetafactory.metafactory (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite; args=[ ()Z, wtf/opal/client/feature/module/impl/crucifix/CrucifixModuleAdapter$CrucifixEnumProperty.lambda$new$0 (Ldev/crucifixbeta/mod/modules/settings/impl/EnumSetting;)Z, ()Z ]
         // 25: invokevirtual wtf/opal/client/feature/module/impl/crucifix/CrucifixModuleAdapter$CrucifixEnumProperty.hideIf (Ljava/util/function/BooleanSupplier;)Lwtf/opal/client/feature/module/property/Property;
         // 28: pop
         // 29: return
      }

      public Enum<?> getValue() {
         return this.setting.getValue();
      }

      public void setValue(Enum<?> value) {
         if (value != null) {
            this.setting.setEnumValue(value.name());
            super.setValue(value);
         }
      }

      public Enum<?>[] getValues() {
         return this.values;
      }

      @Override
      public PropertyPanel<?> createClickGUIComponent() {
         return new CrucifixModuleAdapter.CrucifixEnumComponent(this);
      }
   }

   @Environment(EnvType.CLIENT)
   private static final class CrucifixFriendListComponent extends PropertyPanel<CrucifixModuleAdapter.CrucifixFriendListProperty> {
      private static final int MAX_VISIBLE_ROWS;
      private static final float ROW_HEIGHT;
      private boolean focused;
      private String search = "";

      private CrucifixFriendListComponent(CrucifixModuleAdapter.CrucifixFriendListProperty property) {
         super(property);
      }

      @Override
      public void render(DrawContext context, int mouseX, int mouseY, float delta) {
         int var5 = CrucifixBeta.FRIEND == null ? 0 : CrucifixBeta.FRIEND.friendList.size();
         List var6 = this.getFilteredFriends();
         int var7 = Math.max(1, Math.min(5, var6.size()));
         this.setHeight(32.0F + (float)var7 * 11.0F);
         super.render(context, mouseX, mouseY, delta);
         FontRepository.getFont("productsans-medium")
            .drawString(CrucifixModuleAdapter.displayName(this.getProperty()), this.x + 5.0F, this.y + 8.5F, 7.0F, ColorUtility.getEnabledTextColor());
         String var8 = String.valueOf(var5);
         float var9 = FontRepository.getFont("productsans-medium").getStringWidth(var8, 7.0F);
         FontRepository.getFont("productsans-medium")
            .drawString(var8, this.x + this.width - var9 - 6.0F, this.y + 8.5F, 7.0F, ColorUtility.getDisabledTextColor());
         float var10 = this.x + 5.0F;
         float var11 = this.y + 13.0F;
         float var12 = this.width - 10.0F;
         float var13 = 11.0F;
         boolean var14 = HoverUtility.isHovering(var10, var11, var12, 11.0F, (double)mouseX, (double)mouseY);
         NVGRenderer.roundedRect(
            var10, var11, var12, 11.0F, 3.0F, ColorUtility.scaleOpacity(ColorUtility.getModuleBackgroundColor(), !this.focused && !var14 ? 0.78F : 0.92F)
         );
         NVGRenderer.roundedRectOutline(
            var10, var11, var12, 11.0F, 3.0F, 0.75F, ColorUtility.applyOpacity((Integer)ColorUtility.getClientTheme().first, this.focused ? 0.38F : 0.14F)
         );
         String var15 = this.focused && System.currentTimeMillis() / 500L % 2L == 0L ? "_" : "";
         String var16 = this.search.isEmpty() && !this.focused ? "Search" : this.search + var15;
         int var17 = this.search.isEmpty() && !this.focused ? ColorUtility.getDisabledTextColor() : ColorUtility.getEnabledTextColor();
         NVGRenderer.scissor(
            var10 + 4.0F,
            var11,
            var12 - 8.0F,
            11.0F,
            () -> FontRepository.getFont("productsans-medium").drawString(var16, var10 + 4.0F, var11 + 8.0F, 6.5F, var17)
         );
         float var18 = this.y + 27.0F;
         if (var5 == 0) {
            this.drawFriendRow(LangUtil.ui("No friends", "\u65e0\u597d\u53cb"), var18, true);
         } else if (var6.isEmpty()) {
            this.drawFriendRow(LangUtil.ui("No results", "\u65e0\u7ed3\u679c"), var18, true);
         } else {
            for (int var19 = 0; var19 < var7; var19++) {
               this.drawFriendRow((String)var6.get(var19), var18 + (float)var19 * 11.0F, false);
            }
         }
      }

      @Override
      public void mouseClicked(double mouseX, double mouseY, int button) {
         if (button == 0) {
            this.focused = HoverUtility.isHovering(this.x + 5.0F, this.y + 13.0F, this.width - 10.0F, 11.0F, mouseX, mouseY);
            DropdownClickGUI.typingString = this.focused;
         }
      }

      @Override
      public void keyPressed(KeyInput keyInput) {
         if (this.focused) {
            if (keyInput.key() == 259) {
               if (!this.search.isEmpty()) {
                  this.search = this.search.substring(0, this.search.offsetByCodePoints(this.search.length(), -1));
               }
            } else if (keyInput.key() == 257 || keyInput.key() == 335 || keyInput.key() == 256) {
               this.focused = false;
               DropdownClickGUI.typingString = false;
            }
         }
      }

      @Override
      public void charTyped(char chr, int modifiers) {
         if (this.focused && !Character.isISOControl(chr) && this.search.length() < 32) {
            this.search = this.search + chr;
         }
      }

      @Override
      public void close() {
         this.focused = false;
         DropdownClickGUI.typingString = false;
      }

      private void drawFriendRow(String text, float rowY, boolean muted) {
         NVGRenderer.roundedRect(
            this.x + 5.0F, rowY, this.width - 10.0F, 10.0F, 3.0F, ColorUtility.scaleOpacity(ColorUtility.getModuleBackgroundColor(), 0.58F)
         );
         NVGRenderer.scissor(
            this.x + 8.0F,
            rowY,
            this.width - 16.0F,
            11.0F,
            () -> FontRepository.getFont("productsans-medium")
                  .drawString(text, this.x + 8.0F, rowY + 7.5F, 6.5F, muted ? ColorUtility.getDisabledTextColor() : ColorUtility.getEnabledTextColor())
         );
      }

      private List<String> getFilteredFriends() {
         ArrayList<String> var1 = new ArrayList<>();
         if (CrucifixBeta.FRIEND == null) {
            return var1;
         } else {
            String var2 = this.search.trim().toLowerCase(Locale.ROOT);

            for (String var4 : CrucifixBeta.FRIEND.friendList) {
               if (var4 != null && !var4.isBlank() && (var2.isEmpty() || var4.toLowerCase(Locale.ROOT).contains(var2))) {
                  var1.add(var4);
               }
            }

            var1.sort(String::compareToIgnoreCase);
            return var1;
         }
      }

      static {

         ROW_HEIGHT = 11.0F;
         MAX_VISIBLE_ROWS = 5;
      }
}

   @Environment(EnvType.CLIENT)
   private static final class CrucifixFriendListProperty extends Property<String> {

      private CrucifixFriendListProperty() {
         super("Friends");
         this.id("FriendList");
      }

      public String getValue() {
         return "";
      }

      @Override
      public PropertyPanel<?> createClickGUIComponent() {
         return new CrucifixModuleAdapter.CrucifixFriendListComponent(this);
      }
}

   @Environment(EnvType.CLIENT)
   private static final class CrucifixLabelComponent extends PropertyPanel<CrucifixModuleAdapter.CrucifixBindProperty> {
      private boolean listening;

      private CrucifixLabelComponent(CrucifixModuleAdapter.CrucifixBindProperty property) {
         super(property);
      }

      @Override
      public void render(DrawContext context, int mouseX, int mouseY, float delta) {
         super.render(context, mouseX, mouseY, delta);
         FontRepository.getFont("productsans-medium")
            .drawString(CrucifixModuleAdapter.displayName(this.getProperty()), this.x + 5.0F, this.y + 10.5F, 7.0F, ColorUtility.getEnabledTextColor());
         boolean var5 = InputUtil.isKeyPressed(MinecraftClient.getInstance().getWindow().getHandle(), 344);
         BindSetting var6 = this.getProperty().getBindSetting();
         String var7;
         int var8;
         if (this.listening) {
            var7 = "Press key...";
            var8 = (Integer)ColorUtility.getClientTheme().first;
         } else if (var5 && HoverUtility.isHovering(this.x, this.y, this.width, this.height, (double)mouseX, (double)mouseY)) {
            var7 = var6.isHoldEnable() ? "\u2192 Toggle" : "\u2192 Hold";
            var8 = (Integer)ColorUtility.getClientTheme().first;
         } else {
            String var9 = var6.isHoldEnable() ? " [Hold]" : "";
            var7 = this.getProperty().getValue() + var9;
            var8 = -8355712;
         }

         float var10 = FontRepository.getFont("productsans-medium").getStringWidth(var7, 7.0F);
         FontRepository.getFont("productsans-medium").drawString(var7, this.x + this.width - var10 - 6.0F, this.y + 10.5F, 7.0F, var8);
         if (this.listening) {
            DropdownClickGUI.typingString = true;
         }
      }

      @Override
      public void mouseClicked(double mouseX, double mouseY, int button) {
         if (HoverUtility.isHovering(this.x, this.y, this.width, this.height, mouseX, mouseY)) {
            boolean var6 = InputUtil.isKeyPressed(MinecraftClient.getInstance().getWindow().getHandle(), 344);
            BindSetting var7 = this.getProperty().getBindSetting();
            if (var6 && button == 0) {
               var7.setHoldEnable(!var7.isHoldEnable());
            } else {
               if (this.listening) {
                  var7.setValue(-button - 2);
                  this.listening = false;
                  DropdownClickGUI.typingString = false;
               } else if (button == 0) {
                  this.listening = true;
               }
            }
         }
      }

      @Override
      public void keyPressed(KeyInput keyInput) {
         if (this.listening) {
            BindSetting var2 = this.getProperty().getBindSetting();
            if (keyInput.key() == 256) {
               this.listening = false;
               DropdownClickGUI.typingString = false;
            } else if (keyInput.key() == 261) {
               var2.setValue(-1);
               this.listening = false;
               DropdownClickGUI.typingString = false;
            } else {
               var2.setValue(keyInput.key());
               this.listening = false;
               DropdownClickGUI.typingString = false;
            }
         }
      }

      @Override
      public void close() {
         this.listening = false;
         DropdownClickGUI.typingString = false;
      }
}

   @Environment(EnvType.CLIENT)
   private static final class CrucifixNumberComponent extends PropertyPanel<CrucifixModuleAdapter.CrucifixNumberProperty> {
      private boolean dragging;
      private Animation fillAnimation;

      private CrucifixNumberComponent(CrucifixModuleAdapter.CrucifixNumberProperty property) {
         super(property);
      }

      @Override
      public void render(DrawContext context, int mouseX, int mouseY, float delta) {
         this.setHeight(15.0F);
         super.render(context, mouseX, mouseY, delta);
         CrucifixModuleAdapter.CrucifixNumberProperty var5 = this.getProperty();
         float var6 = this.width - 12.0F;
         float var7 = this.x + 6.0F;
         float var8 = this.y + 13.0F;
         if (this.dragging && mouseX != -1) {
            float var9 = Math.min(1.0F, Math.max(0.0F, ((float)mouseX - var7) / var6));
            var5.setValue(MathUtility.interpolate(var5.getMinValue(), var5.getMaxValue(), (double)var9));
         }

         String var16 = formatValue(var5.getValue(), var5.getSuffix());
         FontRepository.getFont("productsans-medium")
            .drawString(CrucifixModuleAdapter.displayName(var5) + ":" + var16, this.x + 5.0F, this.y + 8.5F, 7.0F, ColorUtility.getEnabledTextColor());
         double var10 = (var5.getValue() - var5.getMinValue()) / (var5.getMaxValue() - var5.getMinValue());
         float var12 = (float)((double)var6 * Math.max(0.0, Math.min(1.0, var10)));
         long var13 = ClientSetting.sliderFollowDuration(50L);
         if (this.fillAnimation == null) {
            this.fillAnimation = new Animation(Easing.LINEAR, var13);
            this.fillAnimation.setValue(var12);
         } else {
            this.fillAnimation.setDuration(var13);
            this.fillAnimation.run(var12);
         }

         float var15 = this.fillAnimation.getValue();
         NVGRenderer.roundedRect(var7, var8, var6, 2.5F, 1.25F, ColorUtility.scaleOpacity(ColorUtility.getModuleBackgroundColor(), 0.82F));
         NVGRenderer.roundedRect(var7, var8, var15, 2.5F, 1.25F, (Integer)ColorUtility.getClientTheme().first);
         NVGRenderer.roundedRect(var7 + var15 - 1.0F, var8 - 1.3F, 2.0F, 5.0F, 1.0F, -1);
      }

      @Override
      public void mouseClicked(double mouseX, double mouseY, int button) {
         if (HoverUtility.isHovering(this.x, this.y, this.width, this.height, mouseX, mouseY) && button == 0) {
            this.dragging = true;
         }
      }

      @Override
      public void mouseReleased(double mouseX, double mouseY, int button) {
         if (button == 0) {
            this.dragging = false;
         }
      }

      private static String formatValue(Number value, String suffix) {
         String var2;
         if (value.doubleValue() == (double)value.intValue()) {
            var2 = String.valueOf(value.intValue());
         } else {
            var2 = String.format(Locale.ROOT, "%.3f", value.doubleValue())
               .replaceAll("0+$", "")
               .replaceAll("\\.$", "");
         }

         return suffix == null ? var2 : var2 + suffix;
      }
}

   @Environment(EnvType.CLIENT)
   private static final class CrucifixNumberProperty extends Property<Double> {
      private final SliderSetting setting;

      private CrucifixNumberProperty(SliderSetting setting) {
         super(setting.getDisplayName());
         this.setting = setting;
         this.hideIf(() -> !setting.isVisible());
      }

      public Double getValue() {
         return this.setting.getValue();
      }

      public void setValue(Double value) {
         this.setting.setValue(value);
         super.setValue(this.setting.getValue());
      }

      public double getMinValue() {
         return this.setting.getMin();
      }

      public double getMaxValue() {
         return this.setting.getMax();
      }

      public String getSuffix() {
         return this.setting.getSuffix();
      }

      @Override
      public PropertyPanel<?> createClickGUIComponent() {
         return new CrucifixModuleAdapter.CrucifixNumberComponent(this);
      }
   }

   @Environment(EnvType.CLIENT)
   private static final class CrucifixStringComponent extends PropertyPanel<CrucifixModuleAdapter.CrucifixStringProperty> {
      private boolean focused;

      private CrucifixStringComponent(CrucifixModuleAdapter.CrucifixStringProperty property) {
         super(property);
      }

      @Override
      public void render(DrawContext context, int mouseX, int mouseY, float delta) {
         this.setHeight(26.0F);
         super.render(context, mouseX, mouseY, delta);
         FontRepository.getFont("productsans-medium")
            .drawString(CrucifixModuleAdapter.displayName(this.getProperty()), this.x + 5.0F, this.y + 8.5F, 7.0F, ColorUtility.getEnabledTextColor());
         NVGRenderer.roundedRect(
            this.x + 5.0F, this.y + 13.0F, this.width - 10.0F, 10.0F, 2.5F, ColorUtility.scaleOpacity(ColorUtility.getModuleBackgroundColor(), 0.86F)
         );
         String var5 = this.focused && System.currentTimeMillis() / 500L % 2L == 0L ? "_" : "";
         FontRepository.getFont("productsans-medium").drawString(this.getProperty().getValue() + var5, this.x + 7.0F, this.y + 20.0F, 7.0F, -8355712);
      }

      @Override
      public void mouseClicked(double mouseX, double mouseY, int button) {
         this.focused = button == 0 && HoverUtility.isHovering(this.x, this.y, this.width, this.height, mouseX, mouseY);
         DropdownClickGUI.typingString = this.focused;
      }

      @Override
      public void keyPressed(KeyInput keyInput) {
         if (this.focused) {
            if (keyInput.key() == 259) {
               String var2 = this.getProperty().getValue();
               if (!var2.isEmpty()) {
                  this.getProperty().setValue(var2.substring(0, var2.offsetByCodePoints(var2.length(), -1)));
               }
            } else if (keyInput.key() == 257 || keyInput.key() == 335 || keyInput.key() == 256) {
               this.focused = false;
               DropdownClickGUI.typingString = false;
            }
         }
      }

      @Override
      public void charTyped(char chr, int modifiers) {
         if (this.focused && !Character.isISOControl(chr)) {
            this.getProperty().setValue(this.getProperty().getValue() + chr);
         }
      }
}

   @Environment(EnvType.CLIENT)
   private static final class CrucifixStringProperty extends Property<String> {
      private final StringSetting setting;

      private CrucifixStringProperty(StringSetting setting) {
         super(setting.getDisplayName());
         this.setting = setting;
         this.hideIf(() -> !setting.isVisible());
      }

      public String getValue() {
         return this.setting.getValue();
      }

      public void setValue(String value) {
         this.setting.setValue(value == null ? "" : value);
         super.setValue(this.setting.getValue());
      }

      @Override
      public PropertyPanel<?> createClickGUIComponent() {
         return new CrucifixModuleAdapter.CrucifixStringComponent(this);
      }
}
}
