package pneumaticCraft.client.gui;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.ScaledResolution;
import net.minecraft.client.resources.I18n;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.Vec3;
import org.apache.commons.lang3.text.WordUtils;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11;
import pneumaticCraft.client.gui.widget.WidgetVerticalScrollbar;
import pneumaticCraft.common.progwidgets.IJump;
import pneumaticCraft.common.progwidgets.ILabel;
import pneumaticCraft.common.progwidgets.IProgWidget;
import pneumaticCraft.lib.ModIds;
import cpw.mods.fml.common.Loader;
public class GuiUnitProgrammer extends GuiScreen{
private final FontRenderer fontRendererObj;
private final List<IProgWidget> progWidgets;
private final int guiLeft, guiTop;
private final int startX, startY, areaWidth, areaHeight;
private final int xSize;
private int translatedX, translatedY;
private int lastMouseX, lastMouseY;
private int lastZoom;
private boolean wasClicking;
private final WidgetVerticalScrollbar scaleScroll;
private static final float SCALE_PER_STEP = 0.2F;
public GuiUnitProgrammer(List<IProgWidget> progWidgets, FontRenderer fontRendererObj, int guiLeft, int guiTop,
int width, int height, int xSize, int startX, int startY, int areaWidth, int areaHeight, int translatedX,
int translatedY, int lastZoom){
this.fontRendererObj = fontRendererObj;
this.progWidgets = progWidgets;
this.guiLeft = guiLeft;
this.guiTop = guiTop;
this.width = width;
this.height = height;
this.xSize = xSize;
this.startX = startX;
this.startY = startY;
this.areaWidth = areaWidth;
this.areaHeight = areaHeight;
this.translatedX = translatedX;
this.translatedY = translatedY;
this.lastZoom = lastZoom;
scaleScroll = new WidgetVerticalScrollbar(guiLeft + 302, guiTop + 40, 129).setStates(9).setCurrentState(lastZoom).setListening(true);
}
public WidgetVerticalScrollbar getScrollBar(){
return scaleScroll;
}
public int getLastZoom(){
return lastZoom;
}
public int getTranslatedX(){
return translatedX;
}
public int getTranslatedY(){
return translatedY;
}
public void renderForeground(int x, int y, IProgWidget tooltipExcludingWidget){
IProgWidget widget = getHoveredWidget(x, y);
if(widget != null && widget != tooltipExcludingWidget) {
List<String> tooltip = new ArrayList<String>();
widget.getTooltip(tooltip);
List<String> errors = new ArrayList<String>();
widget.addErrors(errors, progWidgets);
if(errors.size() > 0) {
tooltip.add(EnumChatFormatting.RED + I18n.format("gui.programmer.errors"));
for(String s : errors) {
String[] lines = WordUtils.wrap("-" + I18n.format(s), 30).split(System.getProperty("line.separator"));
for(String line : lines) {
tooltip.add(EnumChatFormatting.RED + " " + line);
}
}
}
List<String> warnings = new ArrayList<String>();
widget.addWarnings(warnings, progWidgets);
if(warnings.size() > 0) {
tooltip.add(EnumChatFormatting.YELLOW + I18n.format("gui.programmer.warnings"));
for(String s : warnings) {
String[] lines = WordUtils.wrap("-" + I18n.format(s), 30).split(System.getProperty("line.separator"));
for(String line : lines) {
tooltip.add(EnumChatFormatting.YELLOW + " " + line);
}
}
}
addAdditionalInfoToTooltip(widget, tooltip);
if(tooltip.size() > 0) drawHoveringText(tooltip, x - guiLeft, y - guiTop, fontRendererObj);
}
}
public IProgWidget getHoveredWidget(int x, int y){
float scale = getScale();
for(IProgWidget widget : progWidgets) {
if(!isOutsideProgrammingArea(widget)) {
if((x - translatedX) / scale - guiLeft >= widget.getX() && (y - translatedY) / scale - guiTop >= widget.getY() && (x - translatedX) / scale - guiLeft <= widget.getX() + widget.getWidth() / 2 && (y - translatedY) / scale - guiTop <= widget.getY() + widget.getHeight() / 2) {
return widget;
}
}
}
return null;
}
protected void addAdditionalInfoToTooltip(IProgWidget widget, List<String> tooltip){
if(widget.getOptionWindow(null) != null) {
tooltip.add(EnumChatFormatting.GOLD + "Right click for options");
}
if(Loader.isModLoaded(ModIds.IGWMOD)) tooltip.add(I18n.format("gui.programmer.pressIForInfo"));
}
public void render(int x, int y, boolean showFlow, boolean showInfo, boolean translate){
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
int origX = x;
int origY = y;
x -= translatedX;
y -= translatedY;
float scale = getScale();
x = (int)(x / scale);
y = (int)(y / scale);
if(scaleScroll.getState() != lastZoom) {
float shift = SCALE_PER_STEP * (scaleScroll.getState() - lastZoom);
if(new Rectangle(guiLeft + startX, guiTop + startY, areaWidth, areaHeight).contains(origX, origY)) {
translatedX += shift * x;
translatedY += shift * y;
} else {
translatedX += areaWidth / 2 * shift;
translatedY += areaHeight / 2 * shift;
}
}
lastZoom = scaleScroll.getState();
ScaledResolution sr = new ScaledResolution(Minecraft.getMinecraft(), Minecraft.getMinecraft().displayWidth, Minecraft.getMinecraft().displayHeight);
GL11.glScissor((guiLeft + startX) * sr.getScaleFactor(), (sr.getScaledHeight() - areaHeight - (guiTop + startY)) * sr.getScaleFactor(), areaWidth * sr.getScaleFactor(), areaHeight * sr.getScaleFactor());
GL11.glEnable(GL11.GL_SCISSOR_TEST);
GL11.glPushMatrix();
GL11.glTranslated(translatedX, translatedY, 0);
GL11.glScaled(scale, scale, 1);
if(showFlow) showFlow();
GL11.glEnable(GL11.GL_TEXTURE_2D);
for(IProgWidget widget : progWidgets) {
GL11.glPushMatrix();
GL11.glTranslated(widget.getX() + guiLeft, widget.getY() + guiTop, 0);
GL11.glScaled(0.5, 0.5, 1);
widget.render();
GL11.glPopMatrix();
}
for(IProgWidget widget : progWidgets) {
List<String> errors = new ArrayList<String>();
widget.addErrors(errors, progWidgets);
if(errors.size() > 0) {
drawBorder(widget, 0xFFFF0000);
} else {
List<String> warnings = new ArrayList<String>();
widget.addWarnings(warnings, progWidgets);
if(warnings.size() > 0) {
drawBorder(widget, 0xFFFFFF00);
}
}
}
renderAdditionally();
GL11.glColor4d(1, 1, 1, 1);
if(showInfo) {
for(IProgWidget widget : progWidgets) {
GL11.glPushMatrix();
GL11.glTranslated(widget.getX() + guiLeft, widget.getY() + guiTop, 0);
GL11.glScaled(0.5, 0.5, 1);
widget.renderExtraInfo();
GL11.glPopMatrix();
}
}
GL11.glPopMatrix();
GL11.glDisable(GL11.GL_SCISSOR_TEST);
boolean isLeftClicking = Mouse.isButtonDown(0);
if(translate && isLeftClicking && wasClicking && new Rectangle(guiLeft + startX, guiTop + startY, areaWidth, areaHeight).contains(origX, origY)) {
translatedX += origX - lastMouseX;
translatedY += origY - lastMouseY;
}
wasClicking = isLeftClicking;
lastMouseX = origX;
lastMouseY = origY;
}
protected void renderAdditionally(){
}
protected void drawBorder(IProgWidget widget, int color){
GL11.glPushMatrix();
GL11.glTranslated(widget.getX() + guiLeft, widget.getY() + guiTop, 0);
GL11.glScaled(0.5, 0.5, 1);
drawVerticalLine(0, 0, widget.getHeight(), color);
drawVerticalLine(widget.getWidth(), 0, widget.getHeight(), color);
drawHorizontalLine(widget.getWidth(), 0, 0, color);
drawHorizontalLine(widget.getWidth(), 0, widget.getHeight(), color);
GL11.glPopMatrix();
}
private void showFlow(){
GL11.glLineWidth(1);
GL11.glDisable(GL11.GL_TEXTURE_2D);
GL11.glBegin(GL11.GL_LINES);
for(IProgWidget widget : progWidgets) {
if(widget instanceof IJump) {
List<String> jumpLocations = ((IJump)widget).getPossibleJumpLocations();
if(jumpLocations != null) {
for(String jumpLocation : jumpLocations) {
if(jumpLocation != null) {
for(IProgWidget w : progWidgets) {
if(w instanceof ILabel) {
String label = ((ILabel)w).getLabel();
if(label != null && jumpLocation.equals(label)) {
int x1 = widget.getX() + widget.getWidth() / 4;
int y1 = widget.getY() + widget.getHeight() / 4;
int x2 = w.getX() + w.getWidth() / 4;
int y2 = w.getY() + w.getHeight() / 4;
double midX = (x2 + x1) / 2D;
double midY = (y2 + y1) / 2D;
GL11.glVertex3d(guiLeft + x1, guiTop + y1, zLevel);
GL11.glVertex3d(guiLeft + x2, guiTop + y2, zLevel);
Vec3 arrowVec = Vec3.createVectorHelper(x1 - x2, y1 - y2, 0).normalize();
float arrowAngle = (float)Math.toRadians(30);
float arrowSize = 5;
arrowVec.xCoord *= arrowSize;
arrowVec.yCoord *= arrowSize;
arrowVec.rotateAroundZ(arrowAngle);
GL11.glVertex3d(guiLeft + midX, guiTop + midY, zLevel);
GL11.glVertex3d(guiLeft + midX + arrowVec.xCoord, guiTop + midY + arrowVec.yCoord, zLevel);
arrowVec.rotateAroundZ(-2 * arrowAngle);
GL11.glVertex3d(guiLeft + midX, guiTop + midY, zLevel);
GL11.glVertex3d(guiLeft + midX + arrowVec.xCoord, guiTop + midY + arrowVec.yCoord, zLevel);
}
}
}
}
}
}
}
}
GL11.glEnd();
GL11.glEnable(GL11.GL_TEXTURE_2D);
}
public float getScale(){
return 2.0F - scaleScroll.getState() * SCALE_PER_STEP;
}
public boolean isOutsideProgrammingArea(IProgWidget widget){
float scale = getScale();
int x = (int)((widget.getX() + guiLeft) * scale);
int y = (int)((widget.getY() + guiTop) * scale);
x += translatedX - guiLeft;
y += translatedY - guiTop;
return x < startX || x + widget.getWidth() * scale / 2 > startX + areaWidth || y < startY || y + widget.getHeight() * scale / 2 > startY + areaHeight;
}
public void gotoPiece(IProgWidget widget){
scaleScroll.currentScroll = 0;
lastZoom = 0;
translatedX = -widget.getX() * 2 + areaWidth / 2 - guiLeft;
translatedY = -widget.getY() * 2 + areaHeight / 2 - guiTop;
}
}