package net.minecraft.client.gui.screens.inventory;

import net.minecraft.world.item.BannerItem;
import net.minecraft.util.Mth;
import net.minecraft.client.resources.sounds.SoundInstance;
import net.minecraft.client.resources.sounds.SimpleSoundInstance;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.client.Minecraft;
import net.minecraft.world.entity.player.Player;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.block.entity.BannerBlockEntity;
import net.minecraft.nbt.Tag;
import net.minecraft.world.level.ItemLike;
import net.minecraft.world.item.Items;
import net.minecraft.world.inventory.Slot;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.resources.model.ModelBakery;
import net.minecraft.client.renderer.texture.OverlayTexture;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.platform.Lighting;
import net.minecraft.client.renderer.blockentity.BannerRenderer;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.item.ItemStack;
import javax.annotation.Nullable;
import net.minecraft.world.item.DyeColor;
import net.minecraft.world.level.block.entity.BannerPattern;
import com.mojang.datafixers.util.Pair;
import java.util.List;
import net.minecraft.client.model.geom.ModelPart;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.inventory.LoomMenu;

public class LoomScreen extends AbstractContainerScreen<LoomMenu> {
    private static final ResourceLocation BG_LOCATION;
    private static final int TOTAL_PATTERN_ROWS;
    private final ModelPart flag;
    @Nullable
    private List<Pair<BannerPattern, DyeColor>> resultBannerPatterns;
    private ItemStack bannerStack;
    private ItemStack dyeStack;
    private ItemStack patternStack;
    private boolean displayPatterns;
    private boolean displaySpecialPattern;
    private boolean hasMaxPatterns;
    private float scrollOffs;
    private boolean scrolling;
    private int startIndex;
    
    public LoomScreen(final LoomMenu bbm, final Inventory ayi, final Component lf) {
        super(bbm, ayi, lf);
        this.bannerStack = ItemStack.EMPTY;
        this.dyeStack = ItemStack.EMPTY;
        this.patternStack = ItemStack.EMPTY;
        this.startIndex = 1;
        this.flag = BannerRenderer.makeFlag();
        bbm.registerUpdateListener(this::containerChanged);
    }
    
    @Override
    public void render(final int integer1, final int integer2, final float float3) {
        super.render(integer1, integer2, float3);
        this.renderTooltip(integer1, integer2);
    }
    
    @Override
    protected void renderLabels(final int integer1, final int integer2) {
        this.font.draw(this.title.getColoredString(), 8.0f, 4.0f, 4210752);
        this.font.draw(this.inventory.getDisplayName().getColoredString(), 8.0f, (float)(this.imageHeight - 96 + 2), 4210752);
    }
    
    @Override
    protected void renderBg(final float float1, final int integer2, final int integer3) {
        this.renderBackground();
        this.minecraft.getTextureManager().bind(LoomScreen.BG_LOCATION);
        final int integer4 = this.leftPos;
        final int integer5 = this.topPos;
        this.blit(integer4, integer5, 0, 0, this.imageWidth, this.imageHeight);
        final Slot bca7 = ((LoomMenu)this.menu).getBannerSlot();
        final Slot bca8 = ((LoomMenu)this.menu).getDyeSlot();
        final Slot bca9 = ((LoomMenu)this.menu).getPatternSlot();
        final Slot bca10 = ((LoomMenu)this.menu).getResultSlot();
        if (!bca7.hasItem()) {
            this.blit(integer4 + bca7.x, integer5 + bca7.y, this.imageWidth, 0, 16, 16);
        }
        if (!bca8.hasItem()) {
            this.blit(integer4 + bca8.x, integer5 + bca8.y, this.imageWidth + 16, 0, 16, 16);
        }
        if (!bca9.hasItem()) {
            this.blit(integer4 + bca9.x, integer5 + bca9.y, this.imageWidth + 32, 0, 16, 16);
        }
        final int integer6 = (int)(41.0f * this.scrollOffs);
        this.blit(integer4 + 119, integer5 + 13 + integer6, 232 + (this.displayPatterns ? 0 : 12), 0, 12, 15);
        Lighting.setupForFlatItems();
        if (this.resultBannerPatterns != null && !this.hasMaxPatterns) {
            final MultiBufferSource.BufferSource a12 = this.minecraft.renderBuffers().bufferSource();
            final PoseStack cyl13 = new PoseStack();
            cyl13.translate(integer4 + 139, integer5 + 52, 0.0);
            cyl13.scale(24.0f, -24.0f, 1.0f);
            cyl13.translate(0.5, 0.5, 0.5);
            final float float2 = 0.6666667f;
            cyl13.scale(0.6666667f, -0.6666667f, -0.6666667f);
            this.flag.xRot = 0.0f;
            this.flag.y = -32.0f;
            BannerRenderer.renderPatterns(cyl13, a12, 15728880, OverlayTexture.NO_OVERLAY, this.flag, ModelBakery.BANNER_BASE, true, this.resultBannerPatterns);
            a12.endBatch();
        }
        else if (this.hasMaxPatterns) {
            this.blit(integer4 + bca10.x - 2, integer5 + bca10.y - 2, this.imageWidth, 17, 17, 16);
        }
        if (this.displayPatterns) {
            final int integer7 = integer4 + 60;
            final int integer8 = integer5 + 13;
            for (int integer9 = this.startIndex + 16, integer10 = this.startIndex; integer10 < integer9 && integer10 < BannerPattern.COUNT - 5; ++integer10) {
                final int integer11 = integer10 - this.startIndex;
                final int integer12 = integer7 + integer11 % 4 * 14;
                final int integer13 = integer8 + integer11 / 4 * 14;
                this.minecraft.getTextureManager().bind(LoomScreen.BG_LOCATION);
                int integer14 = this.imageHeight;
                if (integer10 == ((LoomMenu)this.menu).getSelectedBannerPatternIndex()) {
                    integer14 += 14;
                }
                else if (integer2 >= integer12 && integer3 >= integer13 && integer2 < integer12 + 14 && integer3 < integer13 + 14) {
                    integer14 += 28;
                }
                this.blit(integer12, integer13, 0, integer14, 14, 14);
                this.renderPattern(integer10, integer12, integer13);
            }
        }
        else if (this.displaySpecialPattern) {
            final int integer7 = integer4 + 60;
            final int integer8 = integer5 + 13;
            this.minecraft.getTextureManager().bind(LoomScreen.BG_LOCATION);
            this.blit(integer7, integer8, 0, this.imageHeight, 14, 14);
            final int integer9 = ((LoomMenu)this.menu).getSelectedBannerPatternIndex();
            this.renderPattern(integer9, integer7, integer8);
        }
        Lighting.setupFor3DItems();
    }
    
    private void renderPattern(final int integer1, final int integer2, final int integer3) {
        final ItemStack ben5 = new ItemStack(Items.GRAY_BANNER);
        final CompoundTag jt6 = ben5.getOrCreateTagElement("BlockEntityTag");
        final ListTag jz7 = new BannerPattern.Builder().addPattern(BannerPattern.BASE, DyeColor.GRAY).addPattern(BannerPattern.values()[integer1], DyeColor.WHITE).toListTag();
        jt6.put("Patterns", jz7);
        final PoseStack cyl8 = new PoseStack();
        cyl8.pushPose();
        cyl8.translate(integer2 + 0.5f, integer3 + 16, 0.0);
        cyl8.scale(6.0f, -6.0f, 1.0f);
        cyl8.translate(0.5, 0.5, 0.0);
        cyl8.translate(0.5, 0.5, 0.5);
        final float float9 = 0.6666667f;
        cyl8.scale(0.6666667f, -0.6666667f, -0.6666667f);
        final MultiBufferSource.BufferSource a10 = this.minecraft.renderBuffers().bufferSource();
        this.flag.xRot = 0.0f;
        this.flag.y = -32.0f;
        final List<Pair<BannerPattern, DyeColor>> list11 = BannerBlockEntity.createPatterns(DyeColor.GRAY, BannerBlockEntity.getItemPatterns(ben5));
        BannerRenderer.renderPatterns(cyl8, a10, 15728880, OverlayTexture.NO_OVERLAY, this.flag, ModelBakery.BANNER_BASE, true, list11);
        cyl8.popPose();
        a10.endBatch();
    }
    
    @Override
    public boolean mouseClicked(final double double1, final double double2, final int integer) {
        this.scrolling = false;
        if (this.displayPatterns) {
            int integer2 = this.leftPos + 60;
            int integer3 = this.topPos + 13;
            for (int integer4 = this.startIndex + 16, integer5 = this.startIndex; integer5 < integer4; ++integer5) {
                final int integer6 = integer5 - this.startIndex;
                final double double3 = double1 - (integer2 + integer6 % 4 * 14);
                final double double4 = double2 - (integer3 + integer6 / 4 * 14);
                if (double3 >= 0.0 && double4 >= 0.0 && double3 < 14.0 && double4 < 14.0 && ((LoomMenu)this.menu).clickMenuButton(this.minecraft.player, integer5)) {
                    Minecraft.getInstance().getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_LOOM_SELECT_PATTERN, 1.0f));
                    this.minecraft.gameMode.handleInventoryButtonClick(((LoomMenu)this.menu).containerId, integer5);
                    return true;
                }
            }
            integer2 = this.leftPos + 119;
            integer3 = this.topPos + 9;
            if (double1 >= integer2 && double1 < integer2 + 12 && double2 >= integer3 && double2 < integer3 + 56) {
                this.scrolling = true;
            }
        }
        return super.mouseClicked(double1, double2, integer);
    }
    
    @Override
    public boolean mouseDragged(final double double1, final double double2, final int integer, final double double4, final double double5) {
        if (this.scrolling && this.displayPatterns) {
            final int integer2 = this.topPos + 13;
            final int integer3 = integer2 + 56;
            this.scrollOffs = ((float)double2 - integer2 - 7.5f) / (integer3 - integer2 - 15.0f);
            this.scrollOffs = Mth.clamp(this.scrollOffs, 0.0f, 1.0f);
            final int integer4 = LoomScreen.TOTAL_PATTERN_ROWS - 4;
            int integer5 = (int)(this.scrollOffs * integer4 + 0.5);
            if (integer5 < 0) {
                integer5 = 0;
            }
            this.startIndex = 1 + integer5 * 4;
            return true;
        }
        return super.mouseDragged(double1, double2, integer, double4, double5);
    }
    
    @Override
    public boolean mouseScrolled(final double double1, final double double2, final double double3) {
        if (this.displayPatterns) {
            final int integer8 = LoomScreen.TOTAL_PATTERN_ROWS - 4;
            this.scrollOffs -= (float)(double3 / integer8);
            this.scrollOffs = Mth.clamp(this.scrollOffs, 0.0f, 1.0f);
            this.startIndex = 1 + (int)(this.scrollOffs * integer8 + 0.5) * 4;
        }
        return true;
    }
    
    @Override
    protected boolean hasClickedOutside(final double double1, final double double2, final int integer3, final int integer4, final int integer5) {
        return double1 < integer3 || double2 < integer4 || double1 >= integer3 + this.imageWidth || double2 >= integer4 + this.imageHeight;
    }
    
    private void containerChanged() {
        final ItemStack ben2 = ((LoomMenu)this.menu).getResultSlot().getItem();
        if (ben2.isEmpty()) {
            this.resultBannerPatterns = null;
        }
        else {
            this.resultBannerPatterns = BannerBlockEntity.createPatterns(((BannerItem)ben2.getItem()).getColor(), BannerBlockEntity.getItemPatterns(ben2));
        }
        final ItemStack ben3 = ((LoomMenu)this.menu).getBannerSlot().getItem();
        final ItemStack ben4 = ((LoomMenu)this.menu).getDyeSlot().getItem();
        final ItemStack ben5 = ((LoomMenu)this.menu).getPatternSlot().getItem();
        final CompoundTag jt6 = ben3.getOrCreateTagElement("BlockEntityTag");
        this.hasMaxPatterns = (jt6.contains("Patterns", 9) && !ben3.isEmpty() && jt6.getList("Patterns", 10).size() >= 6);
        if (this.hasMaxPatterns) {
            this.resultBannerPatterns = null;
        }
        if (!ItemStack.matches(ben3, this.bannerStack) || !ItemStack.matches(ben4, this.dyeStack) || !ItemStack.matches(ben5, this.patternStack)) {
            this.displayPatterns = (!ben3.isEmpty() && !ben4.isEmpty() && ben5.isEmpty() && !this.hasMaxPatterns);
            this.displaySpecialPattern = (!this.hasMaxPatterns && !ben5.isEmpty() && !ben3.isEmpty() && !ben4.isEmpty());
        }
        this.bannerStack = ben3.copy();
        this.dyeStack = ben4.copy();
        this.patternStack = ben5.copy();
    }
    
    static {
        BG_LOCATION = new ResourceLocation("textures/gui/container/loom.png");
        TOTAL_PATTERN_ROWS = (BannerPattern.COUNT - 5 - 1 + 4 - 1) / 4;
    }
}
