package asm.mixins;

import asm.accessors.IPostProcessShader;
import dev.crucifixbeta.api.interfaces.IShaderEffectHook;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.gl.Framebuffer;
import net.minecraft.client.gl.PostEffectPass;
import net.minecraft.client.gl.PostEffectProcessor;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Environment(EnvType.CLIENT)
@Mixin({PostEffectProcessor.class})
public class MixinShaderEffect implements IShaderEffectHook {
   @Unique
   private final List<String> fakedBufferNames = new ArrayList<>();
   @Shadow
   @Final
   private Map<String, Framebuffer> targetsByName;
   @Shadow
   @Final
   private List<PostEffectPass> passes;

   @Override
   public void frogClient$addHook(String name, Framebuffer buffer) {
      Framebuffer var3 = this.targetsByName.get(name);
      if (var3 != buffer) {
         if (var3 != null) {
            for (PostEffectPass var5 : this.passes) {
               if (var5.input == var3) {
                  ((IPostProcessShader)var5).setInput(buffer);
               }

               if (var5.output == var3) {
                  ((IPostProcessShader)var5).setOutput(buffer);
               }
            }

            this.targetsByName.remove(name);
            this.fakedBufferNames.remove(name);
         }

         this.targetsByName.put(name, buffer);
         this.fakedBufferNames.add(name);
      }
   }

   @Inject(
      method = {"close"},
      at = {@At("HEAD")}
   )
   void deleteFakeBuffersHook(CallbackInfo ci) {
      for (String var3 : this.fakedBufferNames) {
         this.targetsByName.remove(var3);
      }
   }
}
