com.kegare.caveworld.client.config.GuiBiomesEntry.java Source code

Java tutorial

Introduction

Here is the source code for com.kegare.caveworld.client.config.GuiBiomesEntry.java

Source

/*
 * Caveworld
 *
 * Copyright (c) 2014 kegare
 * https://github.com/kegare
 *
 * This mod is distributed under the terms of the Minecraft Mod Public License Japanese Translation, or MMPL_J.
 */

package com.kegare.caveworld.client.config;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;

import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.GuiTextField;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.resources.I18n;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.world.biome.BiomeGenBase;
import net.minecraftforge.common.config.ConfigCategory;

import org.apache.commons.lang3.CharUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;

import com.google.common.base.Predicate;
import com.google.common.base.Strings;
import com.google.common.collect.Collections2;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.kegare.caveworld.api.BlockEntry;
import com.kegare.caveworld.api.CaveworldAPI;
import com.kegare.caveworld.api.ICaveBiome;
import com.kegare.caveworld.client.config.GuiSelectBiome.SelectListener;
import com.kegare.caveworld.client.gui.GuiListSlot;
import com.kegare.caveworld.core.CaveBiomeManager;
import com.kegare.caveworld.core.CaveBiomeManager.CaveBiome;
import com.kegare.caveworld.core.Caveworld;
import com.kegare.caveworld.core.Config;
import com.kegare.caveworld.util.ArrayListExtended;
import com.kegare.caveworld.util.CaveUtils;
import com.kegare.caveworld.util.comparator.CaveBiomeComparator;

import cpw.mods.fml.client.config.GuiButtonExt;
import cpw.mods.fml.client.config.GuiCheckBox;
import cpw.mods.fml.client.config.GuiConfig;
import cpw.mods.fml.client.config.HoverChecker;
import cpw.mods.fml.common.registry.GameData;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;

@SideOnly(Side.CLIENT)
public class GuiBiomesEntry extends GuiScreen implements SelectListener {
    protected final GuiScreen parentScreen;

    protected BiomeList biomeList;

    protected GuiButton doneButton;
    protected GuiButton editButton;
    protected GuiButton cancelButton;
    protected GuiButton addButton;
    protected GuiButton removeButton;
    protected GuiButton clearButton;
    protected GuiCheckBox detailInfo;
    protected GuiCheckBox instantFilter;
    protected GuiTextField filterTextField;

    protected HoverChecker detailHoverChecker;
    protected HoverChecker instantHoverChecker;

    protected boolean editMode;
    protected GuiTextField weightField;
    protected GuiTextField terrainBlockField;
    protected GuiTextField terrainMetaField;
    protected GuiTextField topBlockField;
    protected GuiTextField topMetaField;

    protected HoverChecker weightHoverChecker;
    protected HoverChecker terrainHoverChecker;
    protected HoverChecker topHoverChecker;

    private int maxLabelWidth;

    private final List<String> editLabelList = Lists.newArrayList();
    private final List<GuiTextField> editFieldList = Lists.newArrayList();

    private final Map<Object, List<String>> hoverCache = Maps.newHashMap();

    public GuiBiomesEntry(GuiScreen parent) {
        this.parentScreen = parent;
    }

    @Override
    public void initGui() {
        Keyboard.enableRepeatEvents(true);

        if (biomeList == null) {
            biomeList = new BiomeList(this);
        }

        biomeList.func_148122_a(width, height, 32, height - (editMode ? 105 : 28));

        if (doneButton == null) {
            doneButton = new GuiButtonExt(0, 0, 0, 65, 20, I18n.format("gui.done"));
        }

        doneButton.xPosition = width / 2 + 135;
        doneButton.yPosition = height - doneButton.height - 4;

        if (editButton == null) {
            editButton = new GuiButtonExt(1, 0, 0, doneButton.width, doneButton.height, I18n.format("gui.edit"));
            editButton.enabled = false;
        }

        editButton.xPosition = doneButton.xPosition - doneButton.width - 3;
        editButton.yPosition = doneButton.yPosition;
        editButton.enabled = biomeList.selected != null;
        editButton.visible = !editMode;

        if (cancelButton == null) {
            cancelButton = new GuiButtonExt(2, 0, 0, editButton.width, editButton.height,
                    I18n.format("gui.cancel"));
        }

        cancelButton.xPosition = editButton.xPosition;
        cancelButton.yPosition = editButton.yPosition;
        cancelButton.visible = editMode;

        if (removeButton == null) {
            removeButton = new GuiButtonExt(4, 0, 0, doneButton.width, doneButton.height,
                    I18n.format("gui.remove"));
        }

        removeButton.xPosition = editButton.xPosition - editButton.width - 3;
        removeButton.yPosition = doneButton.yPosition;
        removeButton.visible = !editMode;

        if (addButton == null) {
            addButton = new GuiButtonExt(3, 0, 0, doneButton.width, doneButton.height, I18n.format("gui.add"));
        }

        addButton.xPosition = removeButton.xPosition - removeButton.width - 3;
        addButton.yPosition = doneButton.yPosition;
        addButton.visible = !editMode;

        if (clearButton == null) {
            clearButton = new GuiButtonExt(5, 0, 0, removeButton.width, removeButton.height,
                    I18n.format("gui.clear"));
        }

        clearButton.xPosition = removeButton.xPosition;
        clearButton.yPosition = removeButton.yPosition;
        clearButton.visible = false;

        if (detailInfo == null) {
            detailInfo = new GuiCheckBox(6, 0, 5, I18n.format(Caveworld.CONFIG_LANG + "detail"), true);
        }

        detailInfo.setIsChecked(CaveConfigGui.detailInfo);
        detailInfo.xPosition = width / 2 + 95;

        if (instantFilter == null) {
            instantFilter = new GuiCheckBox(7, 0, detailInfo.yPosition + detailInfo.height + 2,
                    I18n.format(Caveworld.CONFIG_LANG + "instant"), true);
        }

        instantFilter.setIsChecked(CaveConfigGui.instantFilter);
        instantFilter.xPosition = detailInfo.xPosition;

        buttonList.clear();
        buttonList.add(doneButton);

        if (editMode) {
            buttonList.add(cancelButton);
        } else {
            buttonList.add(editButton);
            buttonList.add(addButton);
            buttonList.add(removeButton);
            buttonList.add(clearButton);
        }

        buttonList.add(detailInfo);
        buttonList.add(instantFilter);

        if (filterTextField == null) {
            filterTextField = new GuiTextField(fontRendererObj, 0, 0, 122, 16);
            filterTextField.setMaxStringLength(500);
        }

        filterTextField.xPosition = width / 2 - 200;
        filterTextField.yPosition = height - filterTextField.height - 6;

        detailHoverChecker = new HoverChecker(detailInfo, 800);
        instantHoverChecker = new HoverChecker(instantFilter, 800);

        editLabelList.clear();
        editLabelList.add(I18n.format(Caveworld.CONFIG_LANG + "biomes.genWeight"));
        editLabelList.add(I18n.format(Caveworld.CONFIG_LANG + "biomes.terrainBlock"));
        editLabelList.add("");
        editLabelList.add(I18n.format(Caveworld.CONFIG_LANG + "biomes.topBlock"));
        editLabelList.add("");

        for (String key : editLabelList) {
            maxLabelWidth = Math.max(maxLabelWidth, fontRendererObj.getStringWidth(key));
        }

        if (weightField == null) {
            weightField = new GuiTextField(fontRendererObj, 0, 0, 0, 15);
            weightField.setMaxStringLength(3);
        }

        int i = maxLabelWidth + 8 + width / 2;
        weightField.xPosition = width / 2 - i / 2 + maxLabelWidth + 10;
        weightField.yPosition = biomeList.bottom + 1 + 20;
        weightField.width = width / 2 + i / 2 - 45 - weightField.xPosition + 40;

        if (terrainBlockField == null) {
            terrainBlockField = new GuiTextField(fontRendererObj, 0, 0, 0, weightField.height);
            terrainBlockField.setMaxStringLength(100);
        }

        terrainBlockField.xPosition = weightField.xPosition;
        terrainBlockField.yPosition = weightField.yPosition + weightField.height + 5;
        terrainBlockField.width = weightField.width / 4 + weightField.width / 2 - 1;

        if (terrainMetaField == null) {
            terrainMetaField = new GuiTextField(fontRendererObj, 0, 0, 0, terrainBlockField.height);
            terrainMetaField.setMaxStringLength(2);
        }

        terrainMetaField.xPosition = terrainBlockField.xPosition + terrainBlockField.width + 3;
        terrainMetaField.yPosition = terrainBlockField.yPosition;
        terrainMetaField.width = weightField.width / 4 - 1;

        if (topBlockField == null) {
            topBlockField = new GuiTextField(fontRendererObj, 0, 0, 0, terrainBlockField.height);
            topBlockField.setMaxStringLength(100);
        }

        topBlockField.xPosition = terrainBlockField.xPosition;
        topBlockField.yPosition = terrainMetaField.yPosition + terrainMetaField.height + 5;
        topBlockField.width = terrainBlockField.width;

        if (topMetaField == null) {
            topMetaField = new GuiTextField(fontRendererObj, 0, 0, 0, topBlockField.height);
        }

        topMetaField.xPosition = terrainMetaField.xPosition;
        topMetaField.yPosition = topBlockField.yPosition;
        topMetaField.width = terrainMetaField.width;

        editFieldList.clear();

        if (editMode) {
            editFieldList.add(weightField);
            editFieldList.add(terrainBlockField);
            editFieldList.add(terrainMetaField);
            editFieldList.add(topBlockField);
            editFieldList.add(topMetaField);
        }

        weightHoverChecker = new HoverChecker(weightField.yPosition - 1, weightField.yPosition + weightField.height,
                weightField.xPosition - maxLabelWidth - 12, weightField.xPosition - 10, 800);
        terrainHoverChecker = new HoverChecker(terrainBlockField.yPosition - 1,
                terrainBlockField.yPosition + terrainBlockField.height,
                terrainBlockField.xPosition - maxLabelWidth - 12, terrainBlockField.xPosition - 10, 800);
        topHoverChecker = new HoverChecker(topBlockField.yPosition - 1,
                topBlockField.yPosition + topBlockField.height, topBlockField.xPosition - maxLabelWidth - 12,
                topBlockField.xPosition - 10, 800);
    }

    @Override
    protected void actionPerformed(GuiButton button) {
        if (button.enabled) {
            switch (button.id) {
            case 0:
                if (editMode) {
                    if (NumberUtils.toInt(weightField.getText()) <= 0) {
                        return;
                    }

                    biomeList.selected.setGenWeight(
                            NumberUtils.toInt(weightField.getText(), biomeList.selected.getGenWeight()));
                    biomeList.selected.setTerrainBlock(new BlockEntry(terrainBlockField.getText(),
                            NumberUtils.toInt(terrainMetaField.getText())));
                    biomeList.selected.setTopBlock(
                            new BlockEntry(topBlockField.getText(), NumberUtils.toInt(topMetaField.getText())));

                    hoverCache.remove(biomeList.selected);

                    actionPerformed(cancelButton);

                    biomeList.scrollToSelected();
                } else {
                    CaveworldAPI.clearCaveBiomes();

                    ConfigCategory category;

                    for (ICaveBiome entry : biomeList.biomes) {
                        category = Config.biomesCfg.getCategory(Integer.toString(entry.getBiome().biomeID));
                        category.get("genWeight").set(entry.getGenWeight());
                        category.get("terrainBlock").set(
                                GameData.getBlockRegistry().getNameForObject(entry.getTerrainBlock().getBlock()));
                        category.get("terrainBlockMetadata").set(entry.getTerrainBlock().getMetadata());
                        category.get("topBlock")
                                .set(GameData.getBlockRegistry().getNameForObject(entry.getTopBlock().getBlock()));
                        category.get("topBlockMetadata").set(entry.getTopBlock().getMetadata());

                        CaveworldAPI.addCaveBiome(entry);
                    }

                    if (Config.biomesCfg.hasChanged()) {
                        Config.biomesCfg.save();
                    }

                    actionPerformed(cancelButton);
                }

                break;
            case 1:
                if (editMode) {
                    actionPerformed(cancelButton);
                } else {
                    editMode = true;
                    initGui();

                    biomeList.scrollToSelected();

                    weightField.setText(Integer.toString(biomeList.selected.getGenWeight()));
                    terrainBlockField.setText(GameData.getBlockRegistry()
                            .getNameForObject(biomeList.selected.getTerrainBlock().getBlock()));
                    terrainMetaField.setText(Integer.toString(biomeList.selected.getTerrainBlock().getMetadata()));
                    topBlockField.setText(GameData.getBlockRegistry()
                            .getNameForObject(biomeList.selected.getTopBlock().getBlock()));
                    topMetaField.setText(Integer.toString(biomeList.selected.getTopBlock().getMetadata()));
                }

                break;
            case 2:
                if (editMode) {
                    editMode = false;
                    initGui();
                } else {
                    mc.displayGuiScreen(parentScreen);
                }

                break;
            case 3:
                BiomeGenBase[] biomes = new BiomeGenBase[biomeList.biomes.size()];

                for (int i = 0; i < biomes.length; ++i) {
                    biomes[i] = biomeList.biomes.get(i).getBiome();
                }

                mc.displayGuiScreen(new GuiSelectBiome(this).setHiddenBiomes(biomes));
                break;
            case 4:
                if (biomeList.biomes.remove(biomeList.selected)) {
                    int i = biomeList.contents.indexOf(biomeList.selected);

                    Config.biomesCfg.getCategory(Integer.toString(biomeList.selected.getBiome().biomeID))
                            .get("genWeight").set(0);

                    biomeList.contents.remove(i);
                    biomeList.selected = biomeList.contents.get(i, biomeList.contents.get(--i, null));
                }

                break;
            case 5:
                for (Object entry : biomeList.biomes.toArray()) {
                    biomeList.selected = (ICaveBiome) entry;

                    actionPerformed(removeButton);
                }

                break;
            case 6:
                CaveConfigGui.detailInfo = detailInfo.isChecked();
                break;
            case 7:
                CaveConfigGui.instantFilter = instantFilter.isChecked();
                break;
            }
        }
    }

    @Override
    public void setResult(final List<Integer> result) {
        new ForkJoinPool().execute(new RecursiveAction() {
            @Override
            protected void compute() {
                BiomeGenBase biome;
                ICaveBiome entry;

                for (Integer id : result) {
                    biome = BiomeGenBase.getBiome(id);

                    if (biome != null) {
                        for (ICaveBiome cave : biomeList.biomes) {
                            if (cave.getBiome() == biome) {
                                biome = null;
                                biomeList.selected = cave;
                                break;
                            }
                        }

                        if (biome == null) {
                            continue;
                        }

                        if (CaveBiomeManager.defaultMapping.containsKey(biome)) {
                            entry = CaveBiomeManager.defaultMapping.get(biome);
                        } else {
                            entry = new CaveBiome(biome, 10);
                        }

                        if (biomeList.biomes.addIfAbsent(entry)) {
                            biomeList.contents.addIfAbsent(entry);
                            biomeList.selected = entry;
                        }
                    }
                }

                Comparator<ICaveBiome> comparator = new CaveBiomeComparator();

                Collections.sort(biomeList.contents, comparator);
                Collections.sort(biomeList.biomes, comparator);

                biomeList.scrollToSelected();
            }
        });
    }

    @Override
    public void updateScreen() {
        if (editMode) {
            for (GuiTextField textField : editFieldList) {
                textField.updateCursorCounter();
            }
        } else {
            editButton.enabled = biomeList.selected != null;
            removeButton.enabled = editButton.enabled;

            filterTextField.updateCursorCounter();
        }
    }

    @Override
    public void drawScreen(int mouseX, int mouseY, float ticks) {
        biomeList.drawScreen(mouseX, mouseY, ticks);

        drawCenteredString(fontRendererObj, I18n.format(Caveworld.CONFIG_LANG + "biomes"), width / 2, 15, 0xFFFFFF);

        super.drawScreen(mouseX, mouseY, ticks);

        if (editMode) {
            drawCenteredString(fontRendererObj, biomeList.selected.getBiome().biomeName, width / 2,
                    biomeList.bottom + 6, 0xFFFFFF);

            GuiTextField textField;

            for (int i = 0; i < editFieldList.size(); ++i) {
                textField = editFieldList.get(i);
                textField.drawTextBox();
                drawString(fontRendererObj, editLabelList.get(i), textField.xPosition - maxLabelWidth - 10,
                        textField.yPosition + 3, 0xBBBBBB);
            }

            if (weightHoverChecker.checkHover(mouseX, mouseY)) {
                if (!hoverCache.containsKey(weightHoverChecker)) {
                    List<String> hover = Lists.newArrayList();
                    String key = Caveworld.CONFIG_LANG + "biomes.genWeight";
                    hover.add(EnumChatFormatting.GRAY + I18n.format(key));
                    hover.addAll(fontRendererObj.listFormattedStringToWidth(I18n.format(key + ".tooltip"), 300));

                    hoverCache.put(weightHoverChecker, hover);
                }

                func_146283_a(hoverCache.get(weightHoverChecker), mouseX, mouseY);
            } else if (terrainHoverChecker.checkHover(mouseX, mouseY)) {
                if (!hoverCache.containsKey(terrainHoverChecker)) {
                    List<String> hover = Lists.newArrayList();
                    String key = Caveworld.CONFIG_LANG + "biomes.terrainBlock";
                    hover.add(EnumChatFormatting.GRAY + I18n.format(key));
                    hover.addAll(fontRendererObj.listFormattedStringToWidth(I18n.format(key + ".tooltip"), 300));

                    hoverCache.put(terrainHoverChecker, hover);
                }

                func_146283_a(hoverCache.get(terrainHoverChecker), mouseX, mouseY);
            } else if (topHoverChecker.checkHover(mouseX, mouseY)) {
                if (!hoverCache.containsKey(topHoverChecker)) {
                    List<String> hover = Lists.newArrayList();
                    String key = Caveworld.CONFIG_LANG + "biomes.topBlock";
                    hover.add(EnumChatFormatting.GRAY + I18n.format(key));
                    hover.addAll(fontRendererObj.listFormattedStringToWidth(I18n.format(key + ".tooltip"), 300));

                    hoverCache.put(topHoverChecker, hover);
                }

                func_146283_a(hoverCache.get(topHoverChecker), mouseX, mouseY);
            }
        } else {
            filterTextField.drawTextBox();
        }

        if (detailHoverChecker.checkHover(mouseX, mouseY)) {
            if (!hoverCache.containsKey(detailHoverChecker)) {
                hoverCache.put(detailHoverChecker, fontRendererObj
                        .listFormattedStringToWidth(I18n.format(Caveworld.CONFIG_LANG + "detail.hover"), 300));
            }

            func_146283_a(hoverCache.get(detailHoverChecker), mouseX, mouseY);
        } else if (instantHoverChecker.checkHover(mouseX, mouseY)) {
            if (!hoverCache.containsKey(instantHoverChecker)) {
                hoverCache.put(instantHoverChecker, fontRendererObj
                        .listFormattedStringToWidth(I18n.format(Caveworld.CONFIG_LANG + "instant.hover"), 300));
            }

            func_146283_a(hoverCache.get(instantHoverChecker), mouseX, mouseY);
        } else if (biomeList.func_148141_e(mouseY) && isCtrlKeyDown()) {
            ICaveBiome entry = biomeList.contents.get(biomeList.func_148124_c(mouseX, mouseY), null);

            if (entry != null) {
                if (!hoverCache.containsKey(entry)) {
                    BiomeGenBase biome = entry.getBiome();
                    List<String> info = Lists.newArrayList();

                    info.add(EnumChatFormatting.DARK_GRAY + Integer.toString(biome.biomeID) + ": "
                            + biome.biomeName);
                    info.add(EnumChatFormatting.GRAY + I18n.format(Caveworld.CONFIG_LANG + "biomes.genWeight")
                            + ": " + entry.getGenWeight());
                    info.add(EnumChatFormatting.GRAY + I18n.format(Caveworld.CONFIG_LANG + "biomes.terrainBlock")
                            + ": "
                            + GameData.getBlockRegistry().getNameForObject(entry.getTerrainBlock().getBlock())
                            + ", " + entry.getTerrainBlock().getMetadata());
                    info.add(EnumChatFormatting.GRAY + I18n.format(Caveworld.CONFIG_LANG + "biomes.topBlock") + ": "
                            + GameData.getBlockRegistry().getNameForObject(entry.getTopBlock().getBlock()) + ", "
                            + entry.getTopBlock().getMetadata());

                    hoverCache.put(entry, info);
                }

                func_146283_a(hoverCache.get(entry), mouseX, mouseY);
            }
        }
    }

    @Override
    public void handleMouseInput() {
        super.handleMouseInput();

        if (weightField.isFocused()) {
            int i = Mouse.getDWheel();

            if (i < 0) {
                weightField.setText(Integer.toString(Math.max(NumberUtils.toInt(weightField.getText()) - 1, 0)));
            } else if (i > 0) {
                weightField.setText(Integer.toString(Math.min(NumberUtils.toInt(weightField.getText()) + 1, 100)));
            }
        } else if (terrainMetaField.isFocused()) {
            int i = Mouse.getDWheel();

            if (i < 0) {
                terrainMetaField
                        .setText(Integer.toString(Math.max(NumberUtils.toInt(terrainMetaField.getText()) - 1, 0)));
            } else if (i > 0) {
                terrainMetaField
                        .setText(Integer.toString(Math.min(NumberUtils.toInt(terrainMetaField.getText()) + 1, 15)));
            }
        } else if (topMetaField.isFocused()) {
            int i = Mouse.getDWheel();

            if (i < 0) {
                topMetaField.setText(Integer.toString(Math.max(NumberUtils.toInt(topMetaField.getText()) - 1, 0)));
            } else if (i > 0) {
                topMetaField.setText(Integer.toString(Math.min(NumberUtils.toInt(topMetaField.getText()) + 1, 15)));
            }
        }
    }

    @Override
    protected void mouseClicked(int x, int y, int code) {
        super.mouseClicked(x, y, code);

        if (editMode) {
            for (GuiTextField textField : editFieldList) {
                textField.mouseClicked(x, y, code);
            }

            if (!isShiftKeyDown()) {
                if (terrainBlockField.isFocused()) {
                    terrainBlockField.setFocused(false);

                    mc.displayGuiScreen(new GuiSelectBlock(this, terrainBlockField, terrainMetaField));
                } else if (topBlockField.isFocused()) {
                    topBlockField.setFocused(false);

                    mc.displayGuiScreen(new GuiSelectBlock(this, topBlockField, topMetaField));
                }
            }
        } else {
            filterTextField.mouseClicked(x, y, code);
        }
    }

    @Override
    public void handleKeyboardInput() {
        super.handleKeyboardInput();

        if (GuiConfig.isShiftKeyDown()) {
            clearButton.visible = !editMode && Keyboard.getEventKeyState();
        }
    }

    @Override
    protected void keyTyped(char c, int code) {
        if (editMode) {
            for (GuiTextField textField : editFieldList) {
                if (textField.isFocused()) {
                    if (code == Keyboard.KEY_ESCAPE) {
                        textField.setFocused(false);
                    }

                    if (textField == weightField || textField == terrainMetaField || textField == topMetaField) {
                        if (CharUtils.isAsciiControl(c) || CharUtils.isAsciiNumeric(c)) {
                            textField.textboxKeyTyped(c, code);
                        }
                    } else {
                        textField.textboxKeyTyped(c, code);
                    }
                }
            }
        } else {
            if (filterTextField.isFocused()) {
                if (code == Keyboard.KEY_ESCAPE) {
                    filterTextField.setFocused(false);
                }

                String prev = filterTextField.getText();

                filterTextField.textboxKeyTyped(c, code);

                String text = filterTextField.getText();
                boolean changed = text != prev;

                if (Strings.isNullOrEmpty(text) && changed) {
                    biomeList.setFilter(null);
                } else if (instantFilter.isChecked() && changed || code == Keyboard.KEY_RETURN) {
                    biomeList.setFilter(text);
                }
            } else {
                if (code == Keyboard.KEY_ESCAPE) {
                    actionPerformed(doneButton);
                } else if (code == Keyboard.KEY_BACK) {
                    biomeList.selected = null;
                } else if (code == Keyboard.KEY_UP) {
                    biomeList.scrollUp();
                } else if (code == Keyboard.KEY_DOWN) {
                    biomeList.scrollDown();
                } else if (code == Keyboard.KEY_HOME) {
                    biomeList.scrollToTop();
                } else if (code == Keyboard.KEY_END) {
                    biomeList.scrollToEnd();
                } else if (code == Keyboard.KEY_SPACE) {
                    biomeList.scrollToSelected();
                } else if (code == Keyboard.KEY_PRIOR) {
                    biomeList.scrollToPrev();
                } else if (code == Keyboard.KEY_NEXT) {
                    biomeList.scrollToNext();
                } else if (code == Keyboard.KEY_F || code == mc.gameSettings.keyBindChat.getKeyCode()) {
                    filterTextField.setFocused(true);
                } else if (code == Keyboard.KEY_DELETE && biomeList.selected != null) {
                    actionPerformed(removeButton);
                }
            }
        }
    }

    @Override
    public boolean doesGuiPauseGame() {
        return false;
    }

    @Override
    public void onGuiClosed() {
        biomeList.currentPanoramaPaths = null;
    }

    protected static class BiomeList extends GuiListSlot {
        protected final GuiBiomesEntry parent;

        protected final ArrayListExtended<ICaveBiome> biomes = new ArrayListExtended(CaveworldAPI.getCaveBiomes());
        protected final ArrayListExtended<ICaveBiome> contents = new ArrayListExtended(biomes);

        private final Map<String, List<ICaveBiome>> filterCache = Maps.newHashMap();

        protected ICaveBiome selected;

        private BiomeList(GuiBiomesEntry parent) {
            super(parent.mc, 0, 0, 0, 0, 22);
            this.parent = parent;
        }

        @Override
        public void scrollToSelected() {
            scrollToTop();

            if (selected != null) {
                scrollBy(contents.indexOf(selected) * getSlotHeight());
            }
        }

        @Override
        protected int getSize() {
            return contents.size();
        }

        @Override
        protected void drawBackground() {
            parent.drawDefaultBackground();
        }

        @Override
        protected void drawSlot(int index, int par2, int par3, int par4, Tessellator tessellator, int mouseX,
                int mouseY) {
            ICaveBiome entry = contents.get(index, null);

            if (entry == null) {
                return;
            }

            parent.drawCenteredString(parent.fontRendererObj, entry.getBiome().biomeName, width / 2, par3 + 3,
                    0xFFFFFF);

            if (parent.detailInfo.isChecked() || Keyboard.isKeyDown(Keyboard.KEY_TAB)) {
                BlockEntry block = entry.getTerrainBlock();

                if (Item.getItemFromBlock(block.getBlock()) != null) {
                    CaveUtils.renderItemStack(mc, new ItemStack(block.getBlock(), 1, block.getMetadata()),
                            width / 2 - 100, par3 + 1, true, Integer.toString(entry.getBiome().biomeID));
                }

                block = entry.getTopBlock();

                if (Item.getItemFromBlock(block.getBlock()) != null) {
                    CaveUtils.renderItemStack(mc,
                            new ItemStack(block.getBlock(), entry.getGenWeight(), block.getMetadata()),
                            width / 2 + 90, par3 + 1, true, null);
                }
            }
        }

        @Override
        protected void elementClicked(int index, boolean flag, int mouseX, int mouseY) {
            if (!parent.editMode) {
                selected = isSelected(index) ? null : contents.get(index, null);
            }
        }

        @Override
        protected boolean isSelected(int index) {
            return selected == contents.get(index, null);
        }

        protected void setFilter(final String filter) {
            new ForkJoinPool().execute(new RecursiveAction() {
                @Override
                protected void compute() {
                    List<ICaveBiome> result;

                    if (Strings.isNullOrEmpty(filter)) {
                        result = biomes;
                    } else {
                        if (!filterCache.containsKey(filter)) {
                            filterCache.put(filter,
                                    Lists.newArrayList(Collections2.filter(biomes, new BiomeFilter(filter))));
                        }

                        result = filterCache.get(filter);
                    }

                    if (!contents.equals(result)) {
                        contents.clear();
                        contents.addAll(result);
                    }
                }
            });
        }
    }

    public static class BiomeFilter implements Predicate<ICaveBiome> {
        private final String filter;

        public BiomeFilter(String filter) {
            this.filter = filter;
        }

        @Override
        public boolean apply(ICaveBiome entry) {
            return CaveUtils.biomeFilter(entry.getBiome(), filter)
                    || entry.getGenWeight() == NumberUtils.toInt(filter, -1)
                    || CaveUtils.blockFilter(entry.getTerrainBlock(), filter)
                    || CaveUtils.blockFilter(entry.getTopBlock(), filter);
        }
    }
}