package slimeknights.tconstruct.plugin.jei;
import com.google.common.collect.ImmutableList;
import net.minecraft.block.Block;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
import net.minecraftforge.oredict.OreDictionary;
import net.minecraftforge.oredict.ShapedOreRecipe;
import java.util.Arrays;
import java.util.List;
import javax.annotation.Nonnull;
import mezz.jei.api.gui.IGuiIngredientGroup;
import mezz.jei.api.gui.IGuiItemStackGroup;
import mezz.jei.api.gui.IRecipeLayout;
import mezz.jei.api.ingredients.IIngredients;
import mezz.jei.api.recipe.BlankRecipeWrapper;
import mezz.jei.api.recipe.IFocus;
import mezz.jei.api.recipe.IStackHelper;
import mezz.jei.api.recipe.wrapper.ICustomCraftingRecipeWrapper;
import mezz.jei.api.recipe.wrapper.IShapedCraftingRecipeWrapper;
import slimeknights.tconstruct.shared.block.BlockTable;
import slimeknights.tconstruct.tools.common.TableRecipe;
import slimeknights.tconstruct.tools.common.item.ItemBlockTable;
public class TableRecipeWrapper extends BlankRecipeWrapper implements IShapedCraftingRecipeWrapper, ICustomCraftingRecipeWrapper {
private final TableRecipe recipe;
private final int width;
private final int height;
private final List<ItemStack> outputs;
public TableRecipeWrapper(TableRecipe recipe) {
this.recipe = recipe;
for (Object input : this.recipe.getInput()) {
if (input instanceof ItemStack) {
ItemStack itemStack = (ItemStack) input;
if (itemStack.stackSize != 1) {
itemStack.stackSize = 1;
}
}
}
this.width = ObfuscationReflectionHelper.getPrivateValue(ShapedOreRecipe.class, this.recipe, "width");
this.height = ObfuscationReflectionHelper.getPrivateValue(ShapedOreRecipe.class, this.recipe, "height");
// sort the output entries into lists of items
ImmutableList.Builder<ItemStack> builder = ImmutableList.builder();
for(ItemStack stack : recipe.outputBlocks) {
BlockTable block = (BlockTable) BlockTable.getBlockFromItem(recipe.getRecipeOutput().getItem());
Block legBlock = Block.getBlockFromItem(stack.getItem());
if(stack.getItemDamage() == OreDictionary.WILDCARD_VALUE) {
for(ItemStack sub : JEIPlugin.jeiHelpers.getStackHelper().getSubtypes(stack)) {
builder.add(BlockTable.createItemstack(block, recipe.getRecipeOutput().getItemDamage(), legBlock, sub.getItemDamage()));
}
}
else {
builder.add(BlockTable.createItemstack(block, recipe.getRecipeOutput().getItemDamage(), legBlock, stack.getItemDamage()));
}
}
outputs = builder.build();
}
@Override
public void getIngredients(IIngredients ingredients) {
IStackHelper stackHelper = JEIPlugin.jeiHelpers.getStackHelper();
List<List<ItemStack>> inputs = stackHelper.expandRecipeItemStackInputs(Arrays.asList(recipe.getInput()));
ingredients.setInputLists(ItemStack.class, inputs);
//ItemStack recipeOutput = recipe.getRecipeOutput();
if (!outputs.isEmpty()) {
ingredients.setOutputs(ItemStack.class, outputs);
}
}
@SuppressWarnings("rawtypes")
@Override
@Deprecated
public List getInputs() {
return Arrays.asList(recipe.getInput());
}
@Nonnull
@Override
public List<ItemStack> getOutputs() {
return outputs;
}
@Override
public int getWidth() {
return width;
}
@Override
public int getHeight() {
return height;
}
private boolean isOutputBlock(ItemStack stack) {
if(stack == null) {
return false;
}
for(ItemStack output : recipe.outputBlocks) {
// if the item matches the oredict entry, it is an output block
if(OreDictionary.itemMatches(output, stack, false)) {
return true;
}
}
return false;
}
@Override
public void setRecipe(IRecipeLayout recipeLayout, IIngredients ingredients) {
IGuiItemStackGroup guiItemStacks = recipeLayout.getItemStacks();
List<List<ItemStack>> inputs = ingredients.getInputs(ItemStack.class);
List<ItemStack> outputs = ingredients.getOutputs(ItemStack.class);
// determine the focused stack
IFocus<?> ifocus = recipeLayout.getFocus();
Object focusObj = ifocus.getValue();
// if the thing in focus is an itemstack
if(focusObj instanceof ItemStack) {
IGuiIngredientGroup<ItemStack> guiIngredients = recipeLayout.getIngredientsGroup(ItemStack.class);
ItemStack focus = (ItemStack)focusObj;
IFocus.Mode mode = ifocus.getMode();
// input means we clicked on an ingredient, make sure it is one that affects the legs
if(mode == IFocus.Mode.INPUT && isOutputBlock(focus)) {
// first, get the output recipe
ItemStack output = recipe.getPlainRecipeOutput();
BlockTable block = (BlockTable) Block.getBlockFromItem(output.getItem());
// then create a stack with the focus item (which we already validated above)
ItemStack outputFocus = BlockTable.createItemstack(block, output.getItemDamage(), Block.getBlockFromItem(focus.getItem()),
focus.getItemDamage());
// and finally, set the focus override for the recipe
guiIngredients.setOverrideDisplayFocus(new Focus<ItemStack>(IFocus.Mode.OUTPUT, outputFocus));
}
// if we clicked the table, remove all items which affect the legs textures that are not the leg item
else if(mode == IFocus.Mode.OUTPUT) {
// so determine the legs
ItemStack legs = ItemBlockTable.getLegStack(focus);
if(legs != null) {
// and loop through all slots removing leg affecting inputs which don't match
guiIngredients.setOverrideDisplayFocus(new Focus<ItemStack>(IFocus.Mode.INPUT, legs));
}
}
}
// add the itemstacks to the grid
JEIPlugin.craftingGridHelper.setInputStacks(guiItemStacks, inputs, this.getWidth(), this.getHeight());
JEIPlugin.craftingGridHelper.setOutput(guiItemStacks, outputs);
}
}