package crazypants.enderio.machine.invpanel;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import net.minecraft.client.Minecraft;
import net.minecraft.client.audio.PositionedSoundRecord;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.opengl.GL11;
import codechicken.nei.LayoutManager;
import com.enderio.core.client.gui.button.IconButton;
import com.enderio.core.client.gui.button.MultiIconButton;
import com.enderio.core.client.gui.button.ToggleButton;
import com.enderio.core.client.gui.widget.GhostSlot;
import com.enderio.core.client.gui.widget.GuiToolTip;
import com.enderio.core.client.gui.widget.TextFieldEnder;
import com.enderio.core.client.gui.widget.VScrollbar;
import com.enderio.core.client.handlers.SpecialTooltipHandler;
import com.enderio.core.client.render.EnderWidget;
import com.enderio.core.client.render.RenderUtil;
import com.enderio.core.common.Lang;
import com.enderio.core.common.util.ItemUtil;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import crazypants.enderio.EnderIO;
import crazypants.enderio.config.Config;
import crazypants.enderio.fluid.Fluids;
import crazypants.enderio.gui.IconEIO;
import crazypants.enderio.machine.enchanter.ContainerEnchanter;
import crazypants.enderio.machine.gui.GuiMachineBase;
import crazypants.enderio.machine.invpanel.client.CraftingHelper;
import crazypants.enderio.machine.invpanel.client.DatabaseView;
import crazypants.enderio.machine.invpanel.client.InventoryDatabaseClient;
import crazypants.enderio.machine.invpanel.client.ItemEntry;
import crazypants.enderio.machine.invpanel.client.SortOrder;
import crazypants.enderio.network.PacketHandler;
import crazypants.enderio.tool.SmartTank;
@SideOnly(Side.CLIENT)
public class GuiInventoryPanel extends GuiMachineBase<TileInventoryPanel> {
private static final Rectangle inventoryArea = new Rectangle(24+107, 27, 108, 90);
private static final Rectangle btnRefill = new Rectangle(24+85, 32, 20, 20);
private static final Rectangle btnReturnArea = new Rectangle(24+6, 72, 5 * 18, 8);
private static final int ID_SORT = 9876;
private static final int ID_CLEAR = 9877;
private static final int ID_SYNC = 9878;
private static final int GHOST_COLUMNS = 6;
private static final int GHOST_ROWS = 5;
private final DatabaseView view;
private final TextFieldEnder tfFilter;
private final IconButton btnSort;
private final ToggleButton btnSync;
private final GuiToolTip ttRefill;
private final VScrollbar scrollbar;
private final MultiIconButton btnClear;
private final GuiToolTip ttSetReceipe;
private int scrollPos;
private int ghostSlotTooltipStacksize;
private final String headerCrafting;
private final String headerReturn;
private final String headerStorage;
private final String headerInventory;
private final String infoTextFilter;
private final String infoTextOffline;
private CraftingHelper craftingHelper;
private final Rectangle btnAddStoredRecipe = new Rectangle();
public GuiInventoryPanel(TileInventoryPanel te, Container container) {
super(te, container, "inventorypanel");
redstoneButton.visible = false;
configB.visible = false;
for (int y = 0; y < GHOST_ROWS; y++) {
for (int x = 0; x < GHOST_COLUMNS; x++) {
ghostSlots.add(new InvSlot(24 + 108 + x * 18, 28 + y * 18));
}
}
for (int i = 0; i < TileInventoryPanel.MAX_STORED_CRAFTING_RECIPES; i++) {
ghostSlots.add(new RecipeSlot(i, 7, 7 + i * 20));
}
this.view = new DatabaseView();
int sortMode = te.getGuiSortMode();
int sortOrderIdx = sortMode >> 1;
SortOrder[] orders = SortOrder.values();
if(sortOrderIdx >= 0 && te.getGuiSortMode() < orders.length) {
view.setSortOrder(orders[sortOrderIdx], (sortMode & 1) != 0);
}
FontRenderer fr = Minecraft.getMinecraft().fontRenderer;
btnSync = new ToggleButton(this, ID_SYNC, 24 + 233, 46, IconEIO.CROSS, IconEIO.TICK);
btnSync.setToolTip(EnderIO.lang.localize("gui.inventorypanel.tooltip.sync"));
btnSync.setSelectedToolTip(EnderIO.lang.localize("gui.enabled"));
btnSync.setUnselectedToolTip(EnderIO.lang.localize("gui.disabled"));
btnSync.setSelected(getTileEntity().getGuiSync());
if (!Loader.isModLoaded("NotEnoughItems")) {
btnSync.enabled = false;
}
tfFilter = new TextFieldEnder(fr, 24+108, 11, 106, 10);
tfFilter.setEnableBackgroundDrawing(false);
setText(tfFilter, te.getGuiFilterString());
btnSort = new IconButton(this, ID_SORT, 24+233, 27, getSortOrderIcon()) {
@Override
public boolean mousePressed(Minecraft mc, int x, int y) {
return mousePressedButton(mc, x, y, 0);
}
@Override
public boolean mousePressedButton(Minecraft mc, int x, int y, int button) {
if(button <= 1 && super.checkMousePress(mc, x, y)) {
toggleSortOrder(button == 0);
return true;
}
return false;
}
};
scrollbar = new VScrollbar(this, 24+215, 27, 90);
btnClear = new MultiIconButton(this, ID_CLEAR, 24+65, 60, EnderWidget.X_BUT, EnderWidget.X_BUT_PRESSED, EnderWidget.X_BUT_HOVER);
textFields.add(tfFilter);
headerCrafting = EnderIO.lang.localize("gui.inventorypanel.header.crafting");
headerReturn = EnderIO.lang.localize("gui.inventorypanel.header.return");
headerStorage = EnderIO.lang.localize("gui.inventorypanel.header.storage");
headerInventory = EnderIO.lang.localizeExact("container.inventory");
infoTextFilter = EnderIO.lang.localize("gui.inventorypanel.info.filter");
infoTextOffline = EnderIO.lang.localize("gui.inventorypanel.info.offline");
ArrayList<String> list = new ArrayList<String>();
SpecialTooltipHandler.addTooltipFromResources(list, "enderio.gui.inventorypanel.tooltip.return.line");
addToolTip(new GuiToolTip(btnReturnArea, list) {
@Override
public boolean shouldDraw() {
return super.shouldDraw() && !getTileEntity().isExtractionDisabled();
}
});
list.clear();
SpecialTooltipHandler.addTooltipFromResources(list, "enderio.gui.inventorypanel.tooltip.storage.line");
addToolTip(new GuiToolTip(btnReturnArea, list) {
@Override
public boolean shouldDraw() {
return super.shouldDraw() && getTileEntity().isExtractionDisabled();
}
});
list.clear();
SpecialTooltipHandler.addTooltipFromResources(list, "enderio.gui.inventorypanel.tooltip.filterslot.line");
addToolTip(new GuiToolTip(new Rectangle(InventoryPanelContainer.FILTER_SLOT_X, InventoryPanelContainer.FILTER_SLOT_Y, 16, 16), list) {
@Override
public boolean shouldDraw() {
return !getContainer().getSlotFilter().getHasStack() && super.shouldDraw();
}
});
list.clear();
SpecialTooltipHandler.addTooltipFromResources(list, "enderio.gui.inventorypanel.tooltip.refill.line");
ttRefill = new GuiToolTip(btnRefill, list);
ttRefill.setVisible(false);
addToolTip(ttRefill);
list.clear();
SpecialTooltipHandler.addTooltipFromResources(list, "enderio.gui.inventorypanel.tooltip.setrecipe.line");
ttSetReceipe = new GuiToolTip(btnRefill, list) {
@Override
public boolean shouldDraw() {
return super.shouldDraw() && getContainer().hasCraftingRecipe();
}
};
addToolTip(ttSetReceipe);
list.clear();
SpecialTooltipHandler.addTooltipFromResources(list, "enderio.gui.inventorypanel.tooltip.clear.line");
btnClear.setToolTip(list.toArray(new String[list.size()]));
if (!Config.inventoryPanelFree) {
addToolTip(new GuiToolTip(new Rectangle(36, 133, 16, 47), "") {
@Override
protected void updateText() {
text.clear();
text.add(EnderIO.lang.localize("gui.inventorypanel.tooltip.fuelTank"));
text.add(Fluids.toCapactityString(getTileEntity().fuelTank));
}
});
}
list.clear();
SpecialTooltipHandler.addTooltipFromResources(list, "enderio.gui.inventorypanel.tooltip.addrecipe.line");
addToolTip(new GuiToolTip(btnAddStoredRecipe, list));
}
@Override
public void onGuiClosed() {
int sortMode = (view.getSortOrder().ordinal() << 1);
if(view.isSortOrderInverted()) {
sortMode |= 1;
}
getTileEntity().setGuiParameter(sortMode, tfFilter.getText(), btnSync.isSelected());
super.onGuiClosed();
}
public void setCraftingHelper(CraftingHelper craftingHelper) {
if(this.craftingHelper != null) {
this.craftingHelper.remove();
}
this.craftingHelper = craftingHelper;
ttRefill.setVisible(craftingHelper != null);
ttSetReceipe.setVisible(craftingHelper == null);
if(craftingHelper != null) {
craftingHelper.install();
}
}
public void fillFromStoredRecipe(int index, boolean shift) {
StoredCraftingRecipe recipe = getTileEntity().getStoredCraftingRecipe(index);
if(recipe == null) {
return;
}
if(getContainer().clearCraftingGrid()) {
CraftingHelper helper = CraftingHelper.createFromRecipe(recipe);
setCraftingHelper(helper);
helper.refill(this, shift ? 64 : 1);
}
}
@Override
public void initGui() {
super.initGui();
updateSortButton();
btnSort.onGuiInit();
btnClear.onGuiInit();
btnSync.onGuiInit();
addScrollbar(scrollbar);
((InventoryPanelContainer) inventorySlots).createGhostSlots(getGhostSlots());
}
@Override
public void actionPerformed(GuiButton b) {
super.actionPerformed(b);
if (b.id == ID_CLEAR) {
if (getContainer().clearCraftingGrid()) {
setCraftingHelper(null);
}
} else if (b.id == ID_SYNC) {
if (Loader.isModLoaded("NotEnoughItems")) {
updateNEI(((ToggleButton) b).isSelected() ? tfFilter.getText() : "");
}
}
}
@Override
protected void drawGuiContainerBackgroundLayer(float par1, int mouseX, int mouseY) {
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
bindGuiTexture();
int sx = guiLeft;
int sy = guiTop;
drawTexturedModalRect(sx + 24, sy, 0, 0, 232, ySize);
drawTexturedModalRect(sx + 24 + 232, sy, 232, 0, 24, 68);
if(craftingHelper != null) {
boolean hover = btnRefill.contains(mouseX - sx, mouseY - sy);
int iconX = hover ? (isShiftKeyDown() ? 48 : 24) : 0;
drawTexturedModalRect(sx + btnRefill.x - 2, sy + btnRefill.y - 2, iconX, 232, 24, 24);
} else if(getContainer().hasCraftingRecipe()) {
boolean hover = btnRefill.contains(mouseX - sx, mouseY - sy);
int iconX = hover ? 96 : 72;
drawTexturedModalRect(sx + btnRefill.x - 2, sy + btnRefill.y - 2, iconX, 232, 24, 24);
}
TileInventoryPanel te = getTileEntity();
int y = sy;
int numStoredRecipes = te.getStoredCraftingRecipes();
if(numStoredRecipes == 1) {
drawTexturedModalRect(sx, y, 227, 225, 28, 30); y += 30;
} else if(numStoredRecipes > 1) {
drawTexturedModalRect(sx, y, 227, 225, 28, 24); y += 24;
for(int i = 1; i < numStoredRecipes - 1; i++) {
drawTexturedModalRect(sx, y, 198, 229, 28, 20); y += 20;
}
drawTexturedModalRect(sx, y, 198, 229, 28, 26); y += 26;
}
if(numStoredRecipes < TileInventoryPanel.MAX_STORED_CRAFTING_RECIPES && getContainer().hasNewCraftingRecipe()) {
y += 2;
btnAddStoredRecipe.x = 13;
btnAddStoredRecipe.y = y - sy;
btnAddStoredRecipe.width = 12;
btnAddStoredRecipe.height = 14;
boolean hover = btnAddStoredRecipe.contains(mouseX - sx, mouseY - sy);
drawTexturedModalRect(sx + 13, y, 182, hover ? 241 : 225, 15, 14);
} else {
btnAddStoredRecipe.width = 0;
btnAddStoredRecipe.height = 0;
}
SmartTank fuelTank = te.fuelTank;
if (!Config.inventoryPanelFree) {
drawTexturedModalRect(sx + 35, sy + 132, 232, 163, 18, 49);
if (fuelTank.getFluidAmount() > 0) {
RenderUtil.renderGuiTank(fuelTank.getFluid(), fuelTank.getCapacity(), fuelTank.getFluidAmount(), sx + 24 + 12, sy + 132, zLevel, 16, 47);
}
}
int headerColor = 0x404040;
int focusedColor = 0x648494;
FontRenderer fr = getFontRenderer();
fr.drawString(headerCrafting, sx + 24 + 7, sy + 6, headerColor);
fr.drawString(te.isExtractionDisabled() ? headerStorage : headerReturn, sx + 24 + 7, sy + 72,
btnReturnArea.contains(mouseX - sx, mouseY - sy) ? focusedColor : headerColor);
fr.drawString(headerInventory, sx + 24 + 38, sy + 120, headerColor);
super.drawGuiContainerBackgroundLayer(par1, mouseX, mouseY);
view.setDatabase(getDatabase());
view.setItemFilter(te.getItemFilter());
view.updateFilter(tfFilter.getText());
boolean update = view.sortItems();
scrollbar.setScrollMax(Math.max(0, (view.getNumEntries() + GHOST_COLUMNS - 1) / GHOST_COLUMNS - GHOST_ROWS));
if(update || scrollPos != scrollbar.getScrollPos()) {
updateGhostSlots();
}
if(te.isActive()) {
tfFilter.setEnabled(true);
if(!tfFilter.isFocused() && tfFilter.getText().isEmpty()) {
fr.drawString(infoTextFilter, tfFilter.xPosition, tfFilter.yPosition, 0x707070);
}
} else {
tfFilter.setEnabled(false);
setText(tfFilter, "");
fr.drawString(infoTextOffline, tfFilter.xPosition, tfFilter.yPosition, 0x707070);
}
}
@Override
protected void onTextFieldChanged(TextFieldEnder tf, String old) {
if (tf == tfFilter && btnSync.isSelected() && tfFilter.isFocused() && Loader.isModLoaded("NotEnoughItems")) {
updateNEI(tfFilter.getText());
}
}
private void updateNEI(String text) {
LayoutManager.searchField.setText(text);
}
@Override
protected void drawFakeItemStack(int x, int y, ItemStack stack) {
FontRenderer font = stack.getItem().getFontRenderer(stack);
if(font == null) {
font = fontRendererObj;
}
String str = null;
if(stack.stackSize >= 1000) {
int value = stack.stackSize / 1000;
String unit = "k";
if(value >= 1000) {
value /= 1000;
unit = "m";
}
str = value + unit;
} else if(stack.stackSize > 1) {
str = Integer.toString(stack.stackSize);
}
itemRender.renderItemAndEffectIntoGUI(font, mc.renderEngine, stack, x, y);
if(str != null) {
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glDisable(GL11.GL_DEPTH_TEST);
GL11.glDisable(GL11.GL_BLEND);
GL11.glPushMatrix();
GL11.glTranslatef(x + 16, y + 16, 0);
font.drawStringWithShadow(str, 1 - font.getStringWidth(str), -8, 0xFFFFFF);
GL11.glPopMatrix();
GL11.glEnable(GL11.GL_LIGHTING);
GL11.glEnable(GL11.GL_DEPTH_TEST);
}
itemRender.renderItemOverlayIntoGUI(font, mc.renderEngine, stack, x, y, "");
}
@Override
protected void drawGhostSlotTooltip(GhostSlot slot, int mouseX, int mouseY) {
ItemStack stack = slot.getStack();
if(stack != null) {
ghostSlotTooltipStacksize = stack.stackSize;
try {
renderToolTip(stack, mouseX, mouseY);
} finally {
ghostSlotTooltipStacksize = 0;
}
}
}
@Override
public void drawHoveringText(List list, int mouseX, int mouseY, FontRenderer font) {
if(ghostSlotTooltipStacksize >= 1000) {
list.add(EnumChatFormatting.WHITE + EnderIO.lang.localize("gui.inventorypanel.tooltip.itemsstored", Integer.toString(ghostSlotTooltipStacksize)));
}
super.drawHoveringText(list, mouseX, mouseY, font);
}
public InventoryPanelContainer getContainer() {
return (InventoryPanelContainer) inventorySlots;
}
public InventoryDatabaseClient getDatabase() {
return getTileEntity().getDatabaseClient();
}
private IconEIO getSortOrderIcon() {
SortOrder order = view.getSortOrder();
boolean invert = view.isSortOrderInverted();
switch (order) {
case NAME:
return invert ? IconEIO.SORT_NAME_UP : IconEIO.SORT_NAME_DOWN;
case COUNT:
return invert ? IconEIO.SORT_SIZE_UP : IconEIO.SORT_SIZE_DOWN;
case MOD:
return invert ? IconEIO.SORT_MOD_UP : IconEIO.SORT_MOD_DOWN;
default:
return null;
}
}
void toggleSortOrder(boolean next) {
SortOrder order = view.getSortOrder();
SortOrder[] values = SortOrder.values();
int idx = order.ordinal();
if(next && view.isSortOrderInverted()) {
order = values[(idx + 1) % values.length];
} else if(!next && !view.isSortOrderInverted()) {
if(idx == 0) {
idx = values.length;
}
order = values[idx - 1];
}
view.setSortOrder(order, !view.isSortOrderInverted());
updateSortButton();
}
private void updateSortButton() {
SortOrder order = view.getSortOrder();
ArrayList<String> list = new ArrayList<String>();
SpecialTooltipHandler.addTooltipFromResources(list,
"enderio.gui.inventorypanel.tooltip.sort." + order.name().toLowerCase(Locale.US) + (view.isSortOrderInverted() ? "_up" : "_down") + ".line");
btnSort.setIcon(getSortOrderIcon());
btnSort.setToolTip(list.toArray(new String[list.size()]));
}
private void updateGhostSlots() {
scrollPos = scrollbar.getScrollPos();
int index = scrollPos * GHOST_COLUMNS;
int count = view.getNumEntries();
for (int i = 0; i < GHOST_ROWS * GHOST_COLUMNS; i++, index++) {
InvSlot slot = (InvSlot) ghostSlots.get(i);
if(index < count) {
slot.entry = view.getItemEntry(index);
slot.stack = slot.entry.makeItemStack();
} else {
slot.entry = null;
slot.stack = null;
}
}
}
@Override
protected boolean showRecipeButton() {
return false;
}
@Override
public int getXSize() {
return 280;
}
@Override
public int getYSize() {
return 212;
}
@Override
protected void mouseClicked(int x, int y, int button) {
super.mouseClicked(x, y, button);
x -= guiLeft;
y -= guiTop;
if(btnRefill.contains(x, y)) {
if(craftingHelper != null) {
playClickSound();
craftingHelper.refill(this, isShiftKeyDown() ? 64 : 1);
} else if(getContainer().hasCraftingRecipe()) {
playClickSound();
setCraftingHelper(CraftingHelper.createFromSlots(getContainer().getCraftingGridSlots()));
}
}
if(btnAddStoredRecipe.contains(x, y)) {
TileInventoryPanel te = getTileEntity();
if(te.getStoredCraftingRecipes() < TileInventoryPanel.MAX_STORED_CRAFTING_RECIPES && getContainer().hasNewCraftingRecipe()) {
StoredCraftingRecipe recipe = new StoredCraftingRecipe();
if(recipe.loadFromCraftingGrid(getContainer().getCraftingGridSlots())) {
playClickSound();
te.addStoredCraftingRecipe(recipe);
}
}
}
if(btnReturnArea.contains(x, y)) {
TileInventoryPanel te = getTileEntity();
playClickSound();
te.setExtractionDisabled(!te.isExtractionDisabled());
}
}
private void playClickSound() {
mc.getSoundHandler().playSound(PositionedSoundRecord.func_147674_a(new ResourceLocation("gui.button.press"), 1.0F));
}
@Override
protected void mouseWheel(int x, int y, int delta) {
super.mouseWheel(x, y, delta);
if(draggingScrollbar == null) {
x -= guiLeft;
y -= guiTop;
boolean shift = isShiftKeyDown();
if(inventoryArea.contains(x, y)) {
if(!shift) {
scrollbar.scrollBy(-Integer.signum(delta));
} else if(hoverGhostSlot instanceof InvSlot) {
InvSlot invSlot = (InvSlot) hoverGhostSlot;
InventoryDatabaseClient db = getDatabase();
if(invSlot.stack != null && invSlot.entry != null && db != null) {
ItemStack itemStack = mc.thePlayer.inventory.getItemStack();
if (itemStack == null || ItemUtil.areStackMergable(itemStack, invSlot.stack)) {
PacketHandler.INSTANCE.sendToServer(new PacketFetchItem(db.getGeneration(), invSlot.entry, -1, 1));
}
}
}
}
}
}
@Override
protected void ghostSlotClicked(GhostSlot slot, int x, int y, int button) {
if(slot instanceof InvSlot) {
InvSlot invSlot = (InvSlot) slot;
InventoryDatabaseClient db = getDatabase();
if(invSlot.entry != null && invSlot.stack != null && db != null) {
int targetSlot;
int count = Math.min(invSlot.stack.stackSize, invSlot.stack.getMaxStackSize());
if(button == 0) {
if(isShiftKeyDown()) {
InventoryPlayer playerInv = mc.thePlayer.inventory;
targetSlot = playerInv.getFirstEmptyStack();
if(targetSlot >= 0) {
targetSlot = getContainer().getSlotIndex(playerInv, targetSlot);
}
if(targetSlot < 0) {
return;
}
} else {
targetSlot = -1;
}
} else if(button == 1) {
targetSlot = -1;
if(isCtrlKeyDown()) {
count = 1;
} else {
count = (count + 1) / 2;
}
} else {
return;
}
PacketHandler.INSTANCE.sendToServer(new PacketFetchItem(db.getGeneration(), invSlot.entry, targetSlot, count));
}
} else if(slot instanceof RecipeSlot) {
RecipeSlot recipeSlot = (RecipeSlot) slot;
if(recipeSlot.isVisible()) {
if(button == 0) {
fillFromStoredRecipe(recipeSlot.index, isShiftKeyDown());
} else if(button == 1) {
getTileEntity().removeStoredCraftingRecipe(recipeSlot.index);
}
}
}
}
class InvSlot extends GhostSlot {
ItemEntry entry;
ItemStack stack;
InvSlot(int x, int y) {
this.x = x;
this.y = y;
this.grayOut = false;
this.stackSizeLimit = Integer.MAX_VALUE;
}
@Override
public ItemStack getStack() {
return stack;
}
}
class RecipeSlot extends GhostSlot {
final int index;
RecipeSlot(int index, int x, int y) {
this.index = index;
this.x = x;
this.y = y;
}
@Override
public ItemStack getStack() {
TileInventoryPanel te = getTileEntity();
StoredCraftingRecipe recipe = te.getStoredCraftingRecipe(index);
return recipe != null ? recipe.getResult(te) : null;
}
@Override
public boolean isVisible() {
return index < getTileEntity().getStoredCraftingRecipes();
}
}
}