package net.t7seven7t.craftfx.recipe;
import net.t7seven7t.craftfx.CraftFX;
import net.t7seven7t.craftfx.item.ItemRegistry;
import org.apache.commons.lang.Validate;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.ShapedRecipe;
import java.util.HashMap;
import java.util.Map;
/**
* Wrapper for Bukkit's ShapedRecipe that allows setting ingredients with ItemStack info
*/
public class FXShapedRecipe extends ShapedRecipe implements FXRecipe {
private Map<Character, ItemStack> ingredients = new HashMap<>();
private ItemStack[] items;
private int width, height;
/**
* {@inheritDoc}
*/
public FXShapedRecipe(ItemStack result) {
super(result);
}
public FXShapedRecipe setIngredient(char key, ItemStack ingredient) {
Validate.isTrue(super.getIngredientMap().containsKey(key),
"Symbol does not appear in the shape: " + key);
ingredients.put(key, ingredient);
return this;
}
FXShapedRecipe setIngredient(Ingredient ingredient) {
return setIngredient(ingredient.key, ingredient.item);
}
/**
* {@inheritDoc}
*/
@Override
public ShapedRecipe shape(String... shape) {
width = 0;
height = 0;
for (String row : shape) {
height++;
int w = row.toCharArray().length;
if (w > width) {
width = w;
}
}
return super.shape(shape);
}
/**
* {@inheritDoc}
*/
@Override
public Map<Character, ItemStack> getIngredientMap() {
Map<Character, ItemStack> result = new HashMap<>();
for (Map.Entry<Character, ItemStack> entry : ingredients.entrySet()) {
result.put(entry.getKey(), entry.getValue() == null ? null : entry.getValue().clone());
}
return result;
}
/**
* Returns whether this recipe is correct for the ingredients of a specified crafting matrix
*/
public boolean matches(ItemStack[] matrix) {
String shape = "";
if (items == null) {
items = new ItemStack[width * height];
for (int j = 0; j < height; j++) {
shape = shape + getShape()[j];
}
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
items[i + j] = ingredients.get(shape.toCharArray()[i + j]);
}
}
}
for (int i = 0; i <= 3 - width; i++) {
for (int j = 0; j <= 3 - height; j++) {
if (matches(matrix, i, j, true) || matches(matrix, i, j, false)) {
return true;
}
}
}
return false;
}
private boolean matches(ItemStack[] matrix, int iOff, int jOff, boolean reverse) {
ItemStack item1, item2;
ItemRegistry registry = CraftFX.instance().getItemRegistry();
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
int i1 = i - iOff;
int j1 = j - jOff;
item1 = null;
if (i1 >= 0 && j1 >= 0 && i1 < width && j1 < height) {
if (reverse) {
item1 = items[width - i1 - 1 + j1 * width];
} else {
item1 = items[i1 + j1 * width];
}
}
int rowLen = matrix.length == 5 ? 2 : 3;
item2 = matrix[i + j * rowLen];
if (!registry.isSimilar(item1, item2)) {
return false;
}
}
}
return true;
}
}