package pneumaticCraft.common.progwidgets;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.resources.I18n;
import net.minecraft.entity.ai.EntityAIBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.StatCollector;
import org.apache.commons.lang3.text.WordUtils;
import org.lwjgl.opengl.GL11;
import pneumaticCraft.client.gui.GuiProgrammer;
import pneumaticCraft.common.ai.IDroneBase;
import pneumaticCraft.lib.Log;
import cpw.mods.fml.client.FMLClientHandler;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
public abstract class ProgWidget implements IProgWidget{
private int x, y;
private IProgWidget[] connectedParameters;
private IProgWidget outputStepConnection;
private IProgWidget parent;
// private static Gui gui;
public ProgWidget(){
if(getParameters() != null) connectedParameters = new IProgWidget[getParameters().length * 2]; //times two because black- and whitelist.
}
@Override
public void getTooltip(List<String> curTooltip){
curTooltip.add(EnumChatFormatting.DARK_AQUA + I18n.format("programmingPuzzle." + getWidgetString() + ".name"));
}
@Override
public void renderExtraInfo(){
if(getExtraStringInfo() != null) {
GL11.glPushMatrix();
GL11.glScaled(0.5, 0.5, 0.5);
FontRenderer fr = Minecraft.getMinecraft().fontRenderer;
String[] splittedInfo = WordUtils.wrap(getExtraStringInfo(), 40).split(System.getProperty("line.separator"));
for(int i = 0; i < splittedInfo.length; i++) {
int stringLength = fr.getStringWidth(splittedInfo[i]);
int startX = getWidth() / 2 - stringLength / 4;
int startY = getHeight() / 2 - (fr.FONT_HEIGHT + 1) * (splittedInfo.length - 1) / 4 + (fr.FONT_HEIGHT + 1) * i / 2 - fr.FONT_HEIGHT / 4;
Gui.drawRect(startX * 2 - 1, startY * 2 - 1, startX * 2 + stringLength + 1, startY * 2 + fr.FONT_HEIGHT + 1, 0xFFFFFFFF);
fr.drawString(splittedInfo[i], startX * 2, startY * 2, 0xFF000000);
}
GL11.glPopMatrix();
GL11.glColor4d(1, 1, 1, 1);
}
}
public String getExtraStringInfo(){
return null;
}
@Override
public void addWarnings(List<String> curInfo, List<IProgWidget> widgets){
if(this instanceof IVariableWidget) {
Set<String> variables = new HashSet<String>();
((IVariableWidget)this).addVariables(variables);
for(String variable : variables) {
if(!variable.equals("") && !variable.startsWith("#") && !variable.startsWith("$") && !isVariableSetAnywhere(widgets, variable)) {
curInfo.add(StatCollector.translateToLocalFormatted("gui.progWidget.general.warning.variableNeverSet", variable));
}
}
}
}
private boolean isVariableSetAnywhere(List<IProgWidget> widgets, String variable){
if(variable.equals("")) return true;
for(IProgWidget widget : widgets) {
if(widget instanceof IVariableSetWidget) {
Set<String> variables = new HashSet<String>();
((IVariableSetWidget)widget).addVariables(variables);
if(variables.contains(variable)) return true;
}
}
return false;
}
@Override
public void addErrors(List<String> curInfo, List<IProgWidget> widgets){
if(!hasStepInput() && hasStepOutput() && outputStepConnection == null) {
curInfo.add("gui.progWidget.general.error.noPieceConnected");
}
}
@Override
public int getX(){
return x;
}
@Override
public int getY(){
return y;
}
@Override
public void setX(int x){
this.x = x;
}
@Override
public void setY(int y){
this.y = y;
}
@Override
public int getWidth(){
return 30;
}
@Override
public int getHeight(){
return getParameters() != null ? getParameters().length * 22 : 22;
}
@Override
public void setParent(IProgWidget widget){
parent = widget;
}
@Override
public IProgWidget getParent(){
return parent;
}
@Override
public void render(){
FMLClientHandler.instance().getClient().getTextureManager().bindTexture(getTexture());
int width = getWidth() + (getParameters() != null && getParameters().length > 0 ? 10 : 0);
int height = getHeight() + (hasStepOutput() ? 10 : 0);
Tessellator t = Tessellator.instance;
t.startDrawingQuads();
t.addVertexWithUV(0, 0, 0, 0, 0);
t.addVertexWithUV(0, height, 0, 0, 1);
t.addVertexWithUV(width, height, 0, 1, 1);
t.addVertexWithUV(width, 0, 0, 1, 0);
t.draw();
}
protected abstract ResourceLocation getTexture();
@Override
public boolean hasStepOutput(){
return hasStepInput();
}
@Override
public EntityAIBase getWidgetTargetAI(IDroneBase drone, IProgWidget widget){
return null;
}
@Override
public EntityAIBase getWidgetAI(IDroneBase drone, IProgWidget widget){
return null;
}
@Override
public void setParameter(int index, IProgWidget parm){
if(connectedParameters != null) connectedParameters[index] = parm;
}
@Override
public boolean canSetParameter(int index){
if(connectedParameters != null) {
return hasBlacklist() || index < connectedParameters.length / 2;
}
return false;
}
protected boolean hasBlacklist(){
return true;
}
@Override
public IProgWidget[] getConnectedParameters(){
return connectedParameters;
}
@Override
public void setOutputWidget(IProgWidget widget){
outputStepConnection = widget;
}
@Override
public IProgWidget getOutputWidget(){
return outputStepConnection;
}
@Override
public IProgWidget getOutputWidget(IDroneBase drone, List<IProgWidget> allWidgets){
return outputStepConnection;
}
@Override
public IProgWidget copy(){
try {
IProgWidget copy = this.getClass().newInstance();
NBTTagCompound tag = new NBTTagCompound();
writeToNBT(tag);
copy.readFromNBT(tag);
return copy;
} catch(Exception e) {
Log.error("Error occured when trying to copy an " + getWidgetString() + " widget.");
e.printStackTrace();
return null;
}
}
@Override
public void writeToNBT(NBTTagCompound tag){
tag.setString("name", getWidgetString());
tag.setInteger("x", x);
tag.setInteger("y", y);
}
@Override
public void readFromNBT(NBTTagCompound tag){
x = tag.getInteger("x");
y = tag.getInteger("y");
}
@Override
@SideOnly(Side.CLIENT)
public GuiScreen getOptionWindow(GuiProgrammer guiProgrammer){
return null;
}
public static List getConnectedWidgetList(IProgWidget widget, int parameterIndex){
IProgWidget connectingWidget = widget.getConnectedParameters()[parameterIndex];
if(connectingWidget != null) {
List list = new ArrayList();
while(connectingWidget != null) {
list.add(connectingWidget);
connectingWidget = connectingWidget.getConnectedParameters()[0];
}
return list;
} else {
return null;
}
}
@Override
public boolean canBeRunByComputers(IDroneBase drone, IProgWidget widget){
return getWidgetAI(drone, widget) != null;
}
}