package dev.crucifixbeta.mod.modules.impl.client.hud;

import dev.crucifixbeta.CrucifixBeta;
import dev.crucifixbeta.api.events.eventbus.EventListener;
import dev.crucifixbeta.api.events.impl.ClientTickEvent;
import dev.crucifixbeta.api.events.impl.InitEvent;
import dev.crucifixbeta.api.utils.math.Animation;
import dev.crucifixbeta.api.utils.math.Easing;
import dev.crucifixbeta.api.utils.render.ColorUtil;
import dev.crucifixbeta.api.utils.render.Render2DUtil;
import dev.crucifixbeta.api.utils.render.TextUtil;
import dev.crucifixbeta.core.impl.FontManager;
import dev.crucifixbeta.mod.modules.HudModule;
import dev.crucifixbeta.mod.modules.Module;
import dev.crucifixbeta.mod.modules.impl.client.ColorsModule;
import dev.crucifixbeta.mod.modules.settings.impl.BooleanSetting;
import dev.crucifixbeta.mod.modules.settings.impl.EnumSetting;
import dev.crucifixbeta.mod.modules.settings.impl.SliderSetting;
import java.awt.Color;
import java.util.ArrayList;
import java.util.Comparator;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.gui.DrawContext;

@Environment(EnvType.CLIENT)
public class ArrayListHudModule extends HudModule {
   public static ArrayListHudModule INSTANCE;
   private final BooleanSetting lowerCase = this.add(new BooleanSetting("LowerCase", false));
   private final BooleanSetting listSort = this.add(new BooleanSetting("ListSort", true));
   private final BooleanSetting rightAlign = this.add(new BooleanSetting("RightAlign", true));
   private final SliderSetting xOffset = this.add(new SliderSetting("XOffset", 0.0, 0.0, 50.0, 0.1));
   private final SliderSetting textOffset = this.add(new SliderSetting("TextOffset", 0.0, -10.0, 10.0, 0.1));
   private final SliderSetting interval = this.add(new SliderSetting("Interval", 0.0, 0.0, 15.0, 0.1));
   private final SliderSetting enableLength = this.add(new SliderSetting("EnableLength", 200, 0, 1000));
   private final SliderSetting disableLength = this.add(new SliderSetting("DisableLength", 200, 0, 1000));
   private final SliderSetting fadeLength = this.add(new SliderSetting("FadeLength", 200, 0, 1000));
   private final EnumSetting<Easing> easing = this.add(new EnumSetting<>("Easing", Easing.CircInOut));
   private final BooleanSetting blur = this.add(new BooleanSetting("Blur", false).setParent());
   private final SliderSetting radius = this.add(new SliderSetting("Radius", 10.0, 0.0, 100.0, () -> this.blur.isOpen()));
   private final BooleanSetting backGround = this.add(new BooleanSetting("BackGround", false).setParent());
   private final SliderSetting width = this.add(new SliderSetting("Width", 0.0, 0.0, 15.0, () -> this.backGround.isOpen()));
   private final BooleanSetting rect = this.add(new BooleanSetting("Rect", false));
   private final BooleanSetting glow = this.add(new BooleanSetting("Glow", false));
   private final ArrayList<ArrayListHudModule.Entry> entries = new ArrayList<>();

   public ArrayListHudModule() {
      super("ArrayList", "", "\u6a21\u5757\u5217\u8868", 2, 2, HudModule.Corner.RightTop);
      INSTANCE = this;
      CrucifixBeta.EVENT_BUS.subscribe(new ArrayListHudModule.InitHandler());
   }

   @Override
   public void onRender2D(DrawContext context, float tickDelta) {
      if (Module.nullCheck()) {
         this.clearHudBounds();
      } else {
         int var3 = this.getFontHeight();
         double var4 = 0.0;

         for (ArrayListHudModule.Entry var7 : this.entries) {
            var7.prepare(this);
            if (!(var7.renderFade <= 0.01) || !(var7.renderWidth <= 0.01)) {
               var4 = Math.max(var4, var7.renderWidth);
            }
         }

         if (var4 <= 0.5) {
            this.clearHudBounds();
         } else {
            float var35 = this.width.getValueFloat();
            float var36 = var35 / 2.0F;
            float var8 = (float)var3 + this.interval.getValueFloat();
            float var9 = this.interval.getValueFloat() / 2.0F;
            double var10 = 0.0;

            for (ArrayListHudModule.Entry var13 : this.entries) {
               if (!(var13.renderFade <= 0.04)) {
                  var10 += ((double)var3 + this.interval.getValue()) * var13.renderFade;
               }
            }

            int var37 = Math.max(1, (int)Math.ceil(var4 + (double)var35 + (double)var36));
            int var38 = Math.max(1, (int)Math.ceil(Math.max(1.0, var10 + (double)var3)));
            int var14 = this.getHudRenderX(var37);
            int var15 = this.getHudRenderY(var38);
            int var16 = (int)Math.floor((double)var14 + (double)var36);
            double var18 = 20.0;
            double var20 = (double)var15;

            for (ArrayListHudModule.Entry var23 : this.entries) {
               if (!(var23.renderFade <= 0.04)) {
                  double var24 = var23.renderWidth;
                  float var26 = this.rightAlign.getValue() ? (float)((double)var16 + var4 - var24) : (float)var16;
                  double var27 = var23.renderFade;
                  Color var29 = this.getHudColor(var18 += var27);
                  int var30 = var29.getAlpha();
                  int var31 = ColorUtil.injectAlpha(var29.getRGB(), (int)((double)var30 * var27));
                  float var32 = var26 - var36;
                  float var33 = (float)var20 - 1.0F - var9;
                  float var34 = (float)(var24 + (double)var35);
                  if (this.blur.getValue()) {
                     CrucifixBeta.BLUR.applyBlur((float)(this.radius.getValue() * var27), var32, var33, var34, var8);
                  }

                  if (this.backGround.getValue()) {
                     Render2DUtil.drawRect(context.getMatrices(), var32, var33, var34, var8, this.getHudBackgroundColor(var27).getRGB());
                  }

                  if (this.glow.getValue()) {
                     Render2DUtil.drawGlow(context.getMatrices(), var32, var33, var34, var8, this.getHudGlowColor(var27).getRGB());
                  }

                  TextUtil.drawString(context, var23.string, (double)var26, var20 + (double)this.textOffset.getValueFloat(), var31, HudSetting.useFont(), false);
                  if (this.rect.getValue()) {
                     Render2DUtil.drawRect(context.getMatrices(), var32 + var34, var33, 1.0F, var8, this.getHudRectColor(var27).getRGB());
                  }

                  var20 += ((double)var3 + this.interval.getValue()) * var27;
               }
            }

            this.setHudBounds(var14, var15, var37, var38);
         }
      }
   }

   @EventListener(
      priority = -999
   )
   public void onUpdate(ClientTickEvent event) {
      if (!Module.nullCheck()) {
         if (event.isPost()) {
            for (ArrayListHudModule.Entry var3 : this.entries) {
               var3.onUpdate(this);
            }

            if (this.listSort.getValue()) {
               this.entries.sort(Comparator.comparingInt(e -> e.string == null ? 0 : -this.getWidth(e.string)));
            }
         }
      }
   }

   private int getWidth(String s) {
      if (s == null) {
         return 0;
      } else {
         return HudSetting.useFont() ? (int)FontManager.ui.getWidth(s) : mc.textRenderer.getWidth(s);
      }
   }

   private int getFontHeight() {
      return HudSetting.useFont() ? (int)FontManager.ui.getFontHeight() : 9;
   }

   private Color getHudColor(double counter) {
      ColorsModule var3 = ColorsModule.INSTANCE;
      return var3 == null ? Color.WHITE : var3.getHudColor(counter);
   }

   private Color getHudBackgroundColor(double fade) {
      ColorsModule var3 = ColorsModule.INSTANCE;
      return var3 == null ? ColorUtil.injectAlpha(Color.BLACK, (int)(100.0 * fade)) : var3.getHudBackgroundColor(fade);
   }

   private Color getHudRectColor(double fade) {
      ColorsModule var3 = ColorsModule.INSTANCE;
      return var3 == null ? ColorUtil.injectAlpha(Color.WHITE, (int)(255.0 * fade)) : var3.getHudRectColor(fade);
   }

   private Color getHudGlowColor(double fade) {
      ColorsModule var3 = ColorsModule.INSTANCE;
      return var3 == null ? ColorUtil.injectAlpha(Color.WHITE, (int)(255.0 * fade)) : var3.getHudGlowColor(fade);
   }
@Environment(EnvType.CLIENT)
   private static final class Entry {
      private final Module module;
      private String string = "";
      private boolean isOn;
      private double currentX = 0.0;
      private final Animation animation = new Animation();
      private final Animation fadeAnimation = new Animation();
      private double renderWidth;
      private double renderFade;

      private Entry(Module module) {
         this.module = module;
      }

      private void onUpdate(ArrayListHudModule parent) {
         this.isOn = this.module.isOn() && this.module.drawn.getValue();
         if (this.isOn) {
            String var2 = this.module.getArrayName();
            if (var2 == null) {
               var2 = "";
            }

            this.string = parent.lowerCase.getValue() ? var2.toLowerCase() : var2;
         }
      }

      private void prepare(ArrayListHudModule parent) {
         if (this.currentX <= 0.0 && !this.isOn) {
            this.renderWidth = 0.0;
            this.renderFade = 0.0;
         } else {
            String var2 = this.string == null ? "" : this.string;
            double var3 = (double)(parent.getWidth(var2) + 1);
            this.currentX = this.animation
               .get(
                  this.isOn ? var3 : 0.0,
                  this.isOn ? (long)parent.enableLength.getValueInt() : (long)parent.disableLength.getValueInt(),
                  parent.easing.getValue()
               );
            this.renderFade = this.fadeAnimation.get(this.isOn ? 1.0 : 0.0, (long)parent.fadeLength.getValueInt(), parent.easing.getValue());
            this.renderWidth = this.currentX + (double)parent.xOffset.getValueFloat();
         }
      }
}

   @Environment(EnvType.CLIENT)
   private class InitHandler {
      @EventListener
      public void onInit(InitEvent event) {
         for (Module var3 : CrucifixBeta.MODULE.getModules()) {
            ArrayListHudModule.this.entries.add(new ArrayListHudModule.Entry(var3));
         }

         CrucifixBeta.EVENT_BUS.unsubscribe(this);
      }
   }
}
