package joshie.progression.gui.editors;
import joshie.progression.api.criteria.ICriteria;
import joshie.progression.api.criteria.ITab;
import joshie.progression.api.event.TabVisibleEvent;
import joshie.progression.gui.buttons.ButtonNewCriteria;
import joshie.progression.gui.buttons.ButtonTab;
import joshie.progression.gui.core.GuiCore;
import joshie.progression.gui.core.GuiList;
import joshie.progression.gui.editors.TreeEditorElement.ColorMode;
import joshie.progression.handlers.APICache;
import joshie.progression.handlers.RuleHandler;
import joshie.progression.helpers.MCClientHelper;
import joshie.progression.json.Options;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
import net.minecraftforge.common.MinecraftForge;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
import static joshie.progression.api.special.DisplayMode.DISPLAY;
import static joshie.progression.api.special.DisplayMode.EDIT;
import static joshie.progression.gui.core.GuiList.*;
public class GuiTreeEditor extends GuiBaseEditor implements IEditorMode {
private static final HashMap<ITab, Boolean> tabCache = new HashMap();
private HashMap<ICriteria, TreeEditorElement> elements;
public ICriteria selected = null;
public ICriteria previous = null;
public UUID currentTabID;
public ITab currentTab;
public int ticksExisted;
public GuiTreeEditor() {
features.add(BACKGROUND);
features.add(TREE_ELEMENT);
features.add(TEMPLATE_SELECTOR_TAB);
features.add(TEMPLATE_SELECTOR_CRITERIA);
}
@Override
public Object getKey() {
return currentTab;
}
@Override
public boolean hasButtons() {
return true;
}
public void addButtons(GuiCore core, boolean sideWays) {
List<GuiButton> buttonList = core.getButtonNewList(); //Recreate the button list, in order to reposition it
int position = 0;
int posY = -5;
if (MODE == EDIT) {
if (!sideWays) {
buttonList.add(new ButtonNewCriteria(0, posY));
posY += 28;
} else buttonList.add(new ButtonNewCriteria(posY + 10, -22).setSideways());
position++;
}
//Sort tabs alphabetically or by sort index
for (ITab tab : APICache.getCache(true).getSortedTabs()) {
if (isTabVisible(tab) || MODE == EDIT) {
if (!sideWays) {
if (position <= 8) {
buttonList.add(new ButtonTab(tab, 0, posY));
} else buttonList.add(new ButtonTab(tab, core.res.getScaledWidth() - 25, posY));
posY += 28;
if (position == 8) {
posY = -5;
}
position++;
} else {
boolean isEven = (position - 1) % 2 == 0;
if (!isEven) {
buttonList.add(new ButtonTab(tab, posY + 10, -22).setSideways());
} else {
buttonList.add(new ButtonTab(tab, posY + 10, core.ySize).setBottom().setSideways());
posY += 28;
}
position++;
}
}
}
}
public void onClientSetup() {
//Attempt to grab from the config
if (currentTabID == null) {
currentTabID = Options.getSettings().defaultTabID;
}
currentTab = APICache.getClientCache().getTab(currentTabID); //Attempt to grab the tab
//If the config fails, grab the first instance
if (currentTab == null) {
APICache.getClientCache().clearSorted();
for (ITab tab : APICache.getClientCache().getSortedTabs()) {
currentTabID = tab.getUniqueID();
break;
}
}
currentTab = APICache.getClientCache().getTab(currentTabID); //Attempt to grab the tab
if (currentTab == null) { //If the tab was null, create a new blank one
currentTab = RuleHandler.newTab(UUID.randomUUID(), true).setDisplayName("New Tab").setStack(new ItemStack(Items.BOOK)).setVisibility(true);
currentTabID = currentTab.getUniqueID();
}
}
@Override
public void initData() {
addButtons(CORE, APICache.getClientCache().getSortedTabs().size() > 17);
currentTab = APICache.getClientCache().getTab(currentTabID);
if (currentTab == null) {
MCClientHelper.getPlayer().closeScreen();
} else {
tabCache.clear();
rebuildCriteria();
}
}
public void rebuildCriteria() {
//Rebuild
elements = new HashMap();
for (ICriteria criteria : currentTab.getCriteria()) {
elements.put(criteria, new TreeEditorElement(criteria));
}
}
public TreeEditorElement getElement(ICriteria criteria) {
return elements.get(criteria);
}
public void addCriteria(ICriteria criteria, int x, int y, int offsetX) {
elements.put(criteria, new TreeEditorElement(criteria));
TreeEditorElement element = getElement(criteria);
if (element == null) {
element = new TreeEditorElement(criteria);
elements.put(criteria, element);
}
element.draw(x, y, offsetX);
element.click(x, y, false);
lastClicked = criteria;
}
public static boolean isTabVisible(ITab tab) { //Use the cached value, which we update everytime this gui is reopened
if (tabCache.containsKey(tab)) return tabCache.get(tab);
boolean result = tab.isVisible();
TabVisibleEvent event = new TabVisibleEvent(MCClientHelper.getPlayer(), tab.getUniqueID());
if (MinecraftForge.EVENT_BUS.post(event)) result = false;
tabCache.put(tab, result);
return result;
}
@Override
public IEditorMode getPreviousGui() {
return this;
}
@Override
public void drawGuiForeground(boolean overlayvisible, int mouseX, int mouseY) {
if (MODE == DISPLAY && !isTabVisible(currentTab)) return;
for (ICriteria criteria : currentTab.getCriteria()) {
TreeEditorElement element = getElement(criteria);
if (element != null) {
if (MODE == DISPLAY) {
ColorMode mode = TreeEditorElement.getModeForCriteria(criteria, false);
if (mode == ColorMode.INVISIBLE) continue;
}
if (element.isCriteriaVisible() || MODE == EDIT) {
List<ICriteria> prereqs = criteria.getPreReqs();
for (ICriteria c : prereqs) {
int y1 = getElement(c).getY();
int y2 = element.getY();
int x1 = getElement(c).getX();
int x2 = element.getX();
int width;
int textWidth = CORE.mc.fontRendererObj.getStringWidth(c.getLocalisedName());
int iconWidth = 9 + (c.getRewards().size() * 12);
if (textWidth >= iconWidth) {
width = textWidth + 9;
} else width = iconWidth;
width -= 3;
if (c.getTab() == criteria.getTab()) {
drawLine(CORE.getOffsetX() + width + x1, 12 + y1 - 1, CORE.getOffsetX() + 5 + x2, 12 + y2 - 1, 1, GuiList.THEME.connectLineColor1);
drawLine(CORE.getOffsetX() + width + x1, 12 + y1 + 1, CORE.getOffsetX() + 5 + x2, 12 + y2 + 1, 1, GuiList.THEME.connectLineColor2); //#636C69
drawLine(CORE.getOffsetX() + width + x1, 12 + y1, CORE.getOffsetX() + 5 + x2, 12 + y2, 1, GuiList.THEME.connectLineColor3);
}
}
}
}
}
GlStateManager.clear(GL11.GL_DEPTH_BUFFER_BIT);
for (ICriteria criteria : currentTab.getCriteria()) {
TreeEditorElement element = getElement(criteria);
if (element != null) {
if (element.isCriteriaVisible() || MODE == EDIT) {
element.draw(0, CORE.screenTop, CORE.getOffsetX());
}
}
}
}
public ITab previousTab = null;
@Override
public void keyTyped(char character, int key) {
ICriteria toRemove = null;
for (ICriteria criteria : currentTab.getCriteria()) {
TreeEditorElement element = getElement(criteria);
if (element != null) {
if (element.isCriteriaVisible() || MODE == EDIT) {
if (element.keyTyped(character, key)) {
toRemove = criteria;
break;
}
}
}
}
if (toRemove != null) {
RuleHandler.removeCriteria(toRemove.getUniqueID(), false);
}
if (key == Keyboard.KEY_UP) {
currentTab.setSortIndex(currentTab.getSortIndex() + 1);
APICache.getClientCache().clearSorted(); //Clear the sorted
CORE.initGui();
} else if (key == Keyboard.KEY_DOWN) {
currentTab.setSortIndex(currentTab.getSortIndex() - 1);
APICache.getClientCache().clearSorted(); //Clear the sorted
CORE.initGui();
}
}
@Override
public void guiMouseReleased(int mouseX, int mouseY, int button) {
for (ICriteria criteria : currentTab.getCriteria()) {
TreeEditorElement element = getElement(criteria);
if (element != null) {
element.release(mouseX, mouseY);
}
}
isDragging = false;
}
public long lastClick;
public int lastType;
public ICriteria lastClicked = null;
public int drag = 0;
public boolean isDragging = false;
public int lastX;
public int lastY;
@Override
public boolean guiMouseClicked(boolean overlayvisible, int mouseX, int mouseY, int button) {
if (currentTab == null) return false;
long thisClick = System.currentTimeMillis();
long difference = thisClick - lastClick;
boolean isDoubleClick = button == 0 && lastType == 0 && difference <= 500 && lastX == mouseX && lastY == mouseY;
lastClick = System.currentTimeMillis();
lastType = button;
lastX = mouseX;
lastY = mouseY;
lastClicked = null;
if (button == 0) {
for (ICriteria criteria : currentTab.getCriteria()) {
TreeEditorElement element = getElement(criteria);
if (element != null) {
if (MODE == DISPLAY) {
ColorMode mode = TreeEditorElement.getModeForCriteria(criteria, false);
if (mode == ColorMode.INVISIBLE) continue;
}
if (element.isCriteriaVisible() || MODE == EDIT) {
if (element.click(mouseX, mouseY, isDoubleClick)) {
lastClicked = criteria;
return true;
}
}
}
}
if (isDoubleClick && MODE == EDIT) {
GuiList.TREE_EDITOR.previous = null;
GuiList.TREE_EDITOR.selected = null;
GuiList.TREE_EDITOR.lastClicked = null;
GuiList.TREE_EDITOR.isDragging = false;
ITab currentTab = GuiList.TREE_EDITOR.currentTab;
int offsetX = CORE.getOffsetX();
ICriteria criteria = RuleHandler.newCriteria(currentTab, UUID.randomUUID(), true);
criteria.setCoordinates(mouseX - 50 - offsetX, mouseY - 10);
GuiList.TREE_EDITOR.addCriteria(criteria, mouseX - 50, mouseY - 10, offsetX);
return true;
}
return false;
} else {
if (lastClicked == null && selected == null) {
isDragging = true;
drag = mouseX;
return true;
}
}
return true;
}
@Override
public void handleMouseInput(int mouseX, int mouseY) {
if (isDragging) {
int difference = mouseX - drag;
drag = mouseX;
if (difference != 0) {
CORE.scroll(difference);
}
}
if (lastClicked != null) {
for (ICriteria criteria : currentTab.getCriteria()) {
TreeEditorElement element = getElement(criteria);
if (element != null) {
element.follow(mouseX, mouseY);
int wheel = Mouse.getDWheel();
if (wheel != 0) {
getElement(criteria).scroll(wheel < 0);
}
}
}
}
}
}