package wtf.opal.client.screen.click.dropdown;

import dev.crucifixbeta.mod.modules.impl.client.ClientSetting;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import wtf.opal.utility.render.animation.Animation;
import wtf.opal.utility.render.animation.Easing;

@Environment(EnvType.CLIENT)
public final class ClickGuiAnimationConfig {
   private ClickGuiAnimationConfig() {
   }

   public static void applyClickGuiOpenClose(Animation animation, long defaultDuration, Easing defaultEasing) {
      apply(
         animation, mode(ClientSetting.INSTANCE == null ? null : ClientSetting.INSTANCE.clickGuiOpenCloseAnimation.getValue()), defaultDuration, defaultEasing
      );
   }

   public static void applyFunctionBar(Animation animation, long defaultDuration, Easing defaultEasing) {
      apply(animation, mode(ClientSetting.INSTANCE == null ? null : ClientSetting.INSTANCE.functionBarAnimation.getValue()), defaultDuration, defaultEasing);
   }

   public static void applyParameterPanel(Animation animation, long defaultDuration, Easing defaultEasing) {
      apply(animation, mode(ClientSetting.INSTANCE == null ? null : ClientSetting.INSTANCE.parameterPanelAnimation.getValue()), defaultDuration, defaultEasing);
   }

   public static void applyPageSwitch(Animation animation, long defaultDuration, Easing defaultEasing) {
      apply(animation, mode(ClientSetting.INSTANCE == null ? null : ClientSetting.INSTANCE.pageSwitchAnimation.getValue()), defaultDuration, defaultEasing);
   }

   public static long clickGuiCloseDelay(long defaultDuration) {
      return duration(mode(ClientSetting.INSTANCE == null ? null : ClientSetting.INSTANCE.clickGuiOpenCloseAnimation.getValue()), defaultDuration);
   }

   private static ClientSetting.GuiAnimation mode(ClientSetting.GuiAnimation mode) {
      return mode == null ? ClientSetting.GuiAnimation.Default : mode;
   }

   private static void apply(Animation animation, ClientSetting.GuiAnimation mode, long defaultDuration, Easing defaultEasing) {
      animation.setEasing(easing(mode, defaultEasing));
      animation.setDuration(duration(mode, defaultDuration));
   }

   private static Easing easing(ClientSetting.GuiAnimation mode, Easing defaultEasing) {
      return switch (mode) {
         case Default -> defaultEasing;
         case Off, Linear -> Easing.LINEAR;
         case Smooth -> Easing.SMOOTH_STEP;
         case Fast -> Easing.EASE_OUT_CUBIC;
         case Slow -> Easing.EASE_OUT_SINE;
         case Elastic -> Easing.EASE_OUT_ELASTIC;
      };
   }

   private static long duration(ClientSetting.GuiAnimation mode, long defaultDuration) {
      float var3 = switch (mode) {
         case Default, Linear, Smooth -> 1.0F;
         case Off -> 0.0F;
         case Fast -> 0.65F;
         case Slow -> 1.45F;
         case Elastic -> 1.25F;
      };
      return Math.max(0L, (long)Math.round((float)defaultDuration * var3));
   }
}
