package codechicken.nei;
import codechicken.lib.gui.GuiDraw;
import codechicken.nei.KeyManager.IKeyStateTracker;
import codechicken.nei.api.*;
import codechicken.nei.guihook.*;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.gui.inventory.GuiContainerCreative;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.InventoryEffectRenderer;
import net.minecraft.inventory.Slot;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import org.lwjgl.opengl.GL11;
import java.util.HashMap;
import java.util.List;
import java.util.TreeSet;
import static codechicken.lib.gui.GuiDraw.*;
import static codechicken.nei.NEIClientConfig.*;
import static codechicken.nei.NEIClientUtils.*;
public class LayoutManager implements IContainerInputHandler, IContainerTooltipHandler, IContainerDrawHandler, IContainerObjectHandler, IKeyStateTracker
{
private static LayoutManager instance;
private static Widget inputFocused;
/**
* Sorted bottom first
*/
private static TreeSet<Widget> drawWidgets;
/**
* Sorted top first
*/
private static TreeSet<Widget> controlWidgets;
public static ItemPanel itemPanel;
public static SubsetWidget dropDown;
public static TextField searchField;
public static Button options;
public static Button prev;
public static Button next;
public static Label pageLabel;
public static Button more;
public static Button less;
public static ItemQuantityField quantity;
public static SaveLoadButton[] stateButtons;
public static Button[] deleteButtons;
public static Button delete;
public static ButtonCycled gamemode;
public static Button rain;
public static Button magnet;
public static Button[] timeButtons = new Button[4];
public static Button heal;
public static IRecipeOverlayRenderer overlayRenderer;
public static HashMap<Integer, LayoutStyle> layoutStyles = new HashMap<Integer, LayoutStyle>();
public static void load() {
API.addLayoutStyle(0, new LayoutStyleMinecraft());
API.addLayoutStyle(1, new LayoutStyleTMIOld());
instance = new LayoutManager();
KeyManager.trackers.add(instance);
GuiContainerManager.addInputHandler(instance);
GuiContainerManager.addTooltipHandler(instance);
GuiContainerManager.addDrawHandler(instance);
GuiContainerManager.addObjectHandler(instance);
init();
}
@Override
public void onPreDraw(GuiContainer gui) {
if (!isHidden() && isEnabled() && gui instanceof InventoryEffectRenderer)//Reset the gui to the center of the screen, for potion effect offsets etc
{
gui.guiLeft = (gui.width - gui.xSize) / 2;
gui.guiTop = (gui.height - gui.ySize) / 2;
if (gui instanceof GuiContainerCreative && gui.buttonList.size() >= 2) {
GuiButton button1 = (GuiButton) gui.buttonList.get(0);
GuiButton button2 = (GuiButton) gui.buttonList.get(1);
button1.xPosition = gui.guiLeft;
button2.xPosition = gui.guiLeft + gui.xSize - 20;
}
}
}
@Override
public void onMouseClicked(GuiContainer gui, int mousex, int mousey, int button) {
if (isHidden())
return;
for (Widget widget : controlWidgets)
widget.onGuiClick(mousex, mousey);
}
@Override
public boolean mouseClicked(GuiContainer gui, int mousex, int mousey, int button) {
if (isHidden())
return false;
if (!isEnabled())
return options.contains(mousex, mousey) && options.handleClick(mousex, mousey, button);
for (Widget widget : controlWidgets) {
widget.onGuiClick(mousex, mousey);
if (widget.contains(mousex, mousey) ? widget.handleClick(mousex, mousey, button) : widget.handleClickExt(mousex, mousey, button))
return true;
}
return false;
}
@Override
public boolean objectUnderMouse(GuiContainer gui, int mousex, int mousey) {
if (!isHidden() && isEnabled())
for (Widget widget : controlWidgets)
if (widget.contains(mousex, mousey))
return true;
return false;
}
public boolean keyTyped(GuiContainer gui, char keyChar, int keyID) {
if (isEnabled() && !isHidden()) {
if (inputFocused != null)
return inputFocused.handleKeyPress(keyID, keyChar);
for (Widget widget : controlWidgets)
if (widget.handleKeyPress(keyID, keyChar))
return true;
}
return false;
}
@Override
public void onKeyTyped(GuiContainer gui, char keyChar, int keyID) {
}
@Override
public boolean lastKeyTyped(GuiContainer gui, char keyChar, int keyID) {
if (keyID == getKeyBinding("gui.hide")) {
toggleBooleanSetting("inventory.hidden");
return true;
}
if (isEnabled() && !isHidden()) {
for (Widget widget : controlWidgets)
if (inputFocused == null)
widget.lastKeyTyped(keyID, keyChar);
}
return false;
}
public void onMouseUp(GuiContainer gui, int mx, int my, int button) {
if (!isHidden() && isEnabled()) {
for (Widget widget : controlWidgets)
widget.mouseUp(mx, my, button);
}
}
@Override
public void onMouseDragged(GuiContainer gui, int mx, int my, int button, long heldTime) {
if (!isHidden() && isEnabled()) {
for (Widget widget : controlWidgets)
widget.mouseDragged(mx, my, button, heldTime);
}
}
@Override
public ItemStack getStackUnderMouse(GuiContainer gui, int mousex, int mousey) {
if (!isHidden() && isEnabled()) {
for (Widget widget : controlWidgets) {
ItemStack stack = widget.getStackMouseOver(mousex, mousey);
if (stack != null)
return stack;
}
}
return null;
}
public void renderObjects(GuiContainer gui, int mousex, int mousey) {
if (!isHidden()) {
layout(gui);
if (isEnabled()) {
getLayoutStyle().drawBackground(GuiContainerManager.getManager(gui));
for (Widget widget : drawWidgets)
widget.draw(mousex, mousey);
} else {
options.draw(mousex, mousey);
}
GlStateManager.enableLighting();
GlStateManager.disableDepth();
}
}
@Override
public void postRenderObjects(GuiContainer gui, int mousex, int mousey) {
if (!isHidden() && isEnabled()) {
for (Widget widget : drawWidgets)
widget.postDraw(mousex, mousey);
}
}
@Override
public List<String> handleTooltip(GuiContainer gui, int mousex, int mousey, List<String> currenttip) {
if (!isHidden() && isEnabled() && GuiContainerManager.shouldShowTooltip(gui)) {
for (Widget widget : controlWidgets)
currenttip = widget.handleTooltip(mousex, mousey, currenttip);
}
return currenttip;
}
@Override
public List<String> handleItemDisplayName(GuiContainer gui, ItemStack stack, List<String> currenttip) {
String overridename = ItemInfo.getNameOverride(stack);
if (overridename != null)
currenttip.set(0, overridename);
String mainname = currenttip.get(0);
if (showIDs()) {
mainname += " " + Item.getIdFromItem(stack.getItem());
if (stack.getItemDamage() != 0)
mainname += ":" + stack.getItemDamage();
currenttip.set(0, mainname);
}
return currenttip;
}
@Override
public List<String> handleItemTooltip(GuiContainer gui, ItemStack itemstack, int mousex, int mousey, List<String> currenttip) {
return currenttip;
}
public static void layout(GuiContainer gui) {
VisiblityData visiblity = new VisiblityData();
if (isHidden())
visiblity.showNEI = false;
if (gui.height - gui.ySize <= 40)
visiblity.showSearchSection = false;
if (gui.guiLeft - 4 < 76)
visiblity.showWidgets = false;
for (INEIGuiHandler handler : GuiInfo.guiHandlers)
handler.modifyVisiblity(gui, visiblity);
visiblity.translateDependancies();
getLayoutStyle().layout(gui, visiblity);
updateWidgetVisiblities(gui, visiblity);
}
private static void init() {
itemPanel = new ItemPanel();
dropDown = new SubsetWidget();
searchField = new SearchField("search");
options = new Button("Options")
{
@Override
public boolean onButtonPress(boolean rightclick) {
if (!rightclick) {
getOptionList().openGui(getGuiContainer(), false);
return true;
}
return false;
}
@Override
public String getRenderLabel() {
return translate("inventory.options");
}
};
prev = new Button("Prev")
{
public boolean onButtonPress(boolean rightclick) {
if (!rightclick) {
LayoutManager.itemPanel.scroll(-1);
return true;
}
return false;
}
@Override
public String getRenderLabel() {
return translate("inventory.prev");
}
};
next = new Button("Next")
{
public boolean onButtonPress(boolean rightclick) {
if (!rightclick) {
LayoutManager.itemPanel.scroll(1);
return true;
}
return false;
}
@Override
public String getRenderLabel() {
return translate("inventory.next");
}
};
pageLabel = new Label("(0/0)", true);
more = new Button("+")
{
@Override
public boolean onButtonPress(boolean rightclick) {
if (rightclick)
return false;
int modifier = controlKey() ? 64 : shiftKey() ? 10 : 1;
int quantity = getItemQuantity() + modifier;
if (quantity < 0)
quantity = 0;
setItemQuantity(quantity);
return true;
}
};
less = new Button("-")
{
@Override
public boolean onButtonPress(boolean rightclick) {
if (rightclick)
return false;
int modifier = controlKey() ? -64 : shiftKey() ? -10 : -1;
int quantity = getItemQuantity() + modifier;
if (quantity < 0)
quantity = 0;
setItemQuantity(quantity);
return true;
}
};
quantity = new ItemQuantityField("quantity");
stateButtons = new SaveLoadButton[7];
deleteButtons = new Button[7];
for (int i = 0; i < 7; i++) {
final int savestate = i;
stateButtons[i] = new SaveLoadButton("")
{
@Override
public boolean onButtonPress(boolean rightclick) {
if (isStateSaved(savestate))
loadState(savestate);
else
saveState(savestate);
return true;
}
@Override
public void onTextChange() {
NBTTagCompound statelist = global.nbt.getCompoundTag("statename");
global.nbt.setTag("statename", statelist);
statelist.setString("" + savestate, label);
global.saveNBT();
}
};
deleteButtons[i] = new Button("x")
{
@Override
public boolean onButtonPress(boolean rightclick) {
if (!rightclick) {
clearState(savestate);
return true;
}
return false;
}
};
}
delete = new Button()
{
@Override
public boolean onButtonPress(boolean rightclick) {
if ((state & 0x3) == 2)
return false;
ItemStack held = getHeldItem();
if (held != null) {
if (shiftKey()) {
deleteHeldItem();
deleteItemsOfType(held);
} else if (rightclick)
decreaseSlotStack(-999);
else
deleteHeldItem();
} else if (shiftKey())
deleteEverything();
else
NEIController.toggleDeleteMode();
return true;
}
public String getButtonTip() {
if ((state & 0x3) != 2) {
if (shiftKey())
return translate("inventory.delete.inv");
if (NEIController.canUseDeleteMode())
return getStateTip("delete", state);
}
return null;
}
@Override
public void postDraw(int mousex, int mousey) {
if(contains(mousex, mousey) && getHeldItem() != null && (state & 0x3) != 2)
GuiDraw.drawTip(mousex + 9, mousey, translate("inventory.delete." + (shiftKey() ? "all" : "one"), GuiContainerManager.itemDisplayNameShort(getHeldItem())));
}
};
gamemode = new ButtonCycled()
{
@Override
public boolean onButtonPress(boolean rightclick) {
if (!rightclick) {
cycleGamemode();
return true;
}
return false;
}
public String getButtonTip() {
return translate("inventory.gamemode." + getNextGamemode());
}
};
gamemode.icons = new Image[3];
rain = new Button()
{
@Override
public boolean onButtonPress(boolean rightclick) {
if (handleDisabledButtonPress("rain", rightclick))
return true;
if (!rightclick) {
toggleRaining();
return true;
}
return false;
}
public String getButtonTip() {
return getStateTip("rain", state);
}
};
magnet = new Button()
{
@Override
public boolean onButtonPress(boolean rightclick) {
if (!rightclick) {
toggleMagnetMode();
return true;
}
return false;
}
public String getButtonTip() {
return getStateTip("magnet", state);
}
};
for (int i = 0; i < 4; i++) {
final int zone = i;
timeButtons[i] = new Button()
{
@Override
public boolean onButtonPress(boolean rightclick) {
if (handleDisabledButtonPress(NEIActions.timeZones[zone], rightclick))
return true;
if (!rightclick) {
setHourForward(zone * 6);
return true;
}
return false;
}
@Override
public String getButtonTip() {
return getTimeTip(NEIActions.timeZones[zone], state);
}
};
}
heal = new Button()
{
@Override
public boolean onButtonPress(boolean rightclick) {
if (!rightclick) {
healPlayer();
return true;
}
return false;
}
@Override
public String getButtonTip() {
return translate("inventory.heal");
}
};
delete.state |= 0x4;
gamemode.state |= 0x4;
rain.state |= 0x4;
magnet.state |= 0x4;
}
private static String getStateTip(String name, int state) {
String sfx = (state & 0x3) == 2 ? "enable" :
(state & 0x3) == 1 ? "0" : "1";
return translate("inventory." + name + "." + sfx);
}
private static String getTimeTip(String name, int state) {
String sfx = (state & 0x3) == 2 ? "enable" : "set";
return translate("inventory." + name + "." + sfx);
}
private static boolean handleDisabledButtonPress(String ident, boolean rightclick) {
if (!NEIActions.canDisable.contains(ident))
return false;
if (rightclick != disabledActions.contains(ident))
return setPropertyDisabled(ident, rightclick);
return false;
}
private static boolean setPropertyDisabled(String ident, boolean disable) {
if (disable && NEIActions.base(ident).equals("time")) {
int count = 0;
for (int i = 0; i < 4; i++) {
if (disabledActions.contains(NEIActions.timeZones[i]))
count++;
}
if (count == 3)
return false;
}
if (hasSMPCounterPart())
NEICPH.sendSetPropertyDisabled(ident, disable);
return true;
}
@Override
public void load(GuiContainer gui) {
if (isEnabled()) {
setInputFocused(null);
ItemList.loadItems.restart();
overlayRenderer = null;
getLayoutStyle().init();
layout(gui);
}
NEIController.load(gui);
if (checkCreativeInv(gui) && gui.mc.currentScreen instanceof GuiContainerCreative)//override creative with creative+
gui.mc.displayGuiScreen(null);//close the screen and wait for the server to open it for us
}
@Override
public void refresh(GuiContainer gui) {
}
public boolean checkCreativeInv(GuiContainer gui) {
if (gui instanceof GuiContainerCreative && invCreativeMode()) {
NEICPH.sendCreativeInv(true);
return true;
} else if (gui instanceof GuiExtendedCreativeInv && !invCreativeMode()) {
NEICPH.sendCreativeInv(false);
return true;
}
return false;
}
public static void updateWidgetVisiblities(GuiContainer gui, VisiblityData visiblity) {
drawWidgets = new TreeSet<Widget>(new WidgetZOrder(false));
controlWidgets = new TreeSet<Widget>(new WidgetZOrder(true));
if (!visiblity.showNEI)
return;
addWidget(options);
if (visiblity.showItemPanel) {
addWidget(itemPanel);
addWidget(prev);
addWidget(next);
addWidget(pageLabel);
if (canPerformAction("item")) {
addWidget(more);
addWidget(less);
addWidget(quantity);
}
}
if (visiblity.showSearchSection) {
addWidget(dropDown);
addWidget(searchField);
}
if (canPerformAction("item") && hasSMPCounterPart() && visiblity.showStateButtons) {
for (int i = 0; i < 7; i++) {
addWidget(stateButtons[i]);
if (isStateSaved(i))
addWidget(deleteButtons[i]);
}
}
if (visiblity.showUtilityButtons) {
if (canPerformAction("time")) {
for (int i = 0; i < 4; i++)
addWidget(timeButtons[i]);
}
if (canPerformAction("rain"))
addWidget(rain);
if (canPerformAction("heal"))
addWidget(heal);
if (canPerformAction("magnet"))
addWidget(magnet);
if (isValidGamemode("creative") ||
isValidGamemode("creative+") ||
isValidGamemode("adventure"))
addWidget(gamemode);
if (canPerformAction("delete"))
addWidget(delete);
}
}
public static LayoutStyle getLayoutStyle(int id) {
LayoutStyle style = layoutStyles.get(id);
if (style == null)
style = layoutStyles.get(0);
return style;
}
public static LayoutStyle getLayoutStyle() {
return getLayoutStyle(NEIClientConfig.getLayoutStyle());
}
private static void addWidget(Widget widget) {
drawWidgets.add(widget);
controlWidgets.add(widget);
}
@Override
public void guiTick(GuiContainer gui) {
if (checkCreativeInv(gui))
return;
if (!isEnabled())
return;
for (Widget widget : controlWidgets)
widget.update();
}
@Override
public boolean mouseScrolled(GuiContainer gui, int mousex, int mousey, int scrolled) {
if (isHidden() || !isEnabled())
return false;
for (Widget widget : controlWidgets)
if (widget.onMouseWheel(scrolled, mousex, mousey))
return true;
return false;
}
@Override
public void onMouseScrolled(GuiContainer gui, int mousex, int mousey, int scrolled) {
}
@Override
public boolean shouldShowTooltip(GuiContainer gui) {
return itemPanel.draggedStack == null;
}
public static Widget getInputFocused() {
return inputFocused;
}
public static void setInputFocused(Widget widget) {
if (inputFocused != null)
inputFocused.loseFocus();
inputFocused = widget;
if (inputFocused != null)
inputFocused.gainFocus();
}
@Override
public void renderSlotUnderlay(GuiContainer gui, Slot slot) {
if (overlayRenderer != null)
overlayRenderer.renderOverlay(GuiContainerManager.getManager(gui), slot);
}
@Override
public void renderSlotOverlay(GuiContainer window, Slot slot) {
ItemStack item = slot.getStack();
if (world.nbt.getBoolean("searchinventories") && (item == null ? !getSearchExpression().equals("") : !ItemList.itemMatches(item))) {
GlStateManager.disableLighting();
GlStateManager.translate(0, 0, 150);
drawRect(slot.xDisplayPosition, slot.yDisplayPosition, 16, 16, 0x80000000);
GlStateManager.translate(0, 0, -150);
GlStateManager.enableLighting();
}
}
public static void drawIcon(int x, int y, Image image) {
changeTexture("nei:textures/nei_sprites.png");
GlStateManager.color(1, 1, 1, 1);
GlStateManager.enableBlend();
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
drawTexturedModalRect(x, y, image.x, image.y, image.width, image.height);
GlStateManager.disableBlend();
}
public static void drawButtonBackground(int x, int y, int w, int h, boolean edges, int type) {
int wtiles = 0;
int ew = w;//end width
if (w / 2 > 100) {
wtiles = (w - 200) / 50 + 1;
ew = 200;
}
int w1 = ew / 2;
int h1 = h / 2;
int w2 = (ew + 1) / 2;
int h2 = (h + 1) / 2;
int x2 = x + w - w2;
int y2 = y + h - h2;
int ty = 46 + type * 20;
int te = (edges ? 0 : 1);//tex edges
int ty1 = ty + te;
int tx1 = te;
int tx3 = 75;
//halfway the 1 is for odd number adjustment
int ty2 = ty + 20 - h2 - te;
int tx2 = 200 - w2 - te;
changeTexture("textures/gui/widgets.png");
drawTexturedModalRect(x, y, tx1, ty1, w1, h1);//top left
drawTexturedModalRect(x, y2, tx1, ty2, w1, h2);//bottom left
for (int tile = 0; tile < wtiles; tile++) {
int tilex = x + w1 + 50 * tile;
drawTexturedModalRect(tilex, y, tx3, ty1, 50, h1);//top
drawTexturedModalRect(tilex, y2, tx3, ty2, 50, h2);//bottom
}
drawTexturedModalRect(x2, y, tx2, ty1, w2, h1);//top right
drawTexturedModalRect(x2, y2, tx2, ty2, w2, h2);//bottom right
}
public static LayoutManager instance() {
return instance;
}
@Override
public void tickKeyStates() {
if (Minecraft.getMinecraft().currentScreen != null)
return;
if (KeyManager.keyStates.get("world.dawn").down)
timeButtons[0].onButtonPress(false);
if (KeyManager.keyStates.get("world.noon").down)
timeButtons[1].onButtonPress(false);
if (KeyManager.keyStates.get("world.dusk").down)
timeButtons[2].onButtonPress(false);
if (KeyManager.keyStates.get("world.midnight").down)
timeButtons[3].onButtonPress(false);
if (KeyManager.keyStates.get("world.rain").down)
rain.onButtonPress(false);
if (KeyManager.keyStates.get("world.heal").down)
heal.onButtonPress(false);
if (KeyManager.keyStates.get("world.creative").down)
gamemode.onButtonPress(false);
}
}