package dev.crucifixbeta.api.utils.render;

import dev.crucifixbeta.api.utils.Wrapper;
import dev.crucifixbeta.core.impl.FontManager;
import dev.crucifixbeta.mod.modules.impl.render.AntiAlias;
import java.awt.Color;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.render.Camera;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.math.Vec3d;
import org.joml.Matrix4f;
import org.joml.Vector3f;
import org.joml.Vector4f;
import org.lwjgl.opengl.GL11;

@Environment(EnvType.CLIENT)
public class TextUtil implements Wrapper {
   public static final Matrix4f lastProjMat = new Matrix4f();
   public static final Matrix4f lastModMat = new Matrix4f();
   public static final Matrix4f lastWorldSpaceMatrix = new Matrix4f();

   public static float getWidth(String s) {
      return FontManager.shouldUseClientFont(s, false) ? FontManager.ui.getWidth(s) : (float)mc.textRenderer.getWidth(s);
   }

   public static float getHeight() {
      return 9.0F;
   }

   public static void drawStringWithScale(DrawContext drawContext, String text, float x, float y, int color, float scale) {
      MatrixStack var6 = drawContext.getMatrices();
      boolean var7 = scale != 1.0F;
      if (var7) {
         var6.push();
         var6.scale(scale, scale, 1.0F);
         if (scale > 1.0F) {
            var6.translate(-x / scale, -y / scale, 0.0F);
         } else {
            var6.translate(x / scale / 2.0F, y / scale / 2.0F, 0.0F);
         }
      }

      drawString(drawContext, text, (double)x, (double)y, color);
      if (var7) {
         var6.pop();
      }
   }

   public static void drawStringScale(DrawContext drawContext, String text, float x, float y, int color, float scale, boolean shadow) {
      drawStringScale(drawContext, text, x, y, color, scale, shadow, false);
   }

   public static void drawStringScale(DrawContext drawContext, String text, float x, float y, int color, float scale, boolean shadow, boolean customFont) {
      MatrixStack var8 = drawContext.getMatrices();
      boolean var9 = scale != 1.0F;
      if (var9) {
         var8.push();
         var8.scale(scale, scale, 1.0F);
         if (scale > 1.0F) {
            var8.translate(-x / scale, -y / scale, 0.0F);
         } else {
            var8.translate(x / scale / 2.0F, y / scale / 2.0F, 0.0F);
         }
      }

      drawString(drawContext, text, (double)x, (double)y, color, customFont, shadow);
      if (var9) {
         var8.pop();
      }
   }

   public static void drawString(DrawContext drawContext, String text, double x, double y, int color) {
      drawString(drawContext, text, x, y, color, false);
   }

   public static void drawString(DrawContext drawContext, String text, double x, double y, int color, boolean customFont) {
      drawString(drawContext, text, x, y, color, customFont, false);
   }

   public static void drawString(DrawContext drawContext, String text, double x, double y, int color, boolean customFont, boolean shadow) {
      AntiAlias.withTextRender(() -> {
         if (FontManager.shouldUseClientFont(text, customFont)) {
            FontManager.ui.drawString(drawContext.getMatrices(), text, (double)((int)x), (double)((int)y), color, false);
         } else {
            AntiAlias.drawText(drawContext, mc.textRenderer, text, (int)x, (int)y, color, false);
         }
      });
   }

   public static void drawStringPulse(
      DrawContext drawContext, String text, double x, double y, Color startColor, Color endColor, double speed, int counter, boolean customFont
   ) {
      char[] var12 = text.toCharArray();
      int var13 = 0;
      boolean var14 = false;
      String var15 = null;

      for (char var19 : var12) {
         if (var19 == 167) {
            var14 = true;
         } else if (var14) {
            var15 = var19 == 'r' ? null : "§" + var19;
            var14 = false;
         } else {
            var13++;
            if (var15 != null) {
               drawString(drawContext, var15 + var19, x, y, startColor.getRGB(), customFont);
            } else {
               drawString(
                  drawContext, String.valueOf(var19), x, y, ColorUtil.pulseColor(startColor, endColor, (double)var13, counter, speed).getRGB(), customFont
               );
            }

            String var20 = String.valueOf(var19);
            x += FontManager.shouldUseClientFont(var20, customFont) ? (double)FontManager.ui.getWidth(var20) : (double)mc.textRenderer.getWidth(var20);
         }
      }
   }

   public static void drawStringPulse(
      DrawContext drawContext, String text, double x, double y, Color startColor, Color endColor, double speed, int counter, boolean customFont, boolean shadow
   ) {
      char[] var13 = text.toCharArray();
      int var14 = 0;
      boolean var15 = false;
      String var16 = null;

      for (char var20 : var13) {
         if (var20 == 167) {
            var15 = true;
         } else if (var15) {
            var16 = var20 == 'r' ? null : "§" + var20;
            var15 = false;
         } else {
            var14++;
            if (var16 != null) {
               drawString(drawContext, var16 + var20, x, y, startColor.getRGB(), customFont, shadow);
            } else {
               drawString(
                  drawContext,
                  String.valueOf(var20),
                  x,
                  y,
                  ColorUtil.pulseColor(startColor, endColor, (double)var14, counter, speed).getRGB(),
                  customFont,
                  shadow
               );
            }

            String var21 = String.valueOf(var20);
            x += FontManager.shouldUseClientFont(var21, customFont) ? (double)FontManager.ui.getWidth(var21) : (double)mc.textRenderer.getWidth(var21);
         }
      }
   }

   public static Vec3d worldSpaceToScreenSpace(Vec3d pos) {
      Camera var1 = mc.getEntityRenderDispatcher().camera;
      int var2 = mc.getWindow().getHeight();
      int[] var3 = new int[4];
      GL11.glGetIntegerv(2978, var3);
      Vector3f var4 = new Vector3f();
      double var5 = pos.x - var1.getPos().x;
      double var7 = pos.y - var1.getPos().y;
      double var9 = pos.z - var1.getPos().z;
      Vector4f var11 = new Vector4f((float)var5, (float)var7, (float)var9, 1.0F).mul(lastWorldSpaceMatrix);
      Matrix4f var12 = new Matrix4f(lastProjMat);
      Matrix4f var13 = new Matrix4f(lastModMat);
      var12.mul(var13).project(var11.x(), var11.y(), var11.z(), var3, var4);
      return new Vec3d((double)var4.x / mc.getWindow().getScaleFactor(), (double)((float)var2 - var4.y) / mc.getWindow().getScaleFactor(), (double)var4.z);
   }
}
