package net.moonleay.gimble.mixin;

import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.client.option.GameOptions;
import net.moonleay.gimble.client.editor.ClientEditor;
import net.moonleay.gimble.editor.state.mode.Capability;
import net.moonleay.gimble.editor.state.mode.Mode;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(MinecraftClient.class)
public class NormalModeMixin {

    @Shadow
    @Nullable
    public GameOptions options;

    @Shadow
    @Nullable
    public ClientPlayerEntity player;

    @Inject(method = "openPauseMenu", at = @At("HEAD"), cancellable = true)
    private void setNormalMode(boolean pause, CallbackInfo ci) {
        if (ClientEditor.INSTANCE.isInNonDefaultMode() && ClientEditor.INSTANCE.isAllowed()) {
            assert this.player != null;
            if (this.player.isCreative()) {
                // Set the editor mode to normal
                ClientEditor.INSTANCE.setMode(Mode.NORMAL);
                ci.cancel();
            }
        }
    }

    @Inject(method = "handleInputEvents", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;isUsingItem()Z"), cancellable = true)
    private void blockWorldManipulation(CallbackInfo ci) {
        // This could be replaced by net.minecraft.world.GameMode#isBlockBreakingRestricted
        if (!ClientEditor.INSTANCE.shouldClient(Capability.CAN_INTERACT)) {
            assert this.player != null;
            if (this.player.isCreative()) {
                while (this.options.attackKey.wasPressed()) {
                }

                while (this.options.useKey.wasPressed()) {
                }

                while (this.options.pickItemKey.wasPressed()) {
                }
                ci.cancel();
            }
        }
    }
}
