package zmaster587.advancedRocketry.inventory.modules;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import org.lwjgl.opengl.GL11;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import zmaster587.advancedRocketry.api.dimension.IDimensionProperties;
import zmaster587.advancedRocketry.api.dimension.solar.IGalaxy;
import zmaster587.advancedRocketry.api.dimension.solar.StellarBody;
import zmaster587.advancedRocketry.dimension.DimensionManager;
import zmaster587.advancedRocketry.dimension.DimensionProperties;
import zmaster587.advancedRocketry.inventory.TextureResources;
import zmaster587.libVulpes.inventory.GuiModular;
import zmaster587.libVulpes.inventory.modules.IButtonInventory;
import zmaster587.libVulpes.inventory.modules.IProgressBar;
import zmaster587.libVulpes.inventory.modules.ISelectionNotify;
import zmaster587.libVulpes.inventory.modules.ModuleBase;
import zmaster587.libVulpes.inventory.modules.ModuleButton;
import zmaster587.libVulpes.inventory.modules.ModuleContainerPan;
import zmaster587.libVulpes.inventory.modules.ModuleDualProgressBar;
import zmaster587.libVulpes.render.RenderHelper;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.ICrafting;
import net.minecraft.util.ResourceLocation;
public class ModulePlanetSelector extends ModuleContainerPan implements IButtonInventory {
//Closest thing i can get to a struct :/
private class PlanetRenderProperties {
int radius;
int posX;
int posY;
public PlanetRenderProperties() {}
public PlanetRenderProperties(int radius, int posX, int posY) {
this.radius = radius;
this.posX = posX;
this.posY = posY;
}
}
private static final int size = 2000;
private static final int starIdOffset = 10000;
ISelectionNotify hostTile;
private int currentSystem, selectedSystem;
private double zoom;
private boolean currentSystemChanged = false;
private List<ModuleButton> planetList;
int topLevel;
private boolean stellarView;
private HashMap<Integer, PlanetRenderProperties> renderPropertiesMap;
PlanetRenderProperties currentlySelectedPlanet;
public ModulePlanetSelector(int planetId, ResourceLocation backdrop, ISelectionNotify tile, boolean star) {
super(0, 0, null, null, backdrop, 0, 0, 0, 0, size,size);
hostTile = tile;
int center = size/2;
zoom = 1.0;
planetList = new ArrayList<ModuleButton>();
moduleList = new ArrayList<ModuleBase>();
staticModuleList = new ArrayList<ModuleBase>();
renderPropertiesMap = new HashMap<Integer, PlanetRenderProperties>();
currentlySelectedPlanet = new PlanetRenderProperties();
currentSystem = starIdOffset;
selectedSystem = -1;
stellarView = false;
staticModuleList.add(new ModuleButton(0, 0, -1, "<< Up", this, zmaster587.libVulpes.inventory.TextureResources.buttonBuild));
staticModuleList.add(new ModuleButton(0, 18, -2, "Select", this, zmaster587.libVulpes.inventory.TextureResources.buttonBuild));
ModuleDualProgressBar progressBar;
staticModuleList.add(progressBar = new ModuleDualProgressBar(100, 0, 0, TextureResources.atmIndicator, (IProgressBar)tile, "%b -> %a Earth's atmospheric pressure"));
progressBar.setTooltipValueMultiplier(.02f);
staticModuleList.add(progressBar = new ModuleDualProgressBar(200, 0, 2, TextureResources.massIndicator, (IProgressBar)tile, "%b -> %a Earth's mass"));
progressBar.setTooltipValueMultiplier(.02f);
staticModuleList.add(progressBar = new ModuleDualProgressBar(300, 0, 1, TextureResources.distanceIndicator, (IProgressBar)tile, "%b -> %a Relative Distance units"));
progressBar.setTooltipValueMultiplier(.02f);
//renderPlanetarySystem(properties, center, center, 3f);
if(FMLCommonHandler.instance().getSide().isClient()) {
if(star) {
topLevel = -1;
currentSystem = starIdOffset + planetId;
renderStarSystem(DimensionManager.getInstance().getStar(planetId), center, center, 1f, 0.5f);
}
else {
currentSystem = planetId;
topLevel = planetId;
renderPlanetarySystem(DimensionManager.getInstance().getDimensionProperties(planetId), center, center, 1f, 3f);
}
}
}
@Override
public void onScroll(int dwheel) {
//TODO
//zoom = Math.min(Math.max(zoom + dwheel/1000.0, 0.36), 2.0);
//redrawSystem();
}
public int getSelectedSystem() {
return selectedSystem;
}
public void setSelectedSystem(int id) {
selectedSystem = id;
}
@SideOnly(Side.CLIENT)
private void renderGalaxyMap(IGalaxy galaxy, int posX, int posY, float distanceZoomMultiplier, float planetSizeMultiplier) {
Collection<StellarBody> stars = galaxy.getStars();
for(StellarBody star : stars) {
int displaySize = (int)(planetSizeMultiplier*star.getDisplayRadius());
int offsetX = star.getPosX() + posX - displaySize/2;
int offsetY = star.getPosZ() + posY - displaySize/2;
ModuleButton button;
planetList.add(button = new ModuleButton(offsetX, offsetY, star.getId() + starIdOffset, "", this, new ResourceLocation[] { TextureResources.locationSunPng }, String.format("Name: %s\nNumber of Planets: %d",star.getName(), star.getNumPlanets()), displaySize, displaySize));
button.setSound("buttonBlipA");
button.setBGColor(star.getColorRGB8());
renderPropertiesMap.put(star.getId() + starIdOffset, new PlanetRenderProperties(displaySize, offsetX, offsetY));
//prevMultiplier *= 0.25f;
}
moduleList.addAll(planetList);
}
@SideOnly(Side.CLIENT)
private void renderStarSystem(StellarBody star, int posX, int posY, float distanceZoomMultiplier, float planetSizeMultiplier) {
int displaySize = (int)(planetSizeMultiplier*star.getDisplayRadius());
int offsetX = posX - displaySize/2;
int offsetY = posY - displaySize/2;
ModuleButton button;
planetList.add(button = new ModuleButton(offsetX, offsetY, star.getId() + starIdOffset, "", this, new ResourceLocation[] { TextureResources.locationSunPng }, String.format("Name: %s\nNumber of Planets: %d",star.getName(), star.getNumPlanets()), displaySize, displaySize));
button.setSound("buttonBlipA");
button.setBGColor(star.getColorRGB8());
renderPropertiesMap.put(star.getId() + starIdOffset, new PlanetRenderProperties(displaySize, offsetX, offsetY));
//prevMultiplier *= 0.25f;
for(IDimensionProperties properties : star.getPlanets()) {
if(!properties.isMoon())
renderPlanets((DimensionProperties)properties, offsetX + displaySize/2, offsetY + displaySize/2, displaySize, distanceZoomMultiplier,planetSizeMultiplier);
}
moduleList.addAll(planetList);
}
@SideOnly(Side.CLIENT)
private void renderPlanetarySystem(DimensionProperties planet, int posX, int posY, float distanceZoomMultiplier, float planetSizeMultiplier) {
int displaySize = (int)(planetSizeMultiplier*planet.gravitationalMultiplier/.02f);
int offsetX = (int)(distanceZoomMultiplier*posX) - displaySize/2;
int offsetY = (int)(distanceZoomMultiplier*posY) - displaySize/2;
displaySize *=distanceZoomMultiplier;
ModuleButton button;
planetList.add(button = new ModuleButton(offsetX, offsetY, planet.getId(), "", this, new ResourceLocation[] { planet.getPlanetIcon() }, planet.getName(), displaySize, displaySize));
button.setSound("buttonBlipA");
renderPropertiesMap.put(planet.getId(), new PlanetRenderProperties(displaySize, offsetX, offsetY));
//prevMultiplier *= 0.25f;
for(Integer childId : planet.getChildPlanets()) {
DimensionProperties properties = DimensionManager.getInstance().getDimensionProperties(childId);
renderPlanets(properties, offsetX + displaySize/2, offsetY + displaySize/2, displaySize, distanceZoomMultiplier, planetSizeMultiplier);
}
moduleList.addAll(planetList);
}
@SideOnly(Side.CLIENT)
private void renderPlanets(DimensionProperties planet, int parentOffsetX, int parentOffsetY, int parentRadius, float distanceMultiplier, float planetSizeMultiplier) {
int displaySize = (int)(planetSizeMultiplier*planet.gravitationalMultiplier/.02f);
int offsetX = parentOffsetX + (int)(Math.cos(planet.orbitTheta)*((planet.orbitalDist*distanceMultiplier) + parentRadius)) - displaySize/2;
int offsetY = parentOffsetY + (int)(Math.sin(planet.orbitTheta)*((planet.orbitalDist*distanceMultiplier) + parentRadius)) - displaySize/2;
ModuleButton button;
planetList.add(button = new ModuleButton(offsetX, offsetY, planet.getId(), "", this, new ResourceLocation[] { planet.getPlanetIcon() }, planet.getName() + "\nMoons: " + planet.getChildPlanets().size(), displaySize, displaySize));
button.setSound("buttonBlipA");
renderPropertiesMap.put(planet.getId(), new PlanetRenderProperties(displaySize, offsetX, offsetY));
}
@SideOnly(Side.CLIENT)
public void setPlanetAsKnown(int id) {
for(ModuleBase module : moduleList) {
if(module instanceof ModuleButton && ((ModuleButton)module).buttonId == id) {
((ModuleButton)module).setImage( new ResourceLocation[] {DimensionManager.getInstance().getDimensionProperties(id).getPlanetIcon()});
}
}
}
@Override
@SideOnly(Side.CLIENT)
public List<GuiButton> addButtons(int x, int y) {
this.screenSizeX = Minecraft.getMinecraft().displayWidth;
this.screenSizeY = Minecraft.getMinecraft().displayHeight;
setOffset2(internalOffsetX - Minecraft.getMinecraft().displayWidth/4, internalOffsetY - Minecraft.getMinecraft().displayHeight /4);
return super.addButtons(x, y);
}
@SideOnly(Side.CLIENT)
private void redrawSystem() {
int offsetX = -currentPosX;
int offsetY = -currentPosY;
setOffset2(0,0);
for(int i = 0; i< moduleList.size(); i++) {
ModuleBase module = planetList.get(i);
if(planetList.contains(module))
this.buttonList.remove(((ModuleButton)module).button);
}
this.moduleList.removeAll(planetList);
planetList.clear();
if(!stellarView) {
if(currentSystem < starIdOffset) {
DimensionProperties properties = DimensionManager.getInstance().getDimensionProperties(currentSystem);
renderPlanetarySystem(properties, size/2, size/2, 1f,3f*properties.getPathLengthToStar());
}
else
renderStarSystem(DimensionManager.getInstance().getStar(currentSystem - starIdOffset), size/2, size/2, 1f*(float) zoom, (float)zoom*.5f);
}
else
renderGalaxyMap(DimensionManager.getInstance(), size/2, size/2, 1f*(float) zoom, (float)zoom*.25f);
int x = currentPosX - size/2, y = currentPosY - size/2;
this.screenSizeX = Minecraft.getMinecraft().displayWidth;
this.screenSizeY = Minecraft.getMinecraft().displayHeight;
for(ModuleBase module : this.planetList) {
buttonList.addAll(module.addButtons(currentPosX, currentPosY));
}
setOffset2(offsetX, offsetY);
}
@Override
@SideOnly(Side.CLIENT)
public void onMouseClicked(GuiModular gui, int x, int y, int button) {
super.onMouseClicked(gui, x, y, button);
//CME workaround
if(currentSystemChanged) {
currentPosX = 0;
currentPosY = 0;
zoom = 1;
redrawSystem();
setOffset2(internalOffsetX - Minecraft.getMinecraft().displayWidth/4 , internalOffsetY - Minecraft.getMinecraft().displayHeight /4);
//redrawSystem();
selectedSystem = -1;
currentSystemChanged = false;
hostTile.onSystemFocusChanged(this);
}
}
@Override
public void renderForeground(int guiOffsetX, int guiOffsetY, int mouseX,
int mouseY, float zLevel, GuiContainer gui, FontRenderer font) {
super.renderForeground(guiOffsetX, guiOffsetY, mouseX, mouseY, zLevel, gui,
font);
}
@Override
protected void moveContainerInterior(int deltaX, int deltaY) {
super.moveContainerInterior((int)(deltaX), (int)(deltaY));
}
@Override
@SideOnly(Side.CLIENT)
public void renderBackground(GuiContainer gui, int x, int y, int mouseX,
int mouseY, FontRenderer font) {
if(!stellarView && Minecraft.getSystemTime() % 5 == 0)
redrawSystem();
super.renderBackground(gui, x, y, mouseX, mouseY, font);
int center = size/2;
int numSegments = 50;
float theta = (float) (2 * Math.PI / (float)(numSegments));
float cos = (float) Math.cos(theta);
float sin = (float) Math.sin(theta);
GL11.glPushMatrix();
//GL11.glTranslated(-this.currentPosX/4, -this.currentPosY/4, 0);
//GL11.glScaled(zoom, zoom, 1.0);
//GL11.glTranslated(this.currentPosX/4, this.currentPosY/4, 0);
//Render orbits
if(!stellarView) {
for(int ii = 1; ii < 10; ii++) {
int radius = ii*80;
float x2 = radius;
float y2 = 0;
float t;
GL11.glPushMatrix();
GL11.glTranslatef(center + currentPosX, center + currentPosY, 0);
GL11.glDisable(GL11.GL_TEXTURE_2D);
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glColor4f(0.8f, .8f, 1f, .2f);
GL11.glEnable(GL11.GL_LINE_STIPPLE);
GL11.glLineStipple(5, (short)0x5555);
Tessellator.instance.startDrawing(GL11.GL_LINE_LOOP);
for(int i = 0; i < numSegments; i++) {
Tessellator.instance.addVertex(x2, y2, 0);
t = x2;
x2 = cos*x2 - sin*y2;
y2 = sin*t + cos*y2;
}
Tessellator.instance.draw();
//Reset GL info
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glDisable(GL11.GL_LINE_STIPPLE);
GL11.glColor4f(1f, 1f, 1f, 1f);
GL11.glDisable(GL11.GL_BLEND);
GL11.glPopMatrix();
}
}
//Render Selection
if(selectedSystem != -1) {
Minecraft.getMinecraft().getTextureManager().bindTexture(TextureResources.selectionCircle);
GL11.glPushMatrix();
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
float radius = currentlySelectedPlanet.radius/2;
if(renderPropertiesMap.containsKey(selectedSystem)) {
PlanetRenderProperties base = renderPropertiesMap.get(selectedSystem);
GL11.glTranslatef(base.posX + currentPosX + base.radius/2, base.posY + currentPosY + base.radius/2, 0);
}
else
GL11.glTranslatef(currentlySelectedPlanet.posX + currentPosX + radius, currentlySelectedPlanet.posY + currentPosY + radius, 0);
double progress = System.currentTimeMillis() % 20000 / 50f;
GL11.glPushMatrix();
GL11.glRotated(progress, 0, 0, 1);
Tessellator.instance.startDrawingQuads();
RenderHelper.renderNorthFaceWithUV(Tessellator.instance, 1, -radius, -radius, radius, radius, 0, 1, 0, 1);
Tessellator.instance.draw();
GL11.glPopMatrix();
GL11.glPushMatrix();
//GL11.glRotatef(-Minecraft.getMinecraft().theWorld.getTotalWorldTime(), 0, 0, 1);
radius *= (1.2 + 0.1*Math.sin(progress/10f));
Tessellator.instance.startDrawingQuads();
RenderHelper.renderNorthFaceWithUV(Tessellator.instance, 1, -radius, -radius, radius, radius, 0, 1, 0, 1);
Tessellator.instance.draw();
GL11.glPopMatrix();
GL11.glDisable(GL11.GL_BLEND);
GL11.glPopMatrix();
}
GL11.glPopMatrix();
}
@Override
@SideOnly(Side.CLIENT)
public void onInventoryButtonPressed(int buttonId) {
if(buttonId == -1) {
DimensionProperties properties = DimensionManager.getInstance().getDimensionProperties(currentSystem);
if(topLevel == -1 || currentSystem != topLevel) {
if(properties.isMoon())
currentSystem = properties.getParentPlanet();
else {
if(currentSystem >= starIdOffset) {
//if the star was the current system then go to stellar view
stellarView = true;
}
currentSystem = properties.getStar().getId() + starIdOffset;
}
currentSystemChanged=true;
selectedSystem = -1;
}
}
else if(buttonId == -2) {
if(selectedSystem < starIdOffset) {
hostTile.onSelectionConfirmed(this);
Minecraft.getMinecraft().thePlayer.closeScreen();
}
}
else {
if(selectedSystem == buttonId) {
currentSystem = buttonId;
currentSystemChanged=true;
//Go back to planetary mapping
stellarView = false;
selectedSystem = -1;
}
else {
selectedSystem = buttonId;
currentlySelectedPlanet = renderPropertiesMap.get(buttonId);
hostTile.onSelected(this);
}
}
}
@Override
public boolean needsUpdate(int localId) {
for(ModuleBase module : staticModuleList) {
if(localId >= 0 && localId < module.numberOfChangesToSend())
return module.needsUpdate(localId);
localId -= module.numberOfChangesToSend();
}
return false;
}
@Override
public void sendChanges(Container container, ICrafting crafter,
int variableId, int localId) {
for(ModuleBase module : staticModuleList) {
if(localId >= 0 && localId < module.numberOfChangesToSend()) {
module.sendChanges(container, crafter, variableId, localId);
return;
}
localId -= module.numberOfChangesToSend();
}
}
@Override
public void onChangeRecieved(int slot, int value) {
for(ModuleBase module : staticModuleList) {
if(slot >= 0 && slot < module.numberOfChangesToSend()) {
module.onChangeRecieved(slot, value);
return;
}
slot -= module.numberOfChangesToSend();
}
}
@Override
public int numberOfChangesToSend() {
int numChanges = 0;
for(ModuleBase module : staticModuleList) {
numChanges += module.numberOfChangesToSend();
}
return numChanges;
}
}