package gory_moon.moarsigns.integration.tweaker;
import gory_moon.moarsigns.api.MaterialInfo;
import gory_moon.moarsigns.api.ShapedMoarSignRecipe;
import gory_moon.moarsigns.api.ShapedMoarSignRecipe.MatchType;
import gory_moon.moarsigns.api.ShapelessMoarSignRecipe;
import gory_moon.moarsigns.api.SignInfo;
import gory_moon.moarsigns.items.ItemMoarSign;
import gory_moon.moarsigns.items.ModItems;
import minetweaker.IUndoableAction;
import minetweaker.MineTweakerAPI;
import minetweaker.api.item.IIngredient;
import minetweaker.api.item.IItemStack;
import minetweaker.api.minecraft.MineTweakerMC;
import minetweaker.api.oredict.IOreDictEntry;
import minetweaker.mc1102.item.MCItemStack;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.CraftingManager;
import net.minecraft.item.crafting.IRecipe;
import stanhebben.zenscript.annotations.ZenClass;
import stanhebben.zenscript.annotations.ZenMethod;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@ZenClass("mods.MoarSigns")
public class Signs {
private static List<ItemStack> signs = new ArrayList<ItemStack>();
@ZenMethod
public static void addShaped(IItemStack output, IIngredient[][] ingredients) {
MineTweakerAPI.apply(new Add(false, toStack(output), toShapedObjects(ingredients)));
}
@ZenMethod
public static void addShapeless(IItemStack output, IIngredient[] ingredients) {
MineTweakerAPI.apply(new Add(true, toStack(output), toObjects(ingredients)));
}
@ZenMethod
public static void removeRecipes(IItemStack output) {
MineTweakerAPI.apply(new Remove(toStack(output)));
}
@ZenMethod
public static void removeRecipes(IItemStack[] output) {
MineTweakerAPI.apply(new Remove(toStacks(output)));
}
@ZenMethod
public static IItemStack[] getSigns(IIngredient ingredient) {
IItemStack[] base = new IItemStack[0];
if (ingredient instanceof MatchTypeEntry || ingredient instanceof MaterialEntry) {
if (signs.isEmpty()) {
ModItems.SIGN.getSubItemStacks(Signs.signs);
}
ArrayList<IItemStack> signs = new ArrayList<IItemStack>();
if (ingredient instanceof MatchTypeEntry) {
for (ItemStack stack : Signs.signs) {
SignInfo info = ItemMoarSign.getInfo(stack.getTagCompound());
if (ingredient.getInternal() == MatchType.ALL)
signs.add(new MCItemStack(stack));
else if (ingredient.getInternal() == MatchType.METAL && info.isMetal)
signs.add(new MCItemStack(stack));
else if (ingredient.getInternal() == MatchType.WOOD && !info.isMetal)
signs.add(new MCItemStack(stack));
}
} else {
for (ItemStack stack : Signs.signs) {
SignInfo info = ItemMoarSign.getInfo(stack.getTagCompound());
if (((MaterialInfo) ingredient.getInternal()).materialName.equals(info.material.materialName) && (((MaterialEntry) ingredient).getModID() == null || ((MaterialEntry) ingredient).getModID().equals(info.activateTag)))
signs.add(new MCItemStack(stack));
}
}
return signs.toArray(base);
}
return Collections.emptyList().toArray(base);
}
@ZenMethod
public static IItemStack getFirstSign(IIngredient ingredient) {
IItemStack[] signs = getSigns(ingredient);
if (signs != null && signs.length > 0)
return signs[0];
return null;
}
public static ItemStack toStack(IItemStack iStack) {
return MineTweakerMC.getItemStack(iStack);
}
public static ItemStack[] toStacks(IItemStack[] iStack) {
if (iStack == null)
return null;
else {
ItemStack[] output = new ItemStack[iStack.length];
for (int i = 0; i < iStack.length; i++) {
output[i] = toStack(iStack[i]);
}
return output;
}
}
public static Object toObject(IIngredient iStack) {
if (iStack == null)
return null;
else {
if (iStack instanceof IOreDictEntry) {
return toString((IOreDictEntry) iStack);
} else if (iStack instanceof IItemStack) {
return toStack((IItemStack) iStack);
} else if (iStack instanceof MatchTypeEntry) {
return (MatchType) iStack.getInternal();
} else if (iStack instanceof MaterialEntry) {
return (MaterialInfo) iStack.getInternal();
} else
return null;
}
}
public static Object[] toObjects(IIngredient[] ingredient) {
if (ingredient == null)
return null;
else {
Object[] output = new Object[ingredient.length];
for (int i = 0; i < ingredient.length; i++) {
if (ingredient[i] != null) {
output[i] = toObject(ingredient[i]);
} else
output[i] = "";
}
return output;
}
}
public static Object[] toShapedObjects(IIngredient[][] ingredients) {
if (ingredients == null)
return null;
else {
ArrayList prep = new ArrayList();
prep.add("abc");
prep.add("def");
prep.add("ghi");
char[][] map = new char[][]{{'a', 'b', 'c'}, {'d', 'e', 'f'}, {'g', 'h', 'i'}};
for (int x = 0; x < ingredients.length; x++) {
if (ingredients[x] != null) {
for (int y = 0; y < ingredients[x].length; y++) {
if (ingredients[x][y] != null && x < map.length && y < map[x].length) {
prep.add(map[x][y]);
prep.add(toObject(ingredients[x][y]));
}
}
}
}
return prep.toArray();
}
}
public static String toString(IOreDictEntry entry) {
return ((IOreDictEntry) entry).getName();
}
private static class Add implements IUndoableAction {
private final boolean isShapeless;
private final ItemStack output;
private final Object[] recipe;
private IRecipe iRecipe;
public Add(boolean isShapeless, ItemStack output, Object... recipe) {
this.isShapeless = isShapeless;
this.output = output;
this.recipe = recipe;
}
@Override
public void apply() {
if (isShapeless)
iRecipe = new ShapelessMoarSignRecipe(output, true, recipe);
else
iRecipe = new ShapedMoarSignRecipe(output, recipe);
CraftingManager.getInstance().getRecipeList().add(iRecipe);
MineTweakerAPI.getIjeiRecipeRegistry().addRecipe(iRecipe);
}
@Override
public boolean canUndo() {
return CraftingManager.getInstance().getRecipeList() != null;
}
@Override
public void undo() {
CraftingManager.getInstance().getRecipeList().remove(iRecipe);
MineTweakerAPI.getIjeiRecipeRegistry().removeRecipe(iRecipe);
}
@Override
public String describe() {
return "Adding MoarSign recipe for " + output.getDisplayName();
}
@Override
public String describeUndo() {
return "Removing MoarSign recipe for " + output.getDisplayName();
}
@Override
public Object getOverrideKey() {
return null;
}
}
private static class Remove implements IUndoableAction {
private final ItemStack[] outputs;
private ArrayList<IRecipe> iRecipes;
public Remove(ItemStack output) {
this.outputs = new ItemStack[1];
this.outputs[0] = output;
}
public Remove(ItemStack[] outputs) {
this.outputs = outputs;
}
@Override
public void apply() {
List allRecipes = CraftingManager.getInstance().getRecipeList();
iRecipes = new ArrayList<>();
for (Object obj : allRecipes) {
IRecipe recipe = (IRecipe) obj;
for (ItemStack output : outputs) {
if ((recipe instanceof ShapedMoarSignRecipe || recipe instanceof ShapelessMoarSignRecipe) && recipe.getRecipeOutput() != null && ItemStack.areItemStackTagsEqual(recipe.getRecipeOutput(), output)) {
iRecipes.add(recipe);
}
}
}
for (IRecipe recipe : iRecipes) {
CraftingManager.getInstance().getRecipeList().remove(recipe);
MineTweakerAPI.getIjeiRecipeRegistry().removeRecipe(recipe);
}
}
@Override
public boolean canUndo() {
return CraftingManager.getInstance().getRecipeList() != null && iRecipes != null && !iRecipes.isEmpty();
}
@Override
public void undo() {
for (IRecipe recipe : iRecipes) {
CraftingManager.getInstance().getRecipeList().add(recipe);
MineTweakerAPI.getIjeiRecipeRegistry().addRecipe(recipe);
}
}
@Override
public String describe() {
String s = "";
for (ItemStack output : outputs)
s += "Removing MoarSign recipe for " + output.getDisplayName() + "\n";
return s;
}
@Override
public String describeUndo() {
String s = "";
for (ItemStack output : outputs)
s += "Restoring MoarSign recipe for " + output.getDisplayName() + "\n";
return s;
}
@Override
public Object getOverrideKey() {
return null;
}
}
}