package com.flansmod.client.gui;
import java.io.IOException;
import java.util.HashMap;
import org.lwjgl.opengl.GL11;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.ScaledResolution;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.entity.RenderItem;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import net.minecraftforge.fml.client.FMLClientHandler;
import com.flansmod.client.FlansModResourceHandler;
import com.flansmod.common.FlansMod;
import com.flansmod.common.driveables.DriveableType;
import com.flansmod.common.driveables.mechas.MechaType;
import com.flansmod.common.parts.EnumPartCategory;
import com.flansmod.common.parts.ItemPart;
import com.flansmod.common.parts.PartType;
import com.flansmod.common.types.EnumType;
public class GuiDriveableCrafting extends GuiScreen
{
/** The background image */
private static final ResourceLocation texture = new ResourceLocation("flansmod", "gui/driveableCrafting.png");
/** The inventory of the player using this crafting table */
private InventoryPlayer inventory;
/** The Minecraft instance */
private Minecraft mc;
/** The world in which this crafting table resides */
private World world;
/** The crafting table co-ordinates */
private int x, y, z;
/** Item renderer */
private static RenderItem itemRenderer;
/** Gui origin */
private int guiOriginX, guiOriginY;
/** Blueprint scroller, static to save position upon exiting crafting window */
private static int blueprintsScroll = 0;
/** Recipe scroller */
private int recipeScroll = 0;
/** The blueprint that is currently selected */
private static int selectedBlueprint = 0;
/** Spins the driveable model */
private float spinner = 0;
/** Whether or not the currently selected driveable can be crafted */
private boolean canCraft = false;
public GuiDriveableCrafting(InventoryPlayer playerinventory, World w, int i, int j, int k)
{
inventory = playerinventory;
mc = FMLClientHandler.instance().getClient();
itemRenderer = mc.getRenderItem();
world = w;
x = i;
y = j;
z = k;
}
@Override
public void initGui()
{
super.initGui();
buttonList.add(new GuiButton(0, width / 2 + 22, height / 2 + 63, 40, 20, "Craft"));
}
@Override
protected void actionPerformed(GuiButton button)
{
if (button.id == 0)
{
FlansMod.proxy.craftDriveable(inventory.player, DriveableType.types.get(selectedBlueprint));
}
}
@Override
public void drawScreen(int i, int j, float f)
{
String recipeName;
ScaledResolution scaledresolution = new ScaledResolution(mc);
int w = scaledresolution.getScaledWidth();
int h = scaledresolution.getScaledHeight();
drawDefaultBackground();
GL11.glEnable(3042 /*GL_BLEND*/);
//Bind the background texture
mc.renderEngine.bindTexture(texture);
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
guiOriginX = w / 2 - 88;
guiOriginY = h / 2 - 99;
//Draw the background
drawTexturedModalRect(guiOriginX, guiOriginY, 0, 0, 176, 198);
drawString(fontRendererObj, "Vehicle Crafting", guiOriginX + 6, guiOriginY + 6, 0xffffff);
drawString(fontRendererObj, "Requires", guiOriginX + 6, guiOriginY + 125, 0xffffff);
drawString(fontRendererObj, "Engine", guiOriginX + 114, guiOriginY + 141, 0xffffff);
for(int m = 0; m < 2; m++)
{
for(int n = 0; n < 8; n++)
{
//Add the scroll bar position to get the correct driveable
int blueprintNumber = blueprintsScroll * 8 + 8 * m + n;
//If this driveable is selected
if(blueprintNumber == selectedBlueprint)
{
//Bind the gui texture and draw in the green highlighted panel behind the driveable item
mc.renderEngine.bindTexture(texture);
drawTexturedModalRect(guiOriginX + 8 + n * 18, guiOriginY + 18 + m * 18, 213, 11, 16, 16);
}
//If the number is within the bounds of the list
if(blueprintNumber < DriveableType.types.size())
{
//Draw the driveable item
DriveableType type = DriveableType.types.get(blueprintNumber);
drawSlotInventory(new ItemStack(type.item), guiOriginX + 8 + n * 18, guiOriginY + 18 + m * 18);
}
}
}
//Increment the spinner to spin the driveable. Wheeee!
spinner++;
//Return if the selectedBlueprint is invalid
if(selectedBlueprint >= DriveableType.types.size())
{
return;
}
//Make this true and then set it back to false as soon as a problem occurs in finding the required parts
canCraft = true;
//Get the currently selected driveable type and check its not null
DriveableType selectedType = DriveableType.types.get(selectedBlueprint);
if(selectedType != null)
{
//Render rotating driveable model
GL11.glPushMatrix();
GL11.glEnable(GL11.GL_DEPTH_TEST);
GL11.glEnable(GL11.GL_ALPHA_TEST);
GL11.glTranslatef(w / 2 - 46, h /2 - 10, 100);
//Do lights
GlStateManager.disableLighting();
GlStateManager.pushMatrix();
GlStateManager.rotate(180F, 1.0F, 0.0F, 0.0F);
GlStateManager.rotate(0F, 0.0F, 1.0F, 0.0F);
RenderHelper.enableStandardItemLighting();
GlStateManager.popMatrix();
GlStateManager.enableRescaleNormal();
if(selectedType instanceof MechaType)
GL11.glTranslatef(0, 15, 0);
GL11.glScalef(-50F * selectedType.modelScale / selectedType.cameraDistance, 50F * selectedType.modelScale / selectedType.cameraDistance, 50F * selectedType.modelScale / selectedType.cameraDistance);
GL11.glRotatef(180F, 0F, 0F, 1F);
GL11.glRotatef(30F, 1F, 0F, 0F);
GL11.glRotatef(spinner / 5F, 0F, 1F, 0F);
mc.renderEngine.bindTexture(FlansModResourceHandler.getTexture(selectedType));
selectedType.model.render(selectedType);
GL11.glDisable(GL11.GL_DEPTH_TEST);
GL11.glDisable(GL11.GL_ALPHA_TEST);
GL11.glPopMatrix();
recipeName = selectedType.name;
if (recipeName.length() > 16)
recipeName = recipeName.substring(0, 15) + "...";
//Render the info text alongside the driveable
drawString(fontRendererObj, recipeName , guiOriginX + 82, guiOriginY + 64, 0xffffff);
drawString(fontRendererObj, "Cargo Slots : " + selectedType.numCargoSlots, guiOriginX + 82, guiOriginY + 74, 0xffffff);
drawString(fontRendererObj, "Bomb Slots : " + selectedType.numBombSlots, guiOriginX + 82, guiOriginY + 84, 0xffffff);
drawString(fontRendererObj, "Passengers : " + selectedType.numPassengers, guiOriginX + 82, guiOriginY + 94, 0xffffff);
drawString(fontRendererObj, "Guns : " + (selectedType.ammoSlots()), guiOriginX + 82, guiOriginY + 104, 0xffffff);
drawString(fontRendererObj, selectedType.numEngines() + "x", guiOriginX + 100, guiOriginY + 141, 0xffffff);
//Create a temporary copy of the player inventory in order to work out whether the player has each of the itemstacks required
InventoryPlayer temporaryInventory = new InventoryPlayer(null);
temporaryInventory.copyInventory(inventory);
//Draw the recipe items
//Iterate over rows then columns
for(int r = 0; r < 3; r++)
{
for(int c = 0; c < 4; c++)
{
//Work out what recipe item this is
int recipeItemNumber = recipeScroll * 4 + r * 4 + c;
//If this is actually a valid recipe item
if(recipeItemNumber < selectedType.driveableRecipe.size())
{
//Get the itemstack required by the recipe
ItemStack recipeStack = selectedType.driveableRecipe.get(recipeItemNumber);
//The total amount of items found that match this recipe stack
int totalAmountFound = 0;
//Iterate over the temporary inventory
for(int n = 0; n < temporaryInventory.getSizeInventory(); n++)
{
//Get the stack in each slot
ItemStack stackInSlot = temporaryInventory.getStackInSlot(n);
//If the stack is what we want
if(stackInSlot != null && stackInSlot.getItem() == recipeStack.getItem() && stackInSlot.getItemDamage() == recipeStack.getItemDamage())
{
//Work out the amount to take from the stack
int amountFound = Math.min(stackInSlot.stackSize, recipeStack.stackSize - totalAmountFound);
//Take it
stackInSlot.stackSize -= amountFound;
//Check for empty stacks
if(stackInSlot.stackSize <= 0)
stackInSlot = null;
//Put the modified stack back in the inventory
temporaryInventory.setInventorySlotContents(n, stackInSlot);
//Increase the amount found counter
totalAmountFound += amountFound;
//If we have enough, stop looking
if(totalAmountFound == recipeStack.stackSize)
break;
}
}
//If we didn't find enough, give the stack a red outline
if(totalAmountFound < recipeStack.stackSize)
{
mc.renderEngine.bindTexture(texture);
drawTexturedModalRect(guiOriginX + 8 + c * 18, guiOriginY + 138 + r * 18, 195, 11, 16, 16);
canCraft = false;
}
//Draw the actual item we want
drawSlotInventory(recipeStack, guiOriginX + 8 + c * 18, guiOriginY + 138 + r * 18);
}
}
}
//Collect up all the engines into neat and tidy stacks so we can find if any of them are big enough and which of those stacks are best
HashMap<PartType, ItemStack> engines = new HashMap<PartType, ItemStack>();
//Find some suitable engines
for(int n = 0; n < temporaryInventory.getSizeInventory(); n++)
{
//Get the stack in each slot
ItemStack stackInSlot = temporaryInventory.getStackInSlot(n);
//Check to see if its a part
if(stackInSlot != null && stackInSlot.getItem() instanceof ItemPart)
{
PartType partType = ((ItemPart)stackInSlot.getItem()).type;
//Check its an engine that we can use
if(partType.category == EnumPartCategory.ENGINE && partType.worksWith.contains(EnumType.getFromObject(selectedType)))
{
//If we already have engines of this type, add these ones to the stack
if(engines.containsKey(partType))
{
engines.get(partType).stackSize += stackInSlot.stackSize;
}
//Else, make this the first stack
else engines.put(partType, stackInSlot);
}
}
}
//Find the stack of engines that is fastest but which also has enough for this driveable
float bestEngineSpeed = -1F;
ItemStack bestEngineStack = null;
for(PartType part : engines.keySet())
{
//If this engine outperforms the currently selected best one and there are enough of them, swap
if(part.engineSpeed > bestEngineSpeed && engines.get(part).stackSize >= selectedType.numEngines())
{
bestEngineSpeed = part.engineSpeed;
bestEngineStack = engines.get(part);
}
}
//If we didn't find a suitable stack of engines, red the box out
mc.renderEngine.bindTexture(texture);
if(bestEngineStack == null)
{
drawTexturedModalRect(guiOriginX + 152, guiOriginY + 138, 195, 11, 16, 16);
canCraft = false;
}
//But if we did, render the stack
else
{
//drawTexturedModalRect(guiOriginX + 152, guiOriginY + 138, 213, 11, 16, 16);
drawSlotInventory(bestEngineStack, guiOriginX + 152, guiOriginY + 138);
}
}
//If we can't craft it, draw a red box around the craft button
if(!canCraft)
{
mc.renderEngine.bindTexture(texture);
drawTexturedModalRect(guiOriginX + 108, guiOriginY + 160, 176, 28, 44, 24);
drawString(fontRendererObj, "Craft", guiOriginX + 116, guiOriginY + 168, 0xa0a0a0);
}
//If we can craft it, draw the button for crafting
else
{
super.drawScreen(i, j, f);
}
}
/** Item stack renderering method */
private void drawSlotInventory(ItemStack itemstack, int i, int j)
{
if(itemstack == null || itemstack.getItem() == null)
return;
itemRenderer.renderItemIntoGUI(itemstack, i, j);
itemRenderer.renderItemOverlayIntoGUI(fontRendererObj, itemstack, i, j, null);
}
@Override
protected void keyTyped(char c, int i)
{
if (i == 1 || i == mc.gameSettings.keyBindInventory.getKeyCode())
{
mc.thePlayer.closeScreen();
}
}
@Override
protected void mouseClicked(int i, int j, int k) throws IOException
{
super.mouseClicked(i, j, k);
int x = i - guiOriginX;
int y = j - guiOriginY;
if (k == 0 || k == 1)
{
//Driveable buttons
for(int m = 0; m < 2; m++)
{
for(int n = 0; n < 8; n++)
{
if(x >= 8 + n * 18 && x <= 26 + n * 18 && y >= 18 + 18 * m && y <= 42 + 18 * m)
selectedBlueprint = blueprintsScroll * 8 + m * 8 + n;
}
}
//Blueprints back button
if(x >= 157 && x <= 167 && y >= 21 && y <= 31)
{
if(blueprintsScroll > 0)
blueprintsScroll--;
}
//Blueprints forwards button
if(x >= 157 && x <= 167 && y >= 39 && y <= 49)
{
if(blueprintsScroll * 8 + 16 < DriveableType.types.size())
blueprintsScroll++;
}
//Return if the selectedBlueprint is invalid
if(selectedBlueprint >= DriveableType.types.size())
{
return;
}
//Recipe back button
if(x >= 83 && x <= 93 && y >= 141 && y <= 151)
{
if(recipeScroll > 0)
recipeScroll--;
}
//Recipe forwards button
if(x >= 83 && x <= 93 && y >= 177 && y <= 187)
{
DriveableType selectedType = DriveableType.types.get(selectedBlueprint);
if(selectedType != null && recipeScroll * 4 + 12 < selectedType.driveableRecipe.size())
recipeScroll++;
}
}
}
@Override
public boolean doesGuiPauseGame()
{
return false;
}
}