package net.minecraft.src;

import net.lax1dude.eaglercraft.*;
import net.lax1dude.eaglercraft.adapter.Tessellator;
import net.lax1dude.eaglercraft.glemu.FixedFunctionShader;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

public class Minecraft
{
    /** A 10MiB preallocation to ensure the heap is reasonably sized. */
    public static byte[] memoryReserve = new byte[10485760];
    private ServerData currentServerData;

    /** The RenderEngine instance used by Minecraft */
    public RenderEngine renderEngine;

    /**
     * Set to 'this' in Minecraft constructor; used by some settings get methods
     */
    private static Minecraft theMinecraft;
    public PlayerControllerMP playerController;
    private boolean fullscreen;
    private boolean hasCrashed;
    private boolean isGonnaTakeDatScreenShot = false;

    public int displayWidth;
    public int displayHeight;
    private Timer timer = new Timer(20.0F);

    public WorldClient theWorld;
    public RenderGlobal renderGlobal;
    public EntityClientPlayerMP thePlayer;

    /**
     * The Entity from which the renderer determines the render viewpoint. Currently is always the parent Minecraft
     * class's 'thePlayer' instance. Modification of its location, rotation, or other settings at render time will
     * modify the camera likewise, with the caveat of triggering chunk rebuilds as it moves, making it unsuitable for
     * changing the viewpoint mid-render.
     */
    public EntityLivingBase renderViewEntity;
    public EntityLivingBase pointedEntityLiving;
    public EffectRenderer effectRenderer;
    private boolean isGamePaused;

    /** The font renderer used for displaying and measuring text. */
    public FontRenderer fontRenderer;
    public FontRenderer standardGalacticFontRenderer;

    /** The GuiScreen that's being displayed at the moment. */
    public GuiScreen currentScreen;
    public LoadingScreenRenderer loadingScreen;
    public EntityRenderer entityRenderer;

    /** Mouse left click counter */
    private int leftClickCounter;

    /** Display width */
    private int tempDisplayWidth;

    /** Display height */
    private int tempDisplayHeight;

    /** Instance of IntegratedServer. */
    private IntegratedServer theIntegratedServer;

    /** Gui achievement */
    public GuiAchievement guiAchievement;
    public GuiIngame ingameGUI;

    /** Skip render world */
    public boolean skipRenderWorld;

    /** The ray trace hit that the mouse is over. */
    public MovingObjectPosition objectMouseOver;

    /** The game settings that currently hold effect. */
    public GameSettings gameSettings;
    public SoundManager sndManager = new SoundManager();

    /** Mouse helper instance. */
    public MouseHelper mouseHelper;
    public TexturePackList texturePackList;

    private ISaveFormat saveLoader;

    /**
     * This is set to fpsCounter every debug screen update, and is shown on the debug screen.
     */
    public static int debugFPS;

    /**
     * When you place a block, it's set to 6, decremented once per tick, when it's 0, you can place another block.
     */
    private int rightClickDelayTimer;

    /**
     * Checked in Minecraft's while(running) loop, if true it's set to false and the textures refreshed.
     */
    private boolean refreshTexturePacksScheduled;

    /**
     * Does the actual gameplay have focus. If so then mouse and keys will effect the player instead of menus.
     */
    public boolean inGameHasFocus;
    long systemTime = getSystemTime();

    /** Join player counter */
    private int joinPlayerCounter;
    private INetworkManager myNetworkManager;
    private boolean integratedServerIsRunning;

    private long field_83002_am = -1L;
    private List defaultResourcePacks = new ArrayList<>();

    /**
     * Set to true to keep the game loop running. Set to false by shutdown() to allow the game loop to exit cleanly.
     */
    volatile boolean running = true;

    public int chunkUpdates = 0;
    public int chunkGeometryUpdates = 0;
    public static int debugChunkUpdates = 0;
    public static int debugChunkGeometryUpdates = 0;

    /** String that shows the debug information */
    public String debug = "";

    /** Approximate time (in ms) of last update to debug string */
    long debugUpdateTime = getSystemTime();

    /** holds the current fps */
    int fpsCounter;
    long prevFrameTime = -1L;

    long secondTimer = 0l;

    private HashSet<String> shownPlayerMessages = new HashSet();

    /** Profiler currently displayed in the debug screen pie chart */
    private String debugProfilerName = "root";

    private int messageOnLoginCounter = 0;

    public boolean lanState = false;
    public boolean yeeState = false;
    public boolean checkGLErrors = false;

    public Minecraft()
    {
        this.tempDisplayHeight = 480;
		this.fullscreen = false;
		Packet3Chat.maxChatLength = 32767;
		this.displayWidth = 854;
		this.displayHeight = 480;
		this.fullscreen = false;
		theMinecraft = this;
    }

    /**
     * Starts the game: initializes the canvas, the title, the settings, etcetera.
     */
    public void startGame() {
        OpenGlHelper.initializeTextures();
        TextureManager.init();
        this.gameSettings = new GameSettings(this);
        this.texturePackList = new TexturePackList(this);
        this.renderEngine = new RenderEngine(this.texturePackList, this.gameSettings);

        this.loadScreen();

        ChatAllowedCharacters.getAllowedCharacters();
        this.fontRenderer = new FontRenderer(this.gameSettings, "/font/default.png", this.renderEngine, false);
        this.standardGalacticFontRenderer = new FontRenderer(this.gameSettings, "/font/alternate.png", this.renderEngine, false);

        if (this.gameSettings.language != null) {
            StringTranslate.getInstance().setLanguage(this.gameSettings.language, false);
            //this.fontRenderer.setUnicodeFlag(StringTranslate.getInstance().isUnicode());
            //this.fontRenderer.setBidiFlag(StringTranslate.isBidirectional(this.gameSettings.language));
        }

        this.loadScreen();

        ColorizerGrass.setGrassBiomeColorizer(this.renderEngine.getTextureContents("/misc/grasscolor.png"));
        ColorizerFoliage.setFoliageBiomeColorizer(this.renderEngine.getTextureContents("/misc/foliagecolor.png"));
        this.entityRenderer = new EntityRenderer(this);
        AchievementMap.init();
        StatList.nopInit();
        RenderManager.instance = new RenderManager();
        RenderManager.instance.itemRenderer = new ItemRenderer(this);
        AchievementList.openInventory.setStatStringFormatter(new StatStringFormatKeyInv(this));
        this.mouseHelper = new MouseHelper();
        this.checkGLError("Pre startup");
        EaglerAdapter.glEnable(EaglerAdapter.GL_TEXTURE_2D);
        EaglerAdapter.glShadeModel(EaglerAdapter.GL_SMOOTH);
        EaglerAdapter.glClearDepth(1.0F);
        EaglerAdapter.glEnable(EaglerAdapter.GL_DEPTH_TEST);
        EaglerAdapter.glDepthFunc(EaglerAdapter.GL_LEQUAL);
        EaglerAdapter.glEnable(EaglerAdapter.GL_ALPHA_TEST);
        EaglerAdapter.glAlphaFunc(EaglerAdapter.GL_GREATER, 0.1F);
        EaglerAdapter.glCullFace(EaglerAdapter.GL_BACK);
        EaglerAdapter.glMatrixMode(EaglerAdapter.GL_PROJECTION);
        EaglerAdapter.glLoadIdentity();
        EaglerAdapter.glMatrixMode(EaglerAdapter.GL_MODELVIEW);
        this.checkGLError("Startup");
        this.sndManager.loadSoundSettings(this.gameSettings);
        this.renderGlobal = new RenderGlobal(this, this.renderEngine);
        this.renderEngine.refreshTextureMaps();
        EaglerAdapter.glViewport(0, 0, this.displayWidth, this.displayHeight);
        this.effectRenderer = new EffectRenderer(this.theWorld, this.renderEngine);

        this.checkGLError("Post startup");
        this.guiAchievement = new GuiAchievement(this);
        this.ingameGUI = new GuiIngame(this);

        ScaledResolution var2 = new ScaledResolution(this.gameSettings, this.displayWidth, this.displayHeight);
        int var3 = var2.getScaledWidth();
        int var4 = var2.getScaledHeight();

        EaglerAdapter.anisotropicPatch(EaglerAdapter.glNeedsAnisotropicFix());

        EaglerProfile.loadFromStorage();

        this.sndManager.playTheTitleMusic();
        showIntroAnimation();

        String s = EaglerAdapter.getServerToJoinOnLaunch();
        GuiScreen scr;

        if(s != null) {
            scr = new GuiScreenEditProfile(new GuiConnecting(new GuiMainMenu(), this, new ServerData("Eaglercraft Server", s, false)));
        }else {
            scr = new GuiScreenEditProfile(new GuiMainMenu());
        }

        if(!gameSettings.enableVsync && !gameSettings.hideVsyncWarning) {
            scr = new GuiScreenVSyncWarning(scr);
        }

        displayGuiScreen(scr);

        this.loadingScreen = new LoadingScreenRenderer(this);

        byte[] b = EaglerAdapter.loadResourceBytes("adderall");
        yeeState = b != null && (new String(b, StandardCharsets.UTF_8)).hashCode() == 508925104;
    }

    private void showIntroAnimation() {
        ScaledResolution var1 = new ScaledResolution(this.gameSettings, this.displayWidth, this.displayHeight);
        EaglerAdapter.glClearColor(1.0F, 1.0F, 1.0F, 1.0F);
        EaglerAdapter.glDisable(EaglerAdapter.GL_ALPHA_TEST);
        EaglerAdapter.glMatrixMode(EaglerAdapter.GL_MODELVIEW);
        EaglerAdapter.glLoadIdentity();
        EaglerAdapter.glTranslatef(0.0F, 0.0F, -2000.0F);
        EaglerAdapter.glViewport(0, 0, this.displayWidth, this.displayHeight);
        EaglerAdapter.glDisable(EaglerAdapter.GL_LIGHTING);
        EaglerAdapter.glEnable(EaglerAdapter.GL_TEXTURE_2D);
        EaglerAdapter.glEnable(EaglerAdapter.GL_BLEND);
        EaglerAdapter.glBlendFunc(EaglerAdapter.GL_SRC_ALPHA, EaglerAdapter.GL_ONE_MINUS_SRC_ALPHA);
        EaglerAdapter.glDisable(EaglerAdapter.GL_FOG);
        EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);

        long t1 = EaglerAdapter.steadyTimeMillis();
        for(int i = 0; i < 20; i++) {
            this.displayWidth = EaglerAdapter.getCanvasWidth();
            this.displayHeight = EaglerAdapter.getCanvasHeight();
            EaglerAdapter.glViewport(0, 0, this.displayWidth, this.displayHeight);
            var1 = new ScaledResolution(this.gameSettings, this.displayWidth, this.displayHeight);
            EaglerAdapter.glMatrixMode(EaglerAdapter.GL_PROJECTION);
            EaglerAdapter.glLoadIdentity();
            EaglerAdapter.glOrtho(0.0F, var1.getScaledWidth(), var1.getScaledHeight(), 0.0F, 1000.0F, 3000.0F);
            EaglerAdapter.glMatrixMode(EaglerAdapter.GL_MODELVIEW);

            float f = ((float)(EaglerAdapter.steadyTimeMillis() - t1) / 333f);

            EaglerAdapter.glClear(EaglerAdapter.GL_COLOR_BUFFER_BIT | EaglerAdapter.GL_DEPTH_BUFFER_BIT);
            EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, MathHelper.clamp_float(1.0f - f, 0.0F, 1.0F));
            this.renderEngine.bindTexture("%clamp%/title/eagtek.png");
            EaglerAdapter.glPushMatrix();
            float f1 = 1.0f + 0.025f * f * f;
            EaglerAdapter.glTranslatef((var1.getScaledWidth() - 256) / 2, (var1.getScaledHeight() - 256) / 2, 0.0f);
            EaglerAdapter.glTranslatef(-128.0f * (f1 - 1.0f), -128.0f * (f1 - 1.0f) , 0.0f);
            EaglerAdapter.glScalef(f1, f1, 1.0f);
            this.scaledTessellator(0, 0, 0, 0, 256, 256);
            EaglerAdapter.glPopMatrix();

            EaglerAdapter.glFlush();
            updateDisplay();

            long t = t1 + 17 + 17*i - EaglerAdapter.steadyTimeMillis();
            if(t > 0) {
                EaglerAdapter.sleep((int)t);
            }
        }

        t1 = EaglerAdapter.steadyTimeMillis();
        for(int i = 0; i < 20; i++) {
            this.displayWidth = EaglerAdapter.getCanvasWidth();
            this.displayHeight = EaglerAdapter.getCanvasHeight();
            EaglerAdapter.glViewport(0, 0, this.displayWidth, this.displayHeight);
            var1 = new ScaledResolution(this.gameSettings, this.displayWidth, this.displayHeight);
            EaglerAdapter.glMatrixMode(EaglerAdapter.GL_PROJECTION);
            EaglerAdapter.glLoadIdentity();
            EaglerAdapter.glOrtho(0.0F, var1.getScaledWidth(), var1.getScaledHeight(), 0.0F, 1000.0F, 3000.0F);
            EaglerAdapter.glMatrixMode(EaglerAdapter.GL_MODELVIEW);

            float f = ((float)(EaglerAdapter.steadyTimeMillis() - t1) / 333f);

            EaglerAdapter.glClear(EaglerAdapter.GL_COLOR_BUFFER_BIT | EaglerAdapter.GL_DEPTH_BUFFER_BIT);
            EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, MathHelper.clamp_float(f, 0.0F, 1.0F));
            this.renderEngine.bindTexture("%blur%/title/mojang.png");
            EaglerAdapter.glPushMatrix();
            float f1 = 0.875f + 0.025f * (float)Math.sqrt(f);
            EaglerAdapter.glTranslatef((var1.getScaledWidth() - 256) / 2, (var1.getScaledHeight() - 256) / 2, 0.0f);
            EaglerAdapter.glTranslatef(-128.0f * (f1 - 1.0f), -128.0f * (f1 - 1.0f) , 0.0f);
            EaglerAdapter.glScalef(f1, f1, 1.0f);
            this.scaledTessellator(0, 0, 0, 0, 256, 256);
            EaglerAdapter.glPopMatrix();

            EaglerAdapter.glFlush();
            updateDisplay();

            long t = t1 + 17 + 17*i - EaglerAdapter.steadyTimeMillis();
            if(t > 0) {
                EaglerAdapter.sleep((int)t);
            }
        }

        EaglerAdapter.sleep(1600);

        t1 = EaglerAdapter.steadyTimeMillis();
        for(int i = 0; i < 21; i++) {
            this.displayWidth = EaglerAdapter.getCanvasWidth();
            this.displayHeight = EaglerAdapter.getCanvasHeight();
            EaglerAdapter.glViewport(0, 0, this.displayWidth, this.displayHeight);
            var1 = new ScaledResolution(this.gameSettings, this.displayWidth, this.displayHeight);

            float f = ((float)(EaglerAdapter.steadyTimeMillis() - t1) / 340f);

            EaglerAdapter.glClear(EaglerAdapter.GL_COLOR_BUFFER_BIT | EaglerAdapter.GL_DEPTH_BUFFER_BIT);
            EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, MathHelper.clamp_float((1.0f - f), 0.0F, 1.0F));
            this.renderEngine.bindTexture("%blur%/title/mojang.png");
            EaglerAdapter.glPushMatrix();
            float f1 = 0.9f + 0.025f * f * f;
            EaglerAdapter.glTranslatef((var1.getScaledWidth() - 256) / 2, (var1.getScaledHeight() - 256) / 2, 0.0f);
            EaglerAdapter.glTranslatef(-128.0f * (f1 - 1.0f), -128.0f * (f1 - 1.0f) , 0.0f);
            EaglerAdapter.glScalef(f1, f1, 1.0f);
            this.scaledTessellator(0, 0, 0, 0, 256, 256);
            EaglerAdapter.glPopMatrix();

            EaglerAdapter.glFlush();
            updateDisplay();

            long t = t1 + 17 + 17*i - EaglerAdapter.steadyTimeMillis();
            if(t > 0) {
                EaglerAdapter.sleep((int)t);
            }
        }

        EaglerAdapter.glClear(EaglerAdapter.GL_COLOR_BUFFER_BIT | EaglerAdapter.GL_DEPTH_BUFFER_BIT);
        EaglerAdapter.glFlush();
        updateDisplay();

        EaglerAdapter.sleep(100);

        EaglerAdapter.glDisable(EaglerAdapter.GL_BLEND);
        EaglerAdapter.glEnable(EaglerAdapter.GL_ALPHA_TEST);
        EaglerAdapter.glAlphaFunc(EaglerAdapter.GL_GREATER, 0.1F);

        while(EaglerAdapter.keysNext());
        while(EaglerAdapter.mouseNext());
    }

    /**
     * Displays a new screen.
     */
    private void loadScreen() {
        this.displayWidth = EaglerAdapter.getCanvasWidth();
        this.displayHeight = EaglerAdapter.getCanvasHeight();
        ScaledResolution var1 = new ScaledResolution(this.gameSettings, this.displayWidth, this.displayHeight);
        EaglerAdapter.glColorMask(true, true, true, true);
        EaglerAdapter.glClearColor(1.0F, 1.0F, 1.0F, 1.0F);
        EaglerAdapter.glDisable(EaglerAdapter.GL_ALPHA_TEST);
        EaglerAdapter.glMatrixMode(EaglerAdapter.GL_PROJECTION);
        EaglerAdapter.glLoadIdentity();
        EaglerAdapter.glOrtho(0.0F, var1.getScaledWidth(), var1.getScaledHeight(), 0.0F, 1000.0F, 3000.0F);
        EaglerAdapter.glMatrixMode(EaglerAdapter.GL_MODELVIEW);
        EaglerAdapter.glLoadIdentity();
        EaglerAdapter.glTranslatef(0.0F, 0.0F, -2000.0F);
        EaglerAdapter.glViewport(0, 0, this.displayWidth, this.displayHeight);
        EaglerAdapter.glClear(EaglerAdapter.GL_COLOR_BUFFER_BIT | EaglerAdapter.GL_DEPTH_BUFFER_BIT);
        EaglerAdapter.glDisable(EaglerAdapter.GL_LIGHTING);
        EaglerAdapter.glEnable(EaglerAdapter.GL_TEXTURE_2D);
        EaglerAdapter.glDisable(EaglerAdapter.GL_FOG);
        EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
        this.renderEngine.bindTexture("%clamp%/title/eagtek.png");
        short var3 = 256;
        short var4 = 256;
        this.scaledTessellator((var1.getScaledWidth() - var3) / 2, (var1.getScaledHeight() - var4) / 2, 0, 0, var3, var4);
        EaglerAdapter.glDisable(EaglerAdapter.GL_LIGHTING);
        EaglerAdapter.glDisable(EaglerAdapter.GL_FOG);
        EaglerAdapter.glEnable(EaglerAdapter.GL_ALPHA_TEST);
        EaglerAdapter.glAlphaFunc(EaglerAdapter.GL_GREATER, 0.1F);
        EaglerAdapter.glFlush();
        updateDisplay();
        EaglerAdapter.optimize();
    }

    private void updateDisplayMode()
    {
        this.updateDisplay();
    }

    /**
     * Loads Tessellator with a scaled resolution
     */
    public void scaledTessellator(int par1, int par2, int par3, int par4, int par5, int par6)
    {
        float var7 = 0.00390625F;
        float var8 = 0.00390625F;
        Tessellator var9 = Tessellator.instance;
        var9.startDrawingQuads();
        var9.addVertexWithUV((double)(par1 + 0), (double)(par2 + par6), 0.0D, (double)((float)(par3 + 0) * var7), (double)((float)(par4 + par6) * var8));
        var9.addVertexWithUV((double)(par1 + par5), (double)(par2 + par6), 0.0D, (double)((float)(par3 + par5) * var7), (double)((float)(par4 + par6) * var8));
        var9.addVertexWithUV((double)(par1 + par5), (double)(par2 + 0), 0.0D, (double)((float)(par3 + par5) * var7), (double)((float)(par4 + 0) * var8));
        var9.addVertexWithUV((double)(par1 + 0), (double)(par2 + 0), 0.0D, (double)((float)(par3 + 0) * var7), (double)((float)(par4 + 0) * var8));
        var9.draw();
    }

    /**
     * Returns the save loader that is currently being used
     */
    public ISaveFormat getSaveLoader()
    {
        return this.saveLoader;
    }

    /**
     * Sets the argument GuiScreen as the main (topmost visible) screen.
     */
    public void displayGuiScreen(GuiScreen par1GuiScreen)
    {
        if (this.currentScreen != null) {
            this.currentScreen.onGuiClosed();
        }

        if (par1GuiScreen == null && this.theWorld == null) {
            par1GuiScreen = new GuiMainMenu();
        } else if (par1GuiScreen == null && this.thePlayer.getHealth() <= 0) {
            par1GuiScreen = new GuiGameOver();
        }

        if (par1GuiScreen instanceof GuiMainMenu) {
            this.gameSettings.showDebugInfo = false;
            this.ingameGUI.getChatGUI().clearChatMessages();
        }

        this.currentScreen = (GuiScreen) par1GuiScreen;

        if (par1GuiScreen != null) {
            this.setIngameNotInFocus();
            ScaledResolution var2 = new ScaledResolution(this.gameSettings, this.displayWidth, this.displayHeight);
            int var3 = var2.getScaledWidth();
            int var4 = var2.getScaledHeight();
            ((GuiScreen) par1GuiScreen).setWorldAndResolution(this, var3, var4);
            this.skipRenderWorld = false;
        } else {
            if(!this.inGameHasFocus) this.setIngameFocus();
        }
    }

    /**
     * Checks for an OpenGL error. If there is one, prints the error ID and error string.
     */
    public void checkGLError(String par1Str) {
        if(!checkGLErrors) return;
        int var2;


        while ((var2 = EaglerAdapter.glGetError()) != 0) {
            String var3 = EaglerAdapter.gluErrorString(var2);
            System.err.println("########## GL ERROR ##########");
            System.err.println("@ " + par1Str);
            System.err.println(var2 + ": " + var3);
        }
    }

    /**
     * Shuts down the minecraft applet by stopping the resource downloads, and clearing up GL stuff; called when the
     * application (or web page) is exited.
     */
    public void shutdownMinecraftApplet() {
        try {

            System.err.println("Stopping!");

            try {
                this.loadWorld((WorldClient) null);
            } catch (Throwable var8) {
                ;
            }

            try {
                GLAllocation.deleteTexturesAndDisplayLists();
            } catch (Throwable var7) {
                ;
            }

            this.sndManager.closeMinecraft();
        } finally {
            EaglerAdapter.destroyContext();

            if (!this.hasCrashed) {
                EaglerAdapter.exit();
            }
        }

        System.gc();
    }

    public void run() {
        this.running = true;
        this.startGame();
        while (this.running) {
            this.runGameLoop();
        }
        EaglerAdapter.destroyContext();
        EaglerAdapter.exit();
    }

    /**
     * Called repeatedly from run()
     */
    private void runGameLoop() {
        if (this.refreshTexturePacksScheduled) {
            this.refreshTexturePacksScheduled = false;
            this.renderEngine.refreshTextures();
        }

        AxisAlignedBB.getAABBPool().cleanPool();

        if (this.theWorld != null) {
            this.theWorld.getWorldVec3Pool().clear();
        }

        if (EaglerAdapter.shouldShutdown()) {
            this.shutdown();
        }

        if (this.isGamePaused && this.theWorld != null) {
            float var1 = this.timer.renderPartialTicks;
            this.timer.updateTimer();
            this.timer.renderPartialTicks = var1;
        } else {
            this.timer.updateTimer();
        }

        long var6 = System.nanoTime();

        for (int var3 = 0; var3 < this.timer.elapsedTicks; ++var3) {
            this.runTick();
        }

        IntegratedServer.processICP();

        long var7 = System.nanoTime() - var6;
        this.checkGLError("Pre render");
        RenderBlocks.fancyGrass = this.gameSettings.fancyGraphics;
        this.sndManager.setListener(this.thePlayer, this.timer.renderPartialTicks);

        if (!this.isGamePaused) {
            this.sndManager.func_92071_g();
        }

        EaglerAdapter.glEnable(EaglerAdapter.GL_TEXTURE_2D);

        if (!EaglerAdapter.isKeyDown(65)) {
            updateDisplay();
        }

        if (this.thePlayer != null && this.thePlayer.isEntityInsideOpaqueBlock()) {
            this.gameSettings.thirdPersonView = 0;
        }

        EaglerAdapter.glClearStack();

        if (!this.skipRenderWorld) {
            this.entityRenderer.updateCameraAndRender(this.timer.renderPartialTicks);
        }

        EaglerAdapter.glFlush();

        //if (!EaglerAdapter.isFocused() && this.fullscreen) {
        //	this.toggleFullscreen();
        //}

        this.prevFrameTime = System.nanoTime();

        this.guiAchievement.updateAchievementWindow();

        if (!this.fullscreen && (EaglerAdapter.getCanvasWidth() != this.displayWidth || EaglerAdapter.getCanvasHeight() != this.displayHeight)) {
            this.displayWidth = EaglerAdapter.getCanvasWidth();
            this.displayHeight = EaglerAdapter.getCanvasHeight();

            if (this.displayWidth <= 0) {
                this.displayWidth = 1;
            }

            if (this.displayHeight <= 0) {
                this.displayHeight = 1;
            }

            this.resize(this.displayWidth, this.displayHeight);
        }

        this.checkGLError("Post render");
        EaglerAdapter.optimize();
        ++this.fpsCounter;
        //boolean var5 = this.isGamePaused;
        //this.isGamePaused = false;

        if(EaglerAdapter.steadyTimeMillis() - secondTimer > 1000l) {
            debugFPS = fpsCounter;
            fpsCounter = 0;
            debugChunkUpdates = chunkUpdates;
            chunkUpdates = 0;
            debugChunkGeometryUpdates = chunkGeometryUpdates;
            chunkGeometryUpdates = 0;
            secondTimer = EaglerAdapter.steadyTimeMillis();
        }

        if(isGonnaTakeDatScreenShot) {
            isGonnaTakeDatScreenShot = false;
            EaglerAdapter.saveScreenshot();
        }

        EaglerAdapter.doJavascriptCoroutines();
    }

    private int getLimitFramerate()
    {
        return this.currentScreen != null && this.currentScreen instanceof GuiMainMenu ? 2 : this.gameSettings.limitFramerate;
    }

    /**
     * Called when the window is closing. Sets 'running' to false which allows the game loop to exit cleanly.
     */
    public void shutdown()
    {
        this.running = false;
    }

    /**
     * Will set the focus to ingame if the Minecraft window is the active with focus. Also clears any GUI screen
     * currently displayed
     */
    public void setIngameFocus()
    {
        this.inGameHasFocus = true;
        this.mouseHelper.grabMouseCursor();
        this.displayGuiScreen((GuiScreen) null);
        this.leftClickCounter = 10000;
    }

    /**
     * Resets the player keystate, disables the ingame focus, and ungrabs the mouse cursor.
     */
    public void setIngameNotInFocus()
    {
        //if (this.inGameHasFocus)
        //{
            KeyBinding.unPressAllKeys();
            this.inGameHasFocus = false;
            this.mouseHelper.ungrabMouseCursor();
        //}
    }

    /**
     * Displays the ingame menu
     */
    public void displayInGameMenu() {
        if (this.currentScreen == null) {
            this.displayGuiScreen(new GuiIngameMenu());
            if(IntegratedServer.isWorldRunning() && !this.isSingleplayer()) {
                IntegratedServer.autoSave();
            }
        }
    }

    private void sendClickBlockToController(int par1, boolean par2) {
        if (!par2) {
            this.leftClickCounter = 0;
        }

        if (par1 != 0 || this.leftClickCounter <= 0) {
            if (par2 && this.objectMouseOver != null && this.objectMouseOver.typeOfHit == EnumMovingObjectType.TILE && par1 == 0) {
                int var3 = this.objectMouseOver.blockX;
                int var4 = this.objectMouseOver.blockY;
                int var5 = this.objectMouseOver.blockZ;
                this.playerController.onPlayerDamageBlock(var3, var4, var5, this.objectMouseOver.sideHit);

                if (this.thePlayer.isCurrentToolAdventureModeExempt(var3, var4, var5)) {
                    this.effectRenderer.addBlockHitEffects(var3, var4, var5, this.objectMouseOver.sideHit);
                    this.thePlayer.swingItem();
                }
            } else {
                this.playerController.resetBlockRemoving();
            }
        }
    }

    /**
     * Called whenever the mouse is clicked. Button clicked is 0 for left clicking and 1 for right clicking. Args:
     * buttonClicked
     */
    private void clickMouse(int par1) {
        if (par1 != 0 || this.leftClickCounter <= 0) {
            if (par1 == 0) {
                this.thePlayer.swingItem();
            }

            if (par1 == 1) {
                this.rightClickDelayTimer = 4;
            }

            boolean var2 = true;
            ItemStack var3 = this.thePlayer.inventory.getCurrentItem();

            if (this.objectMouseOver == null) {
                if (par1 == 0 && this.playerController.isNotCreative()) {
                    this.leftClickCounter = 10;
                }
            } else if (this.objectMouseOver.typeOfHit == EnumMovingObjectType.ENTITY) {
                if (par1 == 0) {
                    this.playerController.attackEntity(this.thePlayer, this.objectMouseOver.entityHit);
                }

                if (par1 == 1 && this.playerController.func_78768_b(this.thePlayer, this.objectMouseOver.entityHit)) {
                    var2 = false;
                }
            } else if (this.objectMouseOver.typeOfHit == EnumMovingObjectType.TILE) {
                int var4 = this.objectMouseOver.blockX;
                int var5 = this.objectMouseOver.blockY;
                int var6 = this.objectMouseOver.blockZ;
                int var7 = this.objectMouseOver.sideHit;

                if (par1 == 0) {
                    this.playerController.clickBlock(var4, var5, var6, this.objectMouseOver.sideHit);
                } else {
                    int var8 = var3 != null ? var3.stackSize : 0;

                    if (this.playerController.onPlayerRightClick(this.thePlayer, this.theWorld, var3, var4, var5, var6, var7, this.objectMouseOver.hitVec)) {
                        var2 = false;
                        this.thePlayer.swingItem();
                    }

                    if (var3 == null) {
                        return;
                    }

                    if (var3.stackSize == 0) {
                        this.thePlayer.inventory.mainInventory[this.thePlayer.inventory.currentItem] = null;
                    } else if (var3.stackSize != var8 || this.playerController.isInCreativeMode()) {
                        this.entityRenderer.itemRenderer.resetEquippedProgress();
                    }
                }
            }

            if (var2 && par1 == 1) {
                ItemStack var9 = this.thePlayer.inventory.getCurrentItem();

                if (var9 != null && this.playerController.sendUseItem(this.thePlayer, this.theWorld, var9)) {
                    this.entityRenderer.itemRenderer.resetEquippedProgress2();
                }
            }
        }
    }

    /**
     * Called to resize the current screen.
     */
    private void resize(int par1, int par2)
    {
        this.displayWidth = par1 <= 0 ? 1 : par1;
        this.displayHeight = par2 <= 0 ? 1 : par2;

        if (this.currentScreen != null)
        {
            ScaledResolution var3 = new ScaledResolution(this.gameSettings, par1, par2);
            int var4 = var3.getScaledWidth();
            int var5 = var3.getScaledHeight();
            this.currentScreen.setWorldAndResolution(this, var4, var5);
        }
    }

    public void updateDisplay() {
        if(gameSettings.enableVsync) {
            EaglerAdapter.updateDisplay(0, true);
        }else {
            if(EnumBrowser.getBrowser() == EnumBrowser.DESKTOP){
                int i = this.func_90020_K();
                EaglerAdapter.updateDisplay(i > 0 ? EntityRenderer.performanceToFps(i) : 0, false);
            }
        }
    }

    private int func_90020_K() {
        return this.currentScreen != null && this.currentScreen instanceof GuiMainMenu ? 2 : this.gameSettings.limitFramerate;
    }

    private void forceReload() {
        System.err.println("FORCING RELOAD!");

        if (this.sndManager != null) {
            this.sndManager.stopAllSounds();
        }

        //this.sndManager = new SoundManager(); // FIX THIS
        this.sndManager.loadSoundSettings(this.gameSettings);
    }

    public boolean isSingleplayerOrLAN() {
        return IntegratedServer.isWorldRunning();
    }

    public void displayEaglercraftText(String s) {
        if(this.thePlayer != null && shownPlayerMessages.add(s)) {
            this.thePlayer.sendChatToPlayer(s);
        }
    }

    private boolean wasPaused = false;
    /**
     * Runs the current tick.
     */
    public void runTick()
    {
        if (this.rightClickDelayTimer > 0) {
            --this.rightClickDelayTimer;
        }

        this.isGamePaused = this.isSingleplayer() && this.theWorld != null && this.thePlayer != null && this.currentScreen != null
                && this.currentScreen.doesGuiPauseGame() && !IntegratedServerLAN.isHostingLAN();

        if(wasPaused != isGamePaused) {
            IntegratedServer.setPaused(this.isGamePaused);
            wasPaused = isGamePaused;
        }

        if(lanState && !IntegratedServerLAN.isLANOpen()) {
            lanState = false;
            if(thePlayer != null) {
                thePlayer.sendChatToPlayer(EnumChatFormatting.RED + StatCollector.translateToLocal("lanServer.relayDisconnected"));
            }
        }

        if (!this.isGamePaused) {
            this.ingameGUI.updateTick();
        }

        this.entityRenderer.getMouseOver(1.0F);

        if (!this.isGamePaused && this.theWorld != null) {
            this.playerController.updateController();
        }

        if (!this.isGamePaused) {
            this.renderEngine.updateDynamicTextures();
        }

        DefaultSkinRenderer.deleteOldSkins();

        if (this.currentScreen == null && this.thePlayer != null) {
            if (this.thePlayer.getHealth() <= 0) {
                this.displayGuiScreen((GuiScreen) null);
            } else if (this.thePlayer.isPlayerSleeping() && this.theWorld != null) {
                this.displayGuiScreen(new GuiSleepMP());
            }
        } else if (this.currentScreen != null && this.currentScreen instanceof GuiSleepMP && !this.thePlayer.isPlayerSleeping()) {
            this.displayGuiScreen((GuiScreen) null);
        }

        if (this.currentScreen != null) {
            this.leftClickCounter = 10000;
        }

        if (this.currentScreen != null) {
            this.currentScreen.handleInput();

            if (this.currentScreen != null) {
                //this.currentScreen.guiParticles.update(); // FIX THIS
                this.currentScreen.updateScreen();
            }
        }

        GuiMultiplayer.tickRefreshCooldown();

        if (this.currentScreen == null || this.currentScreen.allowUserInput) {

            while (EaglerAdapter.mouseNext()) {
                KeyBinding.setKeyBindState(EaglerAdapter.mouseGetEventButton() - 100, EaglerAdapter.mouseGetEventButtonState());

                if (EaglerAdapter.mouseGetEventButtonState()) {
                    KeyBinding.onTick(EaglerAdapter.mouseGetEventButton() - 100);
                }

                long var1 = getSystemTime() - this.systemTime;

                if (var1 <= 200L) {
                    int var10 = EaglerAdapter.mouseGetEventDWheel();

                    if (var10 != 0) {
                        this.thePlayer.inventory.changeCurrentItem(var10);

                        if (this.gameSettings.noclip) {
                            if (var10 > 0) {
                                var10 = 1;
                            }

                            if (var10 < 0) {
                                var10 = -1;
                            }

                            this.gameSettings.noclipRate += (float) var10 * 0.25F;
                        }
                    }

                    if (this.currentScreen == null) {
                        if ((!this.inGameHasFocus || !EaglerAdapter.isPointerLocked()) && EaglerAdapter.mouseGetEventButtonState()) {
                            this.setIngameFocus();
                        }
                    } else if (this.currentScreen != null) {
                        this.currentScreen.handleMouseInput();
                    }
                }
            }

            if (this.leftClickCounter > 0) {
                --this.leftClickCounter;
            }

            boolean var8;

            while (EaglerAdapter.keysNext()) {
                KeyBinding.setKeyBindState(EaglerAdapter.getEventKey(), EaglerAdapter.getEventKeyState());

                if (EaglerAdapter.getEventKeyState()) {
                    KeyBinding.onTick(EaglerAdapter.getEventKey());
                }

                boolean F3down = (this.gameSettings.keyBindFunction.pressed && EaglerAdapter.isKeyDown(4));

                if (this.field_83002_am > 0L) {
                    if (getSystemTime() - this.field_83002_am >= 6000L) {
                        throw new RuntimeException("manual crash");
                    }

                    if (!EaglerAdapter.isKeyDown(46) || !F3down) {
                        this.field_83002_am = -1L;
                    }
                } else if (F3down && EaglerAdapter.isKeyDown(46)) {
                    this.field_83002_am = getSystemTime();
                }

                if (EaglerAdapter.getEventKeyState()) {
                    isGonnaTakeDatScreenShot |= (this.gameSettings.keyBindFunction.pressed && EaglerAdapter.getEventKey() == 3);
                    if (EaglerAdapter.getEventKey() == 87) {
                        //this.toggleFullscreen();
                    } else {
                        if (this.currentScreen != null) {
                            this.currentScreen.handleKeyboardInput();
                        } else {
                            if (EaglerAdapter.getEventKey() == 1) {
                                this.displayInGameMenu();
                            }

                            if (F3down && EaglerAdapter.getEventKey() == 31) {
                                this.forceReload();
                            }

                            if (F3down && EaglerAdapter.getEventKey() == 20) {
                                this.renderEngine.refreshTextures();
                                this.renderGlobal.loadRenderers();
                                FixedFunctionShader.refreshCoreGL();
                            }

                            if (F3down && EaglerAdapter.getEventKey() == 33) {
                                var8 = EaglerAdapter.isKeyDown(42) | EaglerAdapter.isKeyDown(54);
                                this.gameSettings.setOptionValue(EnumOptions.RENDER_DISTANCE, var8 ? -1 : 1);
                            }

                            if (F3down && EaglerAdapter.getEventKey() == 30) {
                                this.renderGlobal.loadRenderers();
                            }

                            if (F3down && EaglerAdapter.getEventKey() == 35) {
                                this.gameSettings.advancedItemTooltips = !this.gameSettings.advancedItemTooltips;
                                this.gameSettings.saveOptions();
                            }

                            if (F3down && EaglerAdapter.getEventKey() == 48) {
                                RenderManager.field_85095_o = !RenderManager.field_85095_o;
                            }

                            if (F3down && EaglerAdapter.getEventKey() == 25) {
                                this.gameSettings.pauseOnLostFocus = !this.gameSettings.pauseOnLostFocus;
                                this.gameSettings.saveOptions();
                            }

                            if (this.gameSettings.keyBindFunction.pressed && EaglerAdapter.getEventKey() == 2) {
                                this.gameSettings.hideGUI = !this.gameSettings.hideGUI;
                            }

                            if (EaglerAdapter.getEventKey() == 4 && this.gameSettings.keyBindFunction.pressed) {
                                this.gameSettings.showDebugInfo = !this.gameSettings.showDebugInfo;
                                this.gameSettings.showDebugProfilerChart = true;
                            }

                            if (EaglerAdapter.getEventKey() == 6 && this.gameSettings.keyBindFunction.pressed) {
                                ++this.gameSettings.thirdPersonView;

                                if (this.gameSettings.thirdPersonView > 2) {
                                    this.gameSettings.thirdPersonView = 0;
                                }
                            }

                            if (EaglerAdapter.getEventKey() == 7 && this.gameSettings.keyBindFunction.pressed) {
                                this.gameSettings.showCoordinates = !this.gameSettings.showCoordinates;
                                this.gameSettings.saveOptions();
                            }

                            if (EaglerAdapter.getEventKey() == 9 && this.gameSettings.keyBindFunction.pressed) {
                                this.gameSettings.smoothCamera = !this.gameSettings.smoothCamera;
                            }
                        }

                        if(!this.gameSettings.keyBindFunction.pressed) {
                            for (int var9 = 0; var9 < 9; ++var9) {
                                if (EaglerAdapter.getEventKey() == 2 + var9) {
                                    this.thePlayer.inventory.currentItem = var9;
                                }
                            }
                        }
                    }
                }
            }

            var8 = this.gameSettings.chatVisibility != 2;

            while (this.gameSettings.keyBindInventory.isPressed()) {
                this.displayGuiScreen(new GuiInventory(this.thePlayer));
            }

            while (this.gameSettings.keyBindDrop.isPressed()) {
                this.thePlayer.dropOneItem(GuiScreen.isCtrlKeyDown());
            }

            while (this.gameSettings.keyBindChat.isPressed() && var8) {
                this.displayGuiScreen(new GuiChat());
            }

            if (this.currentScreen == null && EaglerAdapter.isKeyDown(53) && var8) {
                this.displayGuiScreen(new GuiChat("/"));
            }

            if(this.gameSettings.keyBindSprint.pressed && !this.thePlayer.isSprinting() && this.thePlayer.canSprint() && !this.thePlayer.isCollidedHorizontally) {
                this.thePlayer.setSprinting(true);
            }

            if (this.thePlayer.isUsingItem()) {
                if (!this.gameSettings.keyBindUseItem.pressed) {
                    this.playerController.onStoppedUsingItem(this.thePlayer);
                }

                label379:

                while (true) {
                    if (!this.gameSettings.keyBindAttack.isPressed()) {
                        while (this.gameSettings.keyBindUseItem.isPressed()) {
                            ;
                        }

                        while (true) {
                            if (this.gameSettings.keyBindPickBlock.isPressed()) {
                                continue;
                            }

                            break label379;
                        }
                    }
                }
            } else {
                while (this.gameSettings.keyBindAttack.isPressed()) {
                    this.clickMouse(0);
                }

                while (this.gameSettings.keyBindUseItem.isPressed()) {
                    this.clickMouse(1);
                }

                while (this.gameSettings.keyBindPickBlock.isPressed()) {
                    this.clickMiddleMouseButton();
                }
            }

            if (this.gameSettings.keyBindUseItem.pressed && this.rightClickDelayTimer == 0 && !this.thePlayer.isUsingItem()) {
                this.clickMouse(1);
            }

            this.sendClickBlockToController(0, this.currentScreen == null && this.gameSettings.keyBindAttack.pressed && this.inGameHasFocus);
        }

        if (this.theWorld != null) {
            if (this.thePlayer != null) {
                ++this.joinPlayerCounter;

                if (this.joinPlayerCounter == 30) {
                    this.joinPlayerCounter = 0;
                    this.theWorld.joinEntityInSurroundings(this.thePlayer);
                }

                ++messageOnLoginCounter;

                if(messageOnLoginCounter == 100 && isSingleplayerOrLAN()) {
                    displayEaglercraftText(EnumChatFormatting.GREEN + "Notice: chunk loading may take a while in singleplayer.");
                }

                if(messageOnLoginCounter == 150 && isSingleplayerOrLAN()) {
                    displayEaglercraftText(EnumChatFormatting.AQUA + "Especially in new worlds, if no chunks show give the game up to 5 straight minutes before \"giving up\" on a new world");
                }
            }

            if (!this.isGamePaused) {
                this.entityRenderer.updateRenderer();
            }

            if (!this.isGamePaused) {
                this.renderGlobal.updateClouds();
            }

            if (!this.isGamePaused) {
                if (this.theWorld.lastLightningBolt > 0) {
                    --this.theWorld.lastLightningBolt;
                }

                this.theWorld.updateEntities();
            }

            if (!this.isGamePaused) {
                this.theWorld.setAllowedSpawnTypes(this.theWorld.difficultySetting > 0, true);

                this.theWorld.tick();
            }

            if (!this.isGamePaused && this.theWorld != null) {
                this.theWorld.doVoidFogParticles(MathHelper.floor_double(this.thePlayer.posX), MathHelper.floor_double(this.thePlayer.posY), MathHelper.floor_double(this.thePlayer.posZ));
            }

            if (!this.isGamePaused) {
                this.effectRenderer.updateEffects();
            }
        } else if (this.myNetworkManager != null) {

            this.myNetworkManager.processReadPackets();
        } else {
            this.entityRenderer.startup = 0;
            this.entityRenderer.preStartup = 0;
            this.entityRenderer.asdfghjkl = false;
        }

        if(!(this.gameSettings.adderall || entityRenderer.asdfghjkl) || !yeeState) {
            this.entityRenderer.startup = 0;
            this.entityRenderer.preStartup = 0;
            this.gameSettings.adderall = false;
            this.entityRenderer.asdfghjkl = false;
        }

        if(this.theWorld == null) {
            this.sndManager.playTheTitleMusic();
        }else {
            this.sndManager.stopTheTitleMusic();
        }

        if(reconnectAddress != null) {
            if(theWorld != null) {
                System.out.println("Redirecting to: " + reconnectAddress);
                theWorld.sendQuittingDisconnectingPacket();
                loadWorld((WorldClient) null);
                stopServerAndDisplayGuiScreen(new GuiConnecting(new GuiMultiplayer(new GuiMainMenu()), this,
                        new ServerData("reconnect", reconnectAddress, true)));
            }
            reconnectAddress = null;
        }

        this.systemTime = getSystemTime();
    }

    public void stopServerAndDisplayGuiScreen(GuiScreen par1GuiScreen) {
        if(!IntegratedServer.isWorldNotLoaded()) {
            IntegratedServer.unloadWorld();
            displayGuiScreen(new GuiScreenSingleplayerLoading(par1GuiScreen, "saving world", () -> IntegratedServer.isReady()));
        }else {
            displayGuiScreen(par1GuiScreen);
        }
    }

    private int titleMusicObj = -1;

    public String reconnectAddress = null;

    /**
     * Arguments: World foldername,  World ingame name, WorldSettings
     */
    public void launchIntegratedServer(String folderName, String trim, WorldSettings var6) {
        this.loadWorld((WorldClient)null);

        IntegratedServer.loadWorld(folderName, gameSettings.difficulty, var6);

        this.displayGuiScreen(new GuiScreenSingleplayerLoading(new GuiScreenSingleplayerConnecting(new GuiMainMenu(), "Connecting to " + folderName), "Loading world: " + folderName, () -> IntegratedServer.isWorldRunning()));
    }

    /**
     * unloads the current world first
     */
    public void loadWorld(WorldClient par1WorldClient)
    {
        this.loadWorld(par1WorldClient, "");
    }

    /**
     * par2Str is displayed on the loading screen to the user unloads the current world first
     */
    public void loadWorld(WorldClient par1WorldClient, String par2Str) {
        if (par1WorldClient == null) {
            NetClientHandler var3 = this.getNetHandler();

            if (var3 != null) {
                var3.cleanup();
            }

            if (this.myNetworkManager != null) {
                this.myNetworkManager.closeConnections();
            }

            this.myNetworkManager = null;

        }
        this.renderViewEntity = null;

        if (this.loadingScreen != null) {
            this.loadingScreen.resetProgressAndMessage(par2Str);
            this.loadingScreen.resetProgresAndWorkingMessage("");
        }

        if (par1WorldClient == null && this.theWorld != null) {
            if (this.texturePackList.getIsDownloading()) {
                this.texturePackList.onDownloadFinished();
            }
            this.lanState = false;
            IntegratedServer.unloadWorld();
            this.setServerData((ServerData) null);
            this.integratedServerIsRunning = false;
        }

        this.sndManager.playStreaming((String) null, 0.0F, 0.0F, 0.0F);
        this.sndManager.stopAllSounds();
        if(EaglerAdapter.isVideoSupported()) {
            EaglerAdapter.unloadVideo();
        }
        this.theWorld = par1WorldClient;

        if (par1WorldClient != null) {
            if (this.renderGlobal != null) {
                this.renderGlobal.setWorldAndLoadRenderers(par1WorldClient);
            }

            if (this.effectRenderer != null) {
                this.effectRenderer.clearEffects(par1WorldClient);
            }

            if (this.thePlayer == null) {
                this.thePlayer = this.playerController.func_78754_a(par1WorldClient);
                this.playerController.flipPlayer(this.thePlayer);
            }

            //if(!EaglerAdapter._wisAnisotropicPatched()) {
            //	displayEaglercraftText("ANGLE Issue #4994 is unpatched on this browser, using fake aliased sampling on linear magnified terrain texture for anisotropic filtering. Chrome patch progress and information available at https://crbug.com/angleproject/4994");
            //}

            StringTranslate var4 = StringTranslate.getInstance();

            if(!this.gameSettings.fancyGraphics || this.gameSettings.ambientOcclusion == 0) {
                displayEaglercraftText("Note: " + var4.translateKey("fancyGraphicsNote"));
            }

            if(!EaglerAdapter.isIntegratedServerAvailable()){
                displayEaglercraftText("Warning: world loading may take a while, so you may need to wait for a few seconds for the world to load and the lag will stop.");
            }

            if(this.gameSettings.showCoordinates) {
                displayEaglercraftText(EnumChatFormatting.LIGHT_PURPLE + "Note: use F+6 to hide the coordinates off of the screen (if you're in public)");
            }else {
                displayEaglercraftText(EnumChatFormatting.LIGHT_PURPLE + "Note: use F+6 to show your coordinates on the screen");
            }

            messageOnLoginCounter = 0;

            this.thePlayer.preparePlayerToSpawn();
            par1WorldClient.spawnEntityInWorld(this.thePlayer);
            this.thePlayer.movementInput = new MovementInputFromOptions(this.gameSettings);
            this.playerController.setPlayerCapabilities(this.thePlayer);
            this.renderViewEntity = this.thePlayer;
        } else {
            this.thePlayer = null;
        }

        System.gc();
        this.systemTime = 0L;
    }

    public void setNetManager(INetworkManager nm) {
		this.myNetworkManager = nm;
	}

    /**
     * A String of renderGlobal.getDebugInfoRenders
     */
    public String debugInfoRenders()
    {
        return this.renderGlobal.getDebugInfoRenders();
    }

    /**
     * Gets the information in the F3 menu about how many entities are infront/around you
     */
    public String getEntityDebug()
    {
        return this.renderGlobal.getDebugInfoEntities();
    }

    /**
     * Gets the name of the world's current chunk provider
     */
    public String getWorldProviderName()
    {
        return this.theWorld.getProviderName();
    }

    /**
     * A String of how many entities are in the world
     */
    public String debugInfoEntities()
    {
        return "P: " + this.effectRenderer.getStatistics() + ". T: " + this.theWorld.getDebugLoadedEntities();
    }

    public void setDimensionAndSpawnPlayer(int par1)
    {
        this.theWorld.setSpawnLocation();
        this.theWorld.removeAllEntities();
        int var2 = 0;
        String var3 = null;

        if (this.thePlayer != null)
        {
            var2 = this.thePlayer.entityId;
            this.theWorld.removeEntity(this.thePlayer);
            var3 = this.thePlayer.func_142021_k();
        }

        this.renderViewEntity = null;
        this.thePlayer = this.playerController.func_78754_a(this.theWorld);
        this.thePlayer.dimension = par1;
        this.renderViewEntity = this.thePlayer;
        this.thePlayer.preparePlayerToSpawn();
        this.thePlayer.func_142020_c(var3);
        this.theWorld.spawnEntityInWorld(this.thePlayer);
        this.playerController.flipPlayer(this.thePlayer);
        this.thePlayer.movementInput = new MovementInputFromOptions(this.gameSettings);
        this.thePlayer.entityId = var2;
        this.playerController.setPlayerCapabilities(this.thePlayer);

        if (this.currentScreen instanceof GuiGameOver)
        {
            this.displayGuiScreen((GuiScreen)null);
        }
    }

    /**
     * Gets whether this is a demo or not.
     */
    public final boolean isDemo()
    {
        return false;
    }

    /**
     * Returns the NetClientHandler.
     */
    public NetClientHandler getNetHandler()
    {
        return this.thePlayer != null ? this.thePlayer.sendQueue : null;
    }

    public static boolean isGuiEnabled()
    {
        return theMinecraft == null || !theMinecraft.gameSettings.hideGUI;
    }

    public static boolean isFancyGraphicsEnabled()
    {
        return theMinecraft != null && theMinecraft.gameSettings.fancyGraphics;
    }

    /**
     * Returns if ambient occlusion is enabled
     */
    public static boolean isAmbientOcclusionEnabled()
    {
        return theMinecraft != null && theMinecraft.gameSettings.ambientOcclusion != 0;
    }

    /**
     * Returns true if the message is a client command and should not be sent to the server. However there are no such
     * commands at this point in time.
     */
    public boolean handleClientCommand(String par1Str)
    {
        return false;
    }

    /**
     * Called when the middle mouse button gets clicked
     */
    private void clickMiddleMouseButton()
    {
        if (this.objectMouseOver != null)
        {
            boolean var1 = this.thePlayer.capabilities.isCreativeMode;
            int var3 = 0;
            boolean var4 = false;
            int var2;
            int var5;

            if (this.objectMouseOver.typeOfHit == EnumMovingObjectType.TILE)
            {
                var5 = this.objectMouseOver.blockX;
                int var6 = this.objectMouseOver.blockY;
                int var7 = this.objectMouseOver.blockZ;
                Block var8 = Block.blocksList[this.theWorld.getBlockId(var5, var6, var7)];

                if (var8 == null)
                {
                    return;
                }

                var2 = var8.idPicked(this.theWorld, var5, var6, var7);

                if (var2 == 0)
                {
                    return;
                }

                var4 = Item.itemsList[var2].getHasSubtypes();
                int var9 = var2 < 256 && !Block.blocksList[var8.blockID].isFlowerPot() ? var2 : var8.blockID;
                var3 = Block.blocksList[var9].getDamageValue(this.theWorld, var5, var6, var7);
            }
            else
            {
                if (this.objectMouseOver.typeOfHit != EnumMovingObjectType.ENTITY || this.objectMouseOver.entityHit == null || !var1)
                {
                    return;
                }

                if (this.objectMouseOver.entityHit instanceof EntityPainting)
                {
                    var2 = Item.painting.itemID;
                }
                else if (this.objectMouseOver.entityHit instanceof EntityLeashKnot)
                {
                    var2 = Item.leash.itemID;
                }
                else if (this.objectMouseOver.entityHit instanceof EntityItemFrame)
                {
                    EntityItemFrame var10 = (EntityItemFrame)this.objectMouseOver.entityHit;

                    if (var10.getDisplayedItem() == null)
                    {
                        var2 = Item.itemFrame.itemID;
                    }
                    else
                    {
                        var2 = var10.getDisplayedItem().itemID;
                        var3 = var10.getDisplayedItem().getItemDamage();
                        var4 = true;
                    }
                }
                else if (this.objectMouseOver.entityHit instanceof EntityMinecart)
                {
                    EntityMinecart var11 = (EntityMinecart)this.objectMouseOver.entityHit;

                    if (var11.getMinecartType() == 2)
                    {
                        var2 = Item.minecartPowered.itemID;
                    }
                    else if (var11.getMinecartType() == 1)
                    {
                        var2 = Item.minecartCrate.itemID;
                    }
                    else if (var11.getMinecartType() == 3)
                    {
                        var2 = Item.minecartTnt.itemID;
                    }
                    else if (var11.getMinecartType() == 5)
                    {
                        var2 = Item.minecartHopper.itemID;
                    }
                    else
                    {
                        var2 = Item.minecartEmpty.itemID;
                    }
                }
                else if (this.objectMouseOver.entityHit instanceof EntityBoat)
                {
                    var2 = Item.boat.itemID;
                }
                else
                {
                    var2 = Item.monsterPlacer.itemID;
                    var3 = EntityList.getEntityID(this.objectMouseOver.entityHit);
                    var4 = true;

                    if (var3 <= 0 || !EntityList.entityEggs.containsKey(Integer.valueOf(var3)))
                    {
                        return;
                    }
                }
            }

            this.thePlayer.inventory.setCurrentItem(var2, var3, var4, var1);

            if (var1)
            {
                var5 = this.thePlayer.inventoryContainer.inventorySlots.size() - 9 + this.thePlayer.inventory.currentItem;
                this.playerController.sendSlotPacket(this.thePlayer.inventory.getStackInSlot(this.thePlayer.inventory.currentItem), var5);
            }
        }
    }

    /**
     * Return the singleton Minecraft instance for the game
     */
    public static Minecraft getMinecraft()
    {
        return theMinecraft;
    }

    /**
     * Used in the usage snooper.
     */
    public static int getGLMaximumTextureSize()
    {
        return 8192;
    }

    public void scheduleTexturePackRefresh() {
        this.refreshTexturePacksScheduled = true;
    }

    /**
     * Set the current ServerData instance.
     */
    public void setServerData(ServerData par1ServerData)
    {
        this.currentServerData = par1ServerData;
    }

    public ServerData getServerData() {
        return this.currentServerData;
    }

    public boolean isIntegratedServerRunning()
    {
        return this.integratedServerIsRunning;
    }

    /**
     * Returns true if there is only one player playing, and the current server is the integrated one.
     */
    public boolean isSingleplayer()
    {
        return this.integratedServerIsRunning && this.theIntegratedServer != null;
    }
    /**
     * Gets the system time in milliseconds.
     */
    public static long getSystemTime() {
        return EaglerAdapter.steadyTimeMillis();
    }

    public Session getSession()
    {
        return new Session(EaglerProfile.username, EaglerProfile.username);
    }

    public RenderEngine getTextureManager()
    {
        return this.renderEngine;
    }

    public String getServerURI() {
        return this.getNetHandler() != null ? this.getNetHandler().getNetManager().getServerURI() : "[not connected]";
    }
}
