<commit_before>package mezz.jei.gui;

import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import mezz.jei.api.gui.IDrawable;
import mezz.jei.api.gui.IGuiFluidStackGroup;
import mezz.jei.api.gui.IGuiIngredientGroup;
import mezz.jei.api.gui.IRecipeLayout;
import mezz.jei.api.ingredients.IIngredients;
import mezz.jei.api.recipe.IFocus;
import mezz.jei.api.recipe.IRecipeCategory;
import mezz.jei.api.recipe.IRecipeWrapper;
import mezz.jei.gui.ingredients.GuiFluidStackGroup;
import mezz.jei.gui.ingredients.GuiIngredient;
import mezz.jei.gui.ingredients.GuiIngredientGroup;
import mezz.jei.gui.ingredients.GuiItemStackGroup;
import mezz.jei.input.IClickedIngredient;
import mezz.jei.util.Ingredients;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.FluidStack;

public class RecipeLayout implements IRecipeLayout {
	private static final int RECIPE_BUTTON_SIZE = 12;
	public static final int recipeTransferButtonIndex = 100;

	private final IRecipeCategory recipeCategory;
	private final GuiItemStackGroup guiItemStackGroup;
	private final GuiFluidStackGroup guiFluidStackGroup;
	private final Map<Class, GuiIngredientGroup> guiIngredientGroups;
	private final RecipeTransferButton recipeTransferButton;
	private final IRecipeWrapper recipeWrapper;
	private final IFocus<?> focus;

	private final int posX;
	private final int posY;

	public <T extends IRecipeWrapper> RecipeLayout(int index, int posX, int posY, IRecipeCategory<T> recipeCategory, T recipeWrapper, IFocus focus) {
		this.recipeCategory = recipeCategory;
		this.focus = focus;

		ItemStack itemStackFocus = null;
		FluidStack fluidStackFocus = null;
		Object focusValue = focus.getValue();
		if (focusValue instanceof ItemStack) {
			itemStackFocus = (ItemStack) focusValue;
		} else if (focusValue instanceof FluidStack) {
			fluidStackFocus = (FluidStack) focusValue;
		}
		this.guiItemStackGroup = new GuiItemStackGroup(new Focus<ItemStack>(focus.getMode(), itemStackFocus));
		this.guiFluidStackGroup = new GuiFluidStackGroup(new Focus<FluidStack>(focus.getMode(), fluidStackFocus));

		this.guiIngredientGroups = new HashMap<Class, GuiIngredientGroup>();
		this.guiIngredientGroups.put(ItemStack.class, this.guiItemStackGroup);
		this.guiIngredientGroups.put(FluidStack.class, this.guiFluidStackGroup);

		int width = recipeCategory.getBackground().getWidth();
		int height = recipeCategory.getBackground().getHeight();
		this.recipeTransferButton = new RecipeTransferButton(recipeTransferButtonIndex + index, posX + width + 2, posY + height - RECIPE_BUTTON_SIZE, RECIPE_BUTTON_SIZE, RECIPE_BUTTON_SIZE, "+");
		this.posX = posX;
		this.posY = posY;

		this.recipeWrapper = recipeWrapper;

		try {
			IIngredients ingredients = new Ingredients();
			recipeWrapper.getIngredients(ingredients);
			recipeCategory.setRecipe(this, recipeWrapper, ingredients);
		} catch (LinkageError ignored) { // legacy
			recipeCategory.setRecipe(this, recipeWrapper);
		}
	}

	public void draw(Minecraft minecraft, int mouseX, int mouseY) {
		IDrawable background = recipeCategory.getBackground();

		GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
		GlStateManager.disableLighting();
		GlStateManager.enableAlpha();

		GlStateManager.pushMatrix();
		GlStateManager.translate(posX, posY, 0.0F);
		{
			background.draw(minecraft);<commit_msg>Defend against crashes from recipes (#488, #491, #497)<commit_after>package mezz.jei.gui;

import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import mezz.jei.api.gui.IDrawable;
import mezz.jei.api.gui.IGuiFluidStackGroup;
import mezz.jei.api.gui.IGuiIngredientGroup;
import mezz.jei.api.gui.IRecipeLayout;
import mezz.jei.api.ingredients.IIngredients;
import mezz.jei.api.recipe.IFocus;
import mezz.jei.api.recipe.IRecipeCategory;
import mezz.jei.api.recipe.IRecipeWrapper;
import mezz.jei.gui.ingredients.GuiFluidStackGroup;
import mezz.jei.gui.ingredients.GuiIngredient;
import mezz.jei.gui.ingredients.GuiIngredientGroup;
import mezz.jei.gui.ingredients.GuiItemStackGroup;
import mezz.jei.input.IClickedIngredient;
import mezz.jei.util.Ingredients;
import mezz.jei.util.Log;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.FluidStack;

public class RecipeLayout implements IRecipeLayout {
	private static final int RECIPE_BUTTON_SIZE = 12;
	public static final int recipeTransferButtonIndex = 100;

	private final IRecipeCategory recipeCategory;
	private final GuiItemStackGroup guiItemStackGroup;
	private final GuiFluidStackGroup guiFluidStackGroup;
	private final Map<Class, GuiIngredientGroup> guiIngredientGroups;
	private final RecipeTransferButton recipeTransferButton;
	private final IRecipeWrapper recipeWrapper;
	private final IFocus<?> focus;

	private final int posX;
	private final int posY;

	public <T extends IRecipeWrapper> RecipeLayout(int index, int posX, int posY, IRecipeCategory<T> recipeCategory, T recipeWrapper, IFocus focus) {
		this.recipeCategory = recipeCategory;
		this.focus = focus;

		ItemStack itemStackFocus = null;
		FluidStack fluidStackFocus = null;
		Object focusValue = focus.getValue();
		if (focusValue instanceof ItemStack) {
			itemStackFocus = (ItemStack) focusValue;
		} else if (focusValue instanceof FluidStack) {
			fluidStackFocus = (FluidStack) focusValue;
		}
		this.guiItemStackGroup = new GuiItemStackGroup(new Focus<ItemStack>(focus.getMode(), itemStackFocus));
		this.guiFluidStackGroup = new GuiFluidStackGroup(new Focus<FluidStack>(focus.getMode(), fluidStackFocus));

		this.guiIngredientGroups = new HashMap<Class, GuiIngredientGroup>();
		this.guiIngredientGroups.put(ItemStack.class, this.guiItemStackGroup);
		this.guiIngredientGroups.put(FluidStack.class, this.guiFluidStackGroup);

		int width = recipeCategory.getBackground().getWidth();
		int height = recipeCategory.getBackground().getHeight();
		this.recipeTransferButton = new RecipeTransferButton(recipeTransferButtonIndex + index, posX + width + 2, posY + height - RECIPE_BUTTON_SIZE, RECIPE_BUTTON_SIZE, RECIPE_BUTTON_SIZE, "+");
		this.posX = posX;
		this.posY = posY;

		this.recipeWrapper = recipeWrapper;

		try {
			try {
				IIngredients ingredients = new Ingredients();
				recipeWrapper.getIngredients(ingredients);
				recipeCategory.setRecipe(this, recipeWrapper, ingredients);
			} catch (LinkageError ignored) { // legacy
				recipeCategory.setRecipe(this, recipeWrapper);
			}
		} catch (RuntimeException e) {
			Log.error("Error caught from Recipe Category: {}", recipeCategory.getClass().getCanonicalName(), e);
		} catch (LinkageError e) {
			Log.error("Error caught from Recipe Category: {}", recipeCategory.getClass().getCanonicalName(), e);
		}
	}

	public void draw(Minecraft minecraft, int mouseX, int mouseY) {
		IDrawable background = recipeCategory.getBackground();

		GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
		GlStateManager.disableLighting();
		GlStateManager.enableAlpha();

		GlStateManager.pushMatrix();
		GlStateManager.translate(posX, posY, 0.0F);
		{
			background.draw(minecraft);
{'fraction_non_alphanumeric': 0.09887238723872387, 'fraction_numerical': 0.005638063806380638, 'mean_word_length': 5.959808612440192, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '360733', 'n_tokens_mistral': 2526, 'n_tokens_neox': 2367, 'n_words': 475}