com.kegare.caveworld.plugin.mceconomy.GuiShopEntry.java Source code

Java tutorial

Introduction

Here is the source code for com.kegare.caveworld.plugin.mceconomy.GuiShopEntry.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.plugin.mceconomy;

import java.io.File;
import java.io.IOException;
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.ItemStack;
import net.minecraft.util.EnumChatFormatting;

import org.apache.commons.io.FileUtils;
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.client.config.CaveConfigGui;
import com.kegare.caveworld.client.config.GuiSelectItem;
import com.kegare.caveworld.client.config.GuiSelectItem.SelectListener;
import com.kegare.caveworld.client.gui.GuiListSlot;
import com.kegare.caveworld.core.Caveworld;
import com.kegare.caveworld.plugin.mceconomy.ShopProductManager.ShopProduct;
import com.kegare.caveworld.util.ArrayListExtended;
import com.kegare.caveworld.util.CaveUtils;
import com.kegare.caveworld.util.ItemEntry;

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 GuiShopEntry extends GuiScreen implements SelectListener {
    protected final GuiScreen parentScreen;

    protected ProductList productList;

    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 itemField;
    protected GuiTextField damageField;
    protected GuiTextField stackField;
    protected GuiTextField costField;

    protected HoverChecker itemHoverChecker;
    protected HoverChecker stackHoverChecker;
    protected HoverChecker costHoverChecker;

    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 GuiShopEntry(GuiScreen parent) {
        this.parentScreen = parent;
    }

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

        if (productList == null) {
            productList = new ProductList(this);
        }

        productList.func_148122_a(width, height, 32, height - (editMode ? 90 : 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 = productList.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 + "shop.item"));
        editLabelList.add("");
        editLabelList.add(I18n.format(Caveworld.CONFIG_LANG + "shop.stackSize"));
        editLabelList.add(I18n.format(Caveworld.CONFIG_LANG + "shop.productCost"));

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

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

        int i = maxLabelWidth + 8 + width / 2;
        itemField.xPosition = width / 2 - i / 2 + maxLabelWidth + 10;
        itemField.yPosition = productList.bottom + 5;
        int fieldWidth = width / 2 + i / 2 - 45 - itemField.xPosition + 40;
        itemField.width = fieldWidth / 4 + fieldWidth / 2 - 1;

        if (damageField == null) {
            damageField = new GuiTextField(fontRendererObj, 0, 0, 0, itemField.height);
            damageField.setMaxStringLength(5);
        }

        damageField.xPosition = itemField.xPosition + itemField.width + 3;
        damageField.yPosition = itemField.yPosition;
        damageField.width = fieldWidth / 4 - 1;

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

        stackField.xPosition = itemField.xPosition;
        stackField.yPosition = itemField.yPosition + itemField.height + 5;
        stackField.width = fieldWidth;

        if (costField == null) {
            costField = new GuiTextField(fontRendererObj, 0, 0, 0, itemField.height);
        }

        costField.xPosition = stackField.xPosition;
        costField.yPosition = stackField.yPosition + stackField.height + 5;
        costField.width = fieldWidth;

        editFieldList.clear();

        if (editMode) {
            editFieldList.add(itemField);
            editFieldList.add(damageField);
            editFieldList.add(stackField);
            editFieldList.add(costField);
        }

        itemHoverChecker = new HoverChecker(itemField.yPosition - 1, itemField.yPosition + itemField.height,
                itemField.xPosition - maxLabelWidth - 12, itemField.xPosition - 10, 800);
        stackHoverChecker = new HoverChecker(stackField.yPosition - 1, stackField.yPosition + stackField.height,
                stackField.xPosition - maxLabelWidth - 12, stackField.xPosition - 10, 800);
        costHoverChecker = new HoverChecker(costField.yPosition - 1, costField.yPosition + costField.height,
                costField.xPosition - maxLabelWidth - 12, costField.xPosition - 10, 800);
    }

    @Override
    protected void actionPerformed(GuiButton button) {
        if (button.enabled) {
            switch (button.id) {
            case 0:
                if (editMode) {
                    if (Strings.isNullOrEmpty(itemField.getText())
                            || !GameData.getItemRegistry().containsKey(itemField.getText())
                            || NumberUtils.toInt(stackField.getText()) <= 0) {
                        return;
                    }

                    productList.selected.setProductItem(new ItemStack(
                            GameData.getItemRegistry().getObject(itemField.getText()),
                            NumberUtils.toInt(stackField.getText()), NumberUtils.toInt(damageField.getText())));
                    productList.selected.setCost(NumberUtils.toInt(costField.getText()));

                    hoverCache.remove(productList.selected);

                    actionPerformed(cancelButton);

                    productList.scrollToSelected();
                } else {
                    boolean flag = ShopProductManager.instance().getShopProducts().size() != productList.products
                            .size();

                    ShopProductManager.instance().getShopProducts().clear();

                    if (flag) {
                        try {
                            FileUtils.forceDelete(new File(MCEconomyPlugin.shopCfg.toString()));

                            MCEconomyPlugin.shopCfg.load();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }

                    for (ShopProduct product : productList.products) {
                        ShopProductManager.instance().addShopProduct(product);
                    }

                    if (MCEconomyPlugin.shopCfg.hasChanged()) {
                        MCEconomyPlugin.shopCfg.save();
                    }

                    actionPerformed(cancelButton);
                }

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

                    productList.scrollToSelected();

                    itemField.setText(GameData.getItemRegistry()
                            .getNameForObject(productList.selected.getProductItem().getItem()));
                    damageField.setText(Integer.toString(productList.selected.getProductItem().getItemDamage()));
                    stackField.setText(Integer.toString(productList.selected.getProductItem().stackSize));
                    costField.setText(Integer.toString(productList.selected.getcost()));
                }

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

                break;
            case 3:
                mc.displayGuiScreen(new GuiSelectItem(this));
                break;
            case 4:
                if (productList.products.remove(productList.selected)) {
                    int i = productList.contents.indexOf(productList.selected);

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

                break;
            case 5:
                for (Object obj : productList.products.toArray()) {
                    productList.selected = (ShopProduct) obj;

                    actionPerformed(removeButton);
                }

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

    @Override
    public void onSelected(ItemEntry entry) {
        if (!editMode) {
            ShopProduct product = new ShopProduct(entry.getItemStack(), 0);

            if (productList.products.addIfAbsent(product)) {
                productList.contents.addIfAbsent(product);
                productList.selected = product;

                editButton.enabled = true;
                actionPerformed(editButton);
            }
        }
    }

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

            filterTextField.updateCursorCounter();
        }
    }

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

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

        super.drawScreen(mouseX, mouseY, ticks);

        if (editMode) {
            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 (itemHoverChecker.checkHover(mouseX, mouseY)) {
                if (!hoverCache.containsKey(itemHoverChecker)) {
                    List<String> hover = Lists.newArrayList();
                    String key = Caveworld.CONFIG_LANG + "shop.item";
                    hover.add(EnumChatFormatting.GRAY + I18n.format(key));
                    hover.addAll(fontRendererObj.listFormattedStringToWidth(I18n.format(key + ".tooltip"), 300));

                    hoverCache.put(itemHoverChecker, hover);
                }

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

                    hoverCache.put(stackHoverChecker, hover);
                }

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

                    hoverCache.put(costHoverChecker, hover);
                }

                func_146283_a(hoverCache.get(costHoverChecker), 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 (productList.func_148141_e(mouseY) && isCtrlKeyDown()) {
            ShopProduct entry = productList.contents.get(productList.func_148124_c(mouseX, mouseY), null);

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

                    info.add(EnumChatFormatting.GRAY + I18n.format(Caveworld.CONFIG_LANG + "shop.item") + ": "
                            + GameData.getItemRegistry().getNameForObject(entry.getProductItem().getItem()) + ", "
                            + entry.getProductItem().getItemDamage());
                    info.add(EnumChatFormatting.GRAY + I18n.format(Caveworld.CONFIG_LANG + "shop.stackSize") + ": "
                            + entry.getProductItem().stackSize);
                    info.add(EnumChatFormatting.GRAY + I18n.format(Caveworld.CONFIG_LANG + "shop.productCost")
                            + ": " + entry.getcost());

                    hoverCache.put(entry, info);
                }

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

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

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

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

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

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

    @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 (itemField.isFocused()) {
                    itemField.setFocused(false);

                    mc.displayGuiScreen(new GuiSelectItem(this, itemField, damageField));
                }
            }
        } 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 (code == Keyboard.KEY_ESCAPE) {
                    textField.setFocused(false);
                } else if (textField.isFocused()) {
                    if (textField != itemField) {
                        if (!CharUtils.isAsciiControl(c) && !CharUtils.isAsciiNumeric(c)) {
                            continue;
                        }
                    }

                    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) {
                    productList.setFilter(null);
                } else if (instantFilter.isChecked() && changed || code == Keyboard.KEY_RETURN) {
                    productList.setFilter(text);
                }
            } else {
                if (code == Keyboard.KEY_ESCAPE) {
                    actionPerformed(doneButton);
                } else if (code == Keyboard.KEY_BACK) {
                    productList.selected = null;
                } else if (code == Keyboard.KEY_TAB) {
                    if (++productList.nameType > 2) {
                        productList.nameType = 0;
                    }
                } else if (code == Keyboard.KEY_UP) {
                    if (isCtrlKeyDown()) {
                        productList.contents.swapTo(productList.contents.indexOf(productList.selected), -1);
                        productList.products.swapTo(productList.products.indexOf(productList.selected), -1);

                        productList.scrollToSelected();
                    } else {
                        productList.scrollUp();
                    }
                } else if (code == Keyboard.KEY_DOWN) {
                    if (isCtrlKeyDown()) {
                        productList.contents.swapTo(productList.contents.indexOf(productList.selected), 1);
                        productList.products.swapTo(productList.products.indexOf(productList.selected), 1);

                        productList.scrollToSelected();
                    } else {
                        productList.scrollDown();
                    }
                } else if (code == Keyboard.KEY_HOME) {
                    productList.scrollToTop();
                } else if (code == Keyboard.KEY_END) {
                    productList.scrollToEnd();
                } else if (code == Keyboard.KEY_SPACE) {
                    productList.scrollToSelected();
                } else if (code == Keyboard.KEY_PRIOR) {
                    productList.scrollToPrev();
                } else if (code == Keyboard.KEY_NEXT) {
                    productList.scrollToNext();
                } else if (code == Keyboard.KEY_F || code == mc.gameSettings.keyBindChat.getKeyCode()) {
                    filterTextField.setFocused(true);
                } else if (code == Keyboard.KEY_DELETE && productList.selected != null) {
                    actionPerformed(removeButton);
                } else if (code == Keyboard.KEY_C && isCtrlKeyDown()) {
                    productList.copied = productList.selected == null ? null
                            : new ShopProduct(productList.selected.getProductItem(),
                                    productList.selected.getcost());
                } else if (code == Keyboard.KEY_X && isCtrlKeyDown()) {
                    keyTyped(Character.MIN_VALUE, Keyboard.KEY_C);
                    actionPerformed(removeButton);
                } else if (code == Keyboard.KEY_V && isCtrlKeyDown() && productList.copied != null) {
                    ShopProduct entry = new ShopProduct(productList.copied.getProductItem(),
                            productList.copied.getcost());

                    if (productList.products.addIfAbsent(entry)) {
                        productList.contents.addIfAbsent(entry);

                        if (productList.selected != null) {
                            productList.contents.swap(productList.contents.indexOf(productList.selected) + 1,
                                    productList.contents.size() - 1);
                            productList.products.swap(productList.products.indexOf(productList.selected) + 1,
                                    productList.products.size() - 1);
                        }

                        productList.selected = entry;
                        productList.scrollToSelected();
                    }
                }
            }
        }
    }

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

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

    protected static class ProductList extends GuiListSlot {
        protected final GuiShopEntry parent;

        protected final ArrayListExtended<ShopProduct> products = new ArrayListExtended(
                ShopProductManager.instance().getShopProducts());
        protected final ArrayListExtended<ShopProduct> contents = new ArrayListExtended(products);

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

        protected int nameType;
        protected ShopProduct selected;
        protected ShopProduct copied;

        private ProductList(GuiShopEntry 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) {
            ShopProduct entry = contents.get(index, null);

            if (entry == null) {
                return;
            }

            ItemStack itemstack = entry.getProductItem();
            String name = null;

            try {
                switch (nameType) {
                case 1:
                    name = GameData.getItemRegistry().getNameForObject(itemstack.getItem());
                    break;
                case 2:
                    name = itemstack.getUnlocalizedName();
                    name = name.substring(name.indexOf(".") + 1);
                    break;
                default:
                    name = itemstack.getDisplayName();
                    break;
                }
            } catch (Throwable e) {
            }

            if (!Strings.isNullOrEmpty(name)) {
                parent.drawCenteredString(parent.fontRendererObj, name, width / 2, par3 + 3, 0xFFFFFF);
            }

            if (parent.detailInfo.isChecked()) {
                CaveUtils.renderItemStack(mc, itemstack, width / 2 - 100, par3 + 1, true, null);

                name = Integer.toString(entry.getcost());
                parent.drawString(parent.fontRendererObj, name,
                        width / 2 + 107 - parent.fontRendererObj.getStringWidth(name), par3 + 8, 0xD0D0D0);
            }
        }

        @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<ShopProduct> result;

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

                        result = filterCache.get(filter);
                    }

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

    public static class ProductFilter implements Predicate<ShopProduct> {
        private final String filter;

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

        @Override
        public boolean apply(ShopProduct product) {
            return CaveUtils.itemFilter(product.getProductItem(), filter)
                    || product.getcost() == NumberUtils.toInt(filter, -1);
        }
    }
}