// Path: src/main/java/com/gmail/jannyboy11/customrecipes/util/ReflectionUtil.java
// public final class ReflectionUtil {
// 	
// 	private ReflectionUtil() {}
// 	
// 	public static Field getDeclaredField(Object object, String fieldName) {
//         return getDeclaredFieldRecursively(object.getClass(), fieldName);
//     }
// 
//     public static Field getDeclaredFieldRecursively(Class<?> clazz, String fieldName) {
//         if (clazz == null) {
//             return null;
//         }
//         try {
//             Field field = clazz.getDeclaredField(fieldName);
//             field.setAccessible(true);
//             return field;
//         }
//         catch (NoSuchFieldException e) {
//             return getDeclaredFieldRecursively(clazz.getSuperclass(), fieldName);
//         }
//         catch (SecurityException e) {
//             e.printStackTrace();
//             return null;
//         }
//     }
// 
//     public static Object getDeclaredFieldValue(Object object, String fieldName) {
//         Field field = getDeclaredField(object, fieldName);
//         try {
//             return field.get(object);
//         }
//         catch (Exception e) {
//             e.printStackTrace();
//             return null;
//         }
//     }
// 
//     public static void setDeclaredFieldValue(Object object, String fieldName, Object value) {
//         Field field = getDeclaredField(object, fieldName);
//         try {
//             field.set(object, value);
//         }
//         catch (Exception e) {
//             e.printStackTrace();
//             return;
//         }
//     }
//     
//     public static void setFinalFieldValue(Object object, String fieldName, Object value) {
//     	Field field = getDeclaredField(object, fieldName);
//         try {
//         	Field modifiersField = Field.class.getDeclaredField("modifiers");
//         	modifiersField.setAccessible(true);
//         	modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
//         	
//             field.set(object, value);
//         }
//         catch (Exception e) {
//             e.printStackTrace();
//             return;
//         }
//     }
//     
//     public static Object getStaticFinalFieldValue(Class<?> clazz, String fieldName) {
//     	Field field = getDeclaredFieldRecursively(clazz, fieldName);
//     	try {
//     		Field modifiersField = Field.class.getDeclaredField("modifiers");
//     		modifiersField.setAccessible(true);
// 			modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
// 			return field.get(null);
// 		} catch (Exception e) {
// 			e.printStackTrace();
// 			return null;
// 		}
//     }
//     
//     public static void setStaticFinalFieldValue(Class<?> clazz, String fieldName, Object value) {
//    		Field field = getDeclaredFieldRecursively(clazz, fieldName);
//     	try {
//     		Field modifiersField = Field.class.getDeclaredField("modifiers");
//     		modifiersField.setAccessible(true);
// 			modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
// 			field.set(null, value);
// 		} catch (Exception e) {
// 			e.printStackTrace();
// 		}
//     }
// 
//     public static Method getDeclaredMethod(Object object, String methodName, Class<?> ... argTypes) {    	
//         return getDeclaredMethodRecursively(object.getClass(), methodName, argTypes);
//     }
// 
//     public static Method getDeclaredMethodRecursively(Class<?> clazz, String methodName, Class<?> ... argTypes) {
//         if (clazz == null) {
//             return null;
//         }
//         try {
//             Method method = clazz.getDeclaredMethod(methodName, argTypes);
//             method.setAccessible(true);
//             return method;
//         }
//         catch (NoSuchMethodException e) {
//             return getDeclaredMethodRecursively(clazz.getSuperclass(), methodName, argTypes);
//         }
//         catch (SecurityException e) {
//             e.printStackTrace();
//             return null;
//         }
//     }
// 
//     public static Object invokeInstanceMethod(Object instance, String methodName, Object ... args) {
//     	Class<?>[] argTypes = new Class[args.length];
//     	for (int i = 0; i < args.length; i++) {
//     		argTypes[i] = args[i].getClass();
//     	}
//     	
//         Method method = getDeclaredMethod(instance, methodName, argTypes);
//         try {
//             return method.invoke(instance, args);
//         }
//         catch (Exception e) {
//             e.printStackTrace();
//             return null;
//         }
//     }
//     
//     public static Object invokeStaticMethod(Class<?> clazz, String methodName, Object ... args) {
//     	Class<?>[] argTypes = new Class[args.length];
//     	for (int i = 0; i < args.length; i++) {
//     		argTypes[i] = args[i].getClass();
//     	}
//     	
// 		try {
// 			Method method = getDeclaredMethodRecursively(clazz, methodName, argTypes);
// 			return method.invoke(null, args);
// 		} catch (Exception e) {
// 			e.printStackTrace();
// 			return null;
// 		}
//     }
// 
// }


import com.gmail.jannyboy11.customrecipes.util.ReflectionUtil;
import net.minecraft.server.v1_12_R1.RecipeItemStack;
package com.gmail.jannyboy11.customrecipes.impl.crafting.custom.ingredient;



public class CountIngredient extends CombinedIngredient {
	
	private final RecipeItemStack basePredicate;
	private final int count;

	public CountIngredient(RecipeItemStack basePredicate, int count) {
		super(basePredicate, itemStack -> itemStack.getCount() == count, Boolean::logicalAnd);
		this.basePredicate = basePredicate;
		this.count = count;
	}
	
	@Override
	public RecipeItemStack asNMSIngredient() {
		RecipeItemStack recipeItemStack = super.asNMSIngredient();
// Path: src/main/java/com/gmail/jannyboy11/customrecipes/util/ReflectionUtil.java
// public final class ReflectionUtil {
// 	
// 	private ReflectionUtil() {}
// 	
// 	public static Field getDeclaredField(Object object, String fieldName) {
//         return getDeclaredFieldRecursively(object.getClass(), fieldName);
//     }
// 
//     public static Field getDeclaredFieldRecursively(Class<?> clazz, String fieldName) {
//         if (clazz == null) {
//             return null;
//         }
//         try {
//             Field field = clazz.getDeclaredField(fieldName);
//             field.setAccessible(true);
//             return field;
//         }
//         catch (NoSuchFieldException e) {
//             return getDeclaredFieldRecursively(clazz.getSuperclass(), fieldName);
//         }
//         catch (SecurityException e) {
//             e.printStackTrace();
//             return null;
//         }
//     }
// 
//     public static Object getDeclaredFieldValue(Object object, String fieldName) {
//         Field field = getDeclaredField(object, fieldName);
//         try {
//             return field.get(object);
//         }
//         catch (Exception e) {
//             e.printStackTrace();
//             return null;
//         }
//     }
// 
//     public static void setDeclaredFieldValue(Object object, String fieldName, Object value) {
//         Field field = getDeclaredField(object, fieldName);
//         try {
//             field.set(object, value);
//         }
//         catch (Exception e) {
//             e.printStackTrace();
//             return;
//         }
//     }
//     
//     public static void setFinalFieldValue(Object object, String fieldName, Object value) {
//     	Field field = getDeclaredField(object, fieldName);
//         try {
//         	Field modifiersField = Field.class.getDeclaredField("modifiers");
//         	modifiersField.setAccessible(true);
//         	modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
//         	
//             field.set(object, value);
//         }
//         catch (Exception e) {
//             e.printStackTrace();
//             return;
//         }
//     }
//     
//     public static Object getStaticFinalFieldValue(Class<?> clazz, String fieldName) {
//     	Field field = getDeclaredFieldRecursively(clazz, fieldName);
//     	try {
//     		Field modifiersField = Field.class.getDeclaredField("modifiers");
//     		modifiersField.setAccessible(true);
// 			modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
// 			return field.get(null);
// 		} catch (Exception e) {
// 			e.printStackTrace();
// 			return null;
// 		}
//     }
//     
//     public static void setStaticFinalFieldValue(Class<?> clazz, String fieldName, Object value) {
//    		Field field = getDeclaredFieldRecursively(clazz, fieldName);
//     	try {
//     		Field modifiersField = Field.class.getDeclaredField("modifiers");
//     		modifiersField.setAccessible(true);
// 			modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
// 			field.set(null, value);
// 		} catch (Exception e) {
// 			e.printStackTrace();
// 		}
//     }
// 
//     public static Method getDeclaredMethod(Object object, String methodName, Class<?> ... argTypes) {    	
//         return getDeclaredMethodRecursively(object.getClass(), methodName, argTypes);
//     }
// 
//     public static Method getDeclaredMethodRecursively(Class<?> clazz, String methodName, Class<?> ... argTypes) {
//         if (clazz == null) {
//             return null;
//         }
//         try {
//             Method method = clazz.getDeclaredMethod(methodName, argTypes);
//             method.setAccessible(true);
//             return method;
//         }
//         catch (NoSuchMethodException e) {
//             return getDeclaredMethodRecursively(clazz.getSuperclass(), methodName, argTypes);
//         }
//         catch (SecurityException e) {
//             e.printStackTrace();
//             return null;
//         }
//     }
// 
//     public static Object invokeInstanceMethod(Object instance, String methodName, Object ... args) {
//     	Class<?>[] argTypes = new Class[args.length];
//     	for (int i = 0; i < args.length; i++) {
//     		argTypes[i] = args[i].getClass();
//     	}
//     	
//         Method method = getDeclaredMethod(instance, methodName, argTypes);
//         try {
//             return method.invoke(instance, args);
//         }
//         catch (Exception e) {
//             e.printStackTrace();
//             return null;
//         }
//     }
//     
//     public static Object invokeStaticMethod(Class<?> clazz, String methodName, Object ... args) {
//     	Class<?>[] argTypes = new Class[args.length];
//     	for (int i = 0; i < args.length; i++) {
//     		argTypes[i] = args[i].getClass();
//     	}
//     	
// 		try {
// 			Method method = getDeclaredMethodRecursively(clazz, methodName, argTypes);
// 			return method.invoke(null, args);
// 		} catch (Exception e) {
// 			e.printStackTrace();
// 			return null;
// 		}
//     }
// 
// }


// Path: src/main/java/com/gmail/jannyboy11/customrecipes/impl/crafting/custom/ingredient/CountIngredient.java
import com.gmail.jannyboy11.customrecipes.util.ReflectionUtil;
import net.minecraft.server.v1_12_R1.RecipeItemStack;

package com.gmail.jannyboy11.customrecipes.impl.crafting.custom.ingredient;



public class CountIngredient extends CombinedIngredient {
	
	private final RecipeItemStack basePredicate;
	private final int count;

	public CountIngredient(RecipeItemStack basePredicate, int count) {
		super(basePredicate, itemStack -> itemStack.getCount() == count, Boolean::logicalAnd);
		this.basePredicate = basePredicate;
		this.count = count;
	}
	
	@Override
	public RecipeItemStack asNMSIngredient() {
		RecipeItemStack recipeItemStack = super.asNMSIngredient();
		ReflectionUtil.setFinalFieldValue(recipeItemStack, "choices", basePredicate.choices);