package net.minecraft.client.gui.screens;

import com.google.common.collect.Sets;
import org.apache.logging.log4j.LogManager;
import net.minecraft.CrashReportCategory;
import net.minecraft.ReportedException;
import net.minecraft.CrashReport;
import com.mojang.blaze3d.platform.InputConstants;
import net.minecraft.Util;
import com.mojang.blaze3d.vertex.BufferBuilder;
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
import java.io.File;
import java.util.Locale;
import java.net.URISyntaxException;
import net.minecraft.network.chat.ClickEvent;
import net.minecraft.nbt.Tag;
import com.google.gson.JsonSyntaxException;
import net.minecraft.ChatFormatting;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.TagParser;
import net.minecraft.network.chat.HoverEvent;
import com.mojang.math.Matrix4f;
import net.minecraft.client.renderer.MultiBufferSource;
import com.mojang.blaze3d.vertex.Tesselator;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.systems.RenderSystem;
import java.util.Arrays;
import java.util.Iterator;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.item.ItemStack;
import com.google.common.collect.Lists;
import java.net.URI;
import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.components.AbstractWidget;
import net.minecraft.client.renderer.entity.ItemRenderer;
import javax.annotation.Nullable;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.components.events.GuiEventListener;
import java.util.List;
import net.minecraft.network.chat.Component;
import java.util.Set;
import org.apache.logging.log4j.Logger;
import net.minecraft.client.gui.components.Widget;
import net.minecraft.client.gui.components.events.AbstractContainerEventHandler;

public abstract class Screen extends AbstractContainerEventHandler implements Widget {
    private static final Logger LOGGER;
    private static final Set<String> ALLOWED_PROTOCOLS;
    protected final Component title;
    protected final List<GuiEventListener> children;
    @Nullable
    protected Minecraft minecraft;
    protected ItemRenderer itemRenderer;
    public int width;
    public int height;
    protected final List<AbstractWidget> buttons;
    public boolean passEvents;
    protected Font font;
    private URI clickedLink;
    
    protected Screen(final Component lf) {
        this.children = Lists.newArrayList();
        this.buttons = Lists.newArrayList();
        this.title = lf;
    }
    
    public Component getTitle() {
        return this.title;
    }
    
    public String getNarrationMessage() {
        return this.getTitle().getString();
    }
    
    @Override
    public void render(final int integer1, final int integer2, final float float3) {
        for (int integer3 = 0; integer3 < this.buttons.size(); ++integer3) {
            this.buttons.get(integer3).render(integer1, integer2, float3);
        }
    }
    
    @Override
    public boolean keyPressed(final int integer1, final int integer2, final int integer3) {
        if (integer1 == 256 && this.shouldCloseOnEsc()) {
            this.onClose();
            return true;
        }
        if (integer1 == 258) {
            final boolean boolean5 = !hasShiftDown();
            if (!this.changeFocus(boolean5)) {
                this.changeFocus(boolean5);
            }
            return true;
        }
        return super.keyPressed(integer1, integer2, integer3);
    }
    
    public boolean shouldCloseOnEsc() {
        return true;
    }
    
    public void onClose() {
        this.minecraft.setScreen(null);
    }
    
    protected <T extends AbstractWidget> T addButton(final T dct) {
        this.buttons.add(dct);
        this.children.add(dct);
        return dct;
    }
    
    protected void renderTooltip(final ItemStack ben, final int integer2, final int integer3) {
        this.renderTooltip(this.getTooltipFromItem(ben), integer2, integer3);
    }
    
    public List<String> getTooltipFromItem(final ItemStack ben) {
        final List<Component> list3 = ben.getTooltipLines(this.minecraft.player, this.minecraft.options.advancedItemTooltips ? TooltipFlag.Default.ADVANCED : TooltipFlag.Default.NORMAL);
        final List<String> list4 = Lists.newArrayList();
        for (final Component lf6 : list3) {
            list4.add(lf6.getColoredString());
        }
        return list4;
    }
    
    public void renderTooltip(final String string, final int integer2, final int integer3) {
        this.renderTooltip(Arrays.<String>asList(string), integer2, integer3);
    }
    
    public void renderTooltip(final List<String> list, final int integer2, final int integer3) {
        if (list.isEmpty()) {
            return;
        }
        RenderSystem.disableRescaleNormal();
        RenderSystem.disableDepthTest();
        int integer4 = 0;
        for (final String string7 : list) {
            final int integer5 = this.font.width(string7);
            if (integer5 > integer4) {
                integer4 = integer5;
            }
        }
        int integer6 = integer2 + 12;
        int integer7 = integer3 - 12;
        final int integer5 = integer4;
        int integer8 = 8;
        if (list.size() > 1) {
            integer8 += 2 + (list.size() - 1) * 10;
        }
        if (integer6 + integer4 > this.width) {
            integer6 -= 28 + integer4;
        }
        if (integer7 + integer8 + 6 > this.height) {
            integer7 = this.height - integer8 - 6;
        }
        this.setBlitOffset(300);
        this.itemRenderer.blitOffset = 300.0f;
        final int integer9 = -267386864;
        this.fillGradient(integer6 - 3, integer7 - 4, integer6 + integer5 + 3, integer7 - 3, -267386864, -267386864);
        this.fillGradient(integer6 - 3, integer7 + integer8 + 3, integer6 + integer5 + 3, integer7 + integer8 + 4, -267386864, -267386864);
        this.fillGradient(integer6 - 3, integer7 - 3, integer6 + integer5 + 3, integer7 + integer8 + 3, -267386864, -267386864);
        this.fillGradient(integer6 - 4, integer7 - 3, integer6 - 3, integer7 + integer8 + 3, -267386864, -267386864);
        this.fillGradient(integer6 + integer5 + 3, integer7 - 3, integer6 + integer5 + 4, integer7 + integer8 + 3, -267386864, -267386864);
        final int integer10 = 1347420415;
        final int integer11 = 1344798847;
        this.fillGradient(integer6 - 3, integer7 - 3 + 1, integer6 - 3 + 1, integer7 + integer8 + 3 - 1, 1347420415, 1344798847);
        this.fillGradient(integer6 + integer5 + 2, integer7 - 3 + 1, integer6 + integer5 + 3, integer7 + integer8 + 3 - 1, 1347420415, 1344798847);
        this.fillGradient(integer6 - 3, integer7 - 3, integer6 + integer5 + 3, integer7 - 3 + 1, 1347420415, 1347420415);
        this.fillGradient(integer6 - 3, integer7 + integer8 + 2, integer6 + integer5 + 3, integer7 + integer8 + 3, 1344798847, 1344798847);
        final PoseStack cyl13 = new PoseStack();
        final MultiBufferSource.BufferSource a14 = MultiBufferSource.immediate(Tesselator.getInstance().getBuilder());
        cyl13.translate(0.0, 0.0, this.itemRenderer.blitOffset);
        final Matrix4f b15 = cyl13.last().pose();
        for (int integer12 = 0; integer12 < list.size(); ++integer12) {
            final String string8 = list.get(integer12);
            if (string8 != null) {
                this.font.drawInBatch(string8, (float)integer6, (float)integer7, -1, true, b15, a14, false, 0, 15728880);
            }
            if (integer12 == 0) {
                integer7 += 2;
            }
            integer7 += 10;
        }
        a14.endBatch();
        this.setBlitOffset(0);
        this.itemRenderer.blitOffset = 0.0f;
        RenderSystem.enableDepthTest();
        RenderSystem.enableRescaleNormal();
    }
    
    protected void renderComponentHoverEffect(final Component lf, final int integer2, final int integer3) {
        if (lf == null || lf.getStyle().getHoverEvent() == null) {
            return;
        }
        final HoverEvent li5 = lf.getStyle().getHoverEvent();
        if (li5.getAction() == HoverEvent.Action.SHOW_ITEM) {
            ItemStack ben6 = ItemStack.EMPTY;
            try {
                final Tag kj7 = TagParser.parseTag(li5.getValue().getString());
                if (kj7 instanceof CompoundTag) {
                    ben6 = ItemStack.of((CompoundTag)kj7);
                }
            }
            catch (CommandSyntaxException ex2) {}
            if (ben6.isEmpty()) {
                this.renderTooltip(ChatFormatting.RED + "Invalid Item!", integer2, integer3);
            }
            else {
                this.renderTooltip(ben6, integer2, integer3);
            }
        }
        else if (li5.getAction() == HoverEvent.Action.SHOW_ENTITY) {
            if (this.minecraft.options.advancedItemTooltips) {
                try {
                    final CompoundTag jt6 = TagParser.parseTag(li5.getValue().getString());
                    final List<String> list7 = Lists.newArrayList();
                    final Component lf2 = Component.Serializer.fromJson(jt6.getString("name"));
                    if (lf2 != null) {
                        list7.add(lf2.getColoredString());
                    }
                    if (jt6.contains("type", 8)) {
                        final String string9 = jt6.getString("type");
                        list7.add("Type: " + string9);
                    }
                    list7.add(jt6.getString("id"));
                    this.renderTooltip(list7, integer2, integer3);
                }
                catch (JsonSyntaxException | CommandSyntaxException ex3) {
                    final Exception ex;
                    final Exception exception6 = ex;
                    this.renderTooltip(ChatFormatting.RED + "Invalid Entity!", integer2, integer3);
                }
            }
        }
        else if (li5.getAction() == HoverEvent.Action.SHOW_TEXT) {
            this.renderTooltip(this.minecraft.font.split(li5.getValue().getColoredString(), Math.max(this.width / 2, 200)), integer2, integer3);
        }
    }
    
    protected void insertText(final String string, final boolean boolean2) {
    }
    
    public boolean handleComponentClicked(final Component lf) {
        if (lf == null) {
            return false;
        }
        final ClickEvent le3 = lf.getStyle().getClickEvent();
        if (hasShiftDown()) {
            if (lf.getStyle().getInsertion() != null) {
                this.insertText(lf.getStyle().getInsertion(), false);
            }
        }
        else if (le3 != null) {
            if (le3.getAction() == ClickEvent.Action.OPEN_URL) {
                if (!this.minecraft.options.chatLinks) {
                    return false;
                }
                try {
                    final URI uRI4 = new URI(le3.getValue());
                    final String string5 = uRI4.getScheme();
                    if (string5 == null) {
                        throw new URISyntaxException(le3.getValue(), "Missing protocol");
                    }
                    if (!Screen.ALLOWED_PROTOCOLS.contains(string5.toLowerCase(Locale.ROOT))) {
                        throw new URISyntaxException(le3.getValue(), "Unsupported protocol: " + string5.toLowerCase(Locale.ROOT));
                    }
                    if (this.minecraft.options.chatLinksPrompt) {
                        this.clickedLink = uRI4;
                        this.minecraft.setScreen(new ConfirmLinkScreen(this::confirmLink, le3.getValue(), false));
                    }
                    else {
                        this.openLink(uRI4);
                    }
                }
                catch (URISyntaxException uRISyntaxException4) {
                    Screen.LOGGER.error("Can't open url for {}", le3, uRISyntaxException4);
                }
            }
            else if (le3.getAction() == ClickEvent.Action.OPEN_FILE) {
                final URI uRI4 = new File(le3.getValue()).toURI();
                this.openLink(uRI4);
            }
            else if (le3.getAction() == ClickEvent.Action.SUGGEST_COMMAND) {
                this.insertText(le3.getValue(), true);
            }
            else if (le3.getAction() == ClickEvent.Action.RUN_COMMAND) {
                this.sendMessage(le3.getValue(), false);
            }
            else if (le3.getAction() == ClickEvent.Action.COPY_TO_CLIPBOARD) {
                this.minecraft.keyboardHandler.setClipboard(le3.getValue());
            }
            else {
                Screen.LOGGER.error("Don't know how to handle {}", le3);
            }
            return true;
        }
        return false;
    }
    
    public void sendMessage(final String string) {
        this.sendMessage(string, true);
    }
    
    public void sendMessage(final String string, final boolean boolean2) {
        if (boolean2) {
            this.minecraft.gui.getChat().addRecentChat(string);
        }
        this.minecraft.player.chat(string);
    }
    
    public void init(final Minecraft dbn, final int integer2, final int integer3) {
        this.minecraft = dbn;
        this.itemRenderer = dbn.getItemRenderer();
        this.font = dbn.font;
        this.width = integer2;
        this.height = integer3;
        this.buttons.clear();
        this.children.clear();
        this.setFocused(null);
        this.init();
    }
    
    public void setSize(final int integer1, final int integer2) {
        this.width = integer1;
        this.height = integer2;
    }
    
    @Override
    public List<? extends GuiEventListener> children() {
        return this.children;
    }
    
    protected void init() {
    }
    
    public void tick() {
    }
    
    public void removed() {
    }
    
    public void renderBackground() {
        this.renderBackground(0);
    }
    
    public void renderBackground(final int integer) {
        if (this.minecraft.level != null) {
            this.fillGradient(0, 0, this.width, this.height, -1072689136, -804253680);
        }
        else {
            this.renderDirtBackground(integer);
        }
    }
    
    public void renderDirtBackground(final int integer) {
        final Tesselator cym3 = Tesselator.getInstance();
        final BufferBuilder cyg4 = cym3.getBuilder();
        this.minecraft.getTextureManager().bind(Screen.BACKGROUND_LOCATION);
        RenderSystem.color4f(1.0f, 1.0f, 1.0f, 1.0f);
        final float float5 = 32.0f;
        cyg4.begin(7, DefaultVertexFormat.POSITION_TEX_COLOR);
        cyg4.vertex(0.0, this.height, 0.0).uv(0.0f, this.height / 32.0f + integer).color(64, 64, 64, 255).endVertex();
        cyg4.vertex(this.width, this.height, 0.0).uv(this.width / 32.0f, this.height / 32.0f + integer).color(64, 64, 64, 255).endVertex();
        cyg4.vertex(this.width, 0.0, 0.0).uv(this.width / 32.0f, (float)integer).color(64, 64, 64, 255).endVertex();
        cyg4.vertex(0.0, 0.0, 0.0).uv(0.0f, (float)integer).color(64, 64, 64, 255).endVertex();
        cym3.end();
    }
    
    public boolean isPauseScreen() {
        return true;
    }
    
    private void confirmLink(final boolean boolean1) {
        if (boolean1) {
            this.openLink(this.clickedLink);
        }
        this.clickedLink = null;
        this.minecraft.setScreen(this);
    }
    
    private void openLink(final URI uRI) {
        Util.getPlatform().openUri(uRI);
    }
    
    public static boolean hasControlDown() {
        if (Minecraft.ON_OSX) {
            return InputConstants.isKeyDown(Minecraft.getInstance().getWindow().getWindow(), 343) || InputConstants.isKeyDown(Minecraft.getInstance().getWindow().getWindow(), 347);
        }
        return InputConstants.isKeyDown(Minecraft.getInstance().getWindow().getWindow(), 341) || InputConstants.isKeyDown(Minecraft.getInstance().getWindow().getWindow(), 345);
    }
    
    public static boolean hasShiftDown() {
        return InputConstants.isKeyDown(Minecraft.getInstance().getWindow().getWindow(), 340) || InputConstants.isKeyDown(Minecraft.getInstance().getWindow().getWindow(), 344);
    }
    
    public static boolean hasAltDown() {
        return InputConstants.isKeyDown(Minecraft.getInstance().getWindow().getWindow(), 342) || InputConstants.isKeyDown(Minecraft.getInstance().getWindow().getWindow(), 346);
    }
    
    public static boolean isCut(final int integer) {
        return integer == 88 && hasControlDown() && !hasShiftDown() && !hasAltDown();
    }
    
    public static boolean isPaste(final int integer) {
        return integer == 86 && hasControlDown() && !hasShiftDown() && !hasAltDown();
    }
    
    public static boolean isCopy(final int integer) {
        return integer == 67 && hasControlDown() && !hasShiftDown() && !hasAltDown();
    }
    
    public static boolean isSelectAll(final int integer) {
        return integer == 65 && hasControlDown() && !hasShiftDown() && !hasAltDown();
    }
    
    public void resize(final Minecraft dbn, final int integer2, final int integer3) {
        this.init(dbn, integer2, integer3);
    }
    
    public static void wrapScreenError(final Runnable runnable, final String string2, final String string3) {
        try {
            runnable.run();
        }
        catch (Throwable throwable4) {
            final CrashReport h5 = CrashReport.forThrowable(throwable4, string2);
            final CrashReportCategory i6 = h5.addCategory("Affected screen");
            i6.setDetail("Screen name", () -> string3);
            throw new ReportedException(h5);
        }
    }
    
    protected boolean isValidCharacterForName(final String string, final char character, final int integer) {
        final int integer2 = string.indexOf(58);
        final int integer3 = string.indexOf(47);
        if (character == ':') {
            return (integer3 == -1 || integer <= integer3) && integer2 == -1;
        }
        if (character == '/') {
            return integer > integer2;
        }
        return character == '_' || character == '-' || (character >= 'a' && character <= 'z') || (character >= '0' && character <= '9') || character == '.';
    }
    
    @Override
    public boolean isMouseOver(final double double1, final double double2) {
        return true;
    }
    
    static {
        LOGGER = LogManager.getLogger();
        ALLOWED_PROTOCOLS = Sets.<String>newHashSet("http", "https");
    }
}
