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

import com.google.gson.internal.LinkedTreeMap;
import com.ibm.icu.impl.Pair;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.util.Window;
import wtf.opal.client.Constants;
import wtf.opal.client.feature.module.property.Property;
import wtf.opal.client.feature.module.property.impl.mode.ModuleMode;

@Environment(EnvType.CLIENT)
public final class ScreenPositionProperty extends Property<Pair<Float, Float>> {
   private float startX;
   private float startY;
   private float width;
   private float height;
   private boolean dragging;

   public ScreenPositionProperty(String name, float relativeX, float relativeY) {
      super(name);
      this.setValue(Pair.of(relativeX, relativeY));
   }

   public ScreenPositionProperty(String name, ModuleMode<?> parent, float relativeX, float relativeY) {
      super(name, parent);
      this.setValue(Pair.of(relativeX, relativeY));
   }

   @Override
   public void applyValue(Object propertyValue) {
      if (propertyValue instanceof LinkedTreeMap var2) {
         if (var2.isEmpty()) {
            return;
         }

         Double var3 = (Double)var2.get("x");
         Double var4 = (Double)var2.get("y");
         if (var3 == null || var4 == null) {
            return;
         }

         this.setValue(Pair.of(var3.floatValue(), var4.floatValue()));
      }
   }

   public float getRelativeX() {
      return (Float)this.getValue().first;
   }

   public float getRelativeY() {
      return (Float)this.getValue().second;
   }

   public float getScaledX() {
      float var1 = this.getRelativeX();
      float var2 = var1 * (float)Constants.mc.getWindow().getScaledWidth();
      return var1 > 0.5F ? var2 - this.width : var2;
   }

   public float getScaledY() {
      return this.getRelativeY() * (float)Constants.mc.getWindow().getScaledHeight();
   }

   public void _setRelativeX(float relativeX) {
      this.setValue(Pair.of(relativeX, this.getRelativeY()));
   }

   public void _setRelativeY(float relativeY) {
      this.setValue(Pair.of(this.getRelativeX(), relativeY));
   }

   public void setRelativeX(float scaledX) {
      int var2 = Constants.mc.getWindow().getScaledWidth();
      float var3 = scaledX / (float)var2;
      if (var3 > 0.5F) {
         var3 += this.width / (float)var2;
      }

      this._setRelativeX(var3);
   }

   public void setRelativeY(float scaledY) {
      float var2 = scaledY / (float)Constants.mc.getWindow().getScaledHeight();
      this._setRelativeY(var2);
   }

   public void snapToGrid() {
      Window var1 = Constants.mc.getWindow();
      int var2 = var1.getScaledWidth();
      int var3 = var1.getScaledHeight();
      float var4 = this.getRelativeX();
      float var5 = this.getRelativeY();
      float var6 = this.width / (float)var2;
      float var7 = this.height / (float)var3;
      float var8 = var6 / 2.0F;
      float var9 = var7 / 2.0F;
      if (var4 < 0.01F) {
         this._setRelativeX(0.0F);
      } else if (var4 > 0.99F) {
         this._setRelativeX(1.0F);
      } else if (var4 + var8 > 0.49F && var4 + var8 < 0.51F) {
         this._setRelativeX(0.5F - var8);
      }

      if (var5 < 0.01F) {
         this._setRelativeY(0.0F);
      } else if (var5 + var7 > 0.99F) {
         this._setRelativeY(1.0F - var7);
      } else if (var5 + var9 > 0.49F && var5 + var9 < 0.51F) {
         this._setRelativeY(0.5F - var9);
      }
   }

   public float getWidth() {
      return this.width;
   }

   public float getHeight() {
      return this.height;
   }

   public void setWidth(float width) {
      this.width = width;
   }

   public void setHeight(float height) {
      this.height = height;
   }

   public boolean isDragging() {
      return this.dragging;
   }

   public void setDragging(boolean dragging) {
      this.dragging = dragging;
   }

   public float getStartX() {
      return this.startX > (float)Constants.mc.getWindow().getScaledWidth() / 2.0F ? this.startX - this.width : this.startX;
   }

   public float getStartY() {
      return this.startY;
   }

   public void setStartX(float startX) {
      this.startX = startX;
   }

   public void setStartY(float startY) {
      this.startY = startY;
   }
}
