package org.bukkit.inventory;
import org.apache.commons.lang.Validate;
import org.bukkit.Material;
import org.bukkit.material.MaterialData;
import java.util.HashMap;
import java.util.Map;
/**
* Represents a shaped (ie normal) crafting recipe.
*/
public class ShapedRecipe implements Recipe
{
private ItemStack output;
private String[] rows;
private Map<Character, ItemStack> ingredients = new HashMap<Character, ItemStack>();
/**
* Create a shaped recipe to craft the specified ItemStack. The
* constructor merely determines the result and type; to set the actual
* recipe, you'll need to call the appropriate methods.
*
* @param result The item you want the recipe to create.
* @see ShapedRecipe#shape(String...)
* @see ShapedRecipe#setIngredient(char, Material)
* @see ShapedRecipe#setIngredient(char, Material, int)
* @see ShapedRecipe#setIngredient(char, MaterialData)
*/
public ShapedRecipe(ItemStack result)
{
this.output = new ItemStack(result);
}
/**
* Set the shape of this recipe to the specified rows. Each character
* represents a different ingredient; exactly what each character
* represents is set separately. The first row supplied corresponds with
* the upper most part of the recipe on the workbench e.g. if all three
* rows are supplies the first string represents the top row on the
* workbench.
*
* @param shape The rows of the recipe (up to 3 rows).
* @return The changed recipe, so you can chain calls.
*/
public ShapedRecipe shape(final String... shape)
{
Validate.notNull(shape, "Must provide a shape");
Validate.isTrue(shape.length > 0 && shape.length < 4, "Crafting recipes should be 1, 2, 3 rows, not ", shape.length);
for(String row : shape)
{
Validate.notNull(row, "Shape cannot have null rows");
Validate.isTrue(row.length() > 0 && row.length() < 4, "Crafting rows should be 1, 2, or 3 characters, not ", row.length());
}
this.rows = new String[shape.length];
for(int i = 0; i < shape.length; i++)
{
this.rows[i] = shape[i];
}
// Remove character mappings for characters that no longer exist in the shape
HashMap<Character, ItemStack> newIngredients = new HashMap<Character, ItemStack>();
for(String row : shape)
{
for(Character c : row.toCharArray())
{
newIngredients.put(c, ingredients.get(c));
}
}
this.ingredients = newIngredients;
return this;
}
/**
* Sets the material that a character in the recipe shape refers to.
*
* @param key The character that represents the ingredient in the shape.
* @param ingredient The ingredient.
* @return The changed recipe, so you can chain calls.
*/
public ShapedRecipe setIngredient(char key, MaterialData ingredient)
{
return setIngredient(key, ingredient.getItemType(), ingredient.getData());
}
/**
* Sets the material that a character in the recipe shape refers to.
*
* @param key The character that represents the ingredient in the shape.
* @param ingredient The ingredient.
* @return The changed recipe, so you can chain calls.
*/
public ShapedRecipe setIngredient(char key, Material ingredient)
{
return setIngredient(key, ingredient, 0);
}
/**
* Sets the material that a character in the recipe shape refers to.
*
* @param key The character that represents the ingredient in the shape.
* @param ingredient The ingredient.
* @param raw The raw material data as an integer.
* @return The changed recipe, so you can chain calls.
* @deprecated Magic value
*/
@Deprecated
public ShapedRecipe setIngredient(char key, Material ingredient, int raw)
{
Validate.isTrue(ingredients.containsKey(key), "Symbol does not appear in the shape:", key);
// -1 is the old wildcard, map to Short.MAX_VALUE as the new one
if(raw == -1)
{
raw = Short.MAX_VALUE;
}
ingredients.put(key, new ItemStack(ingredient, 1, (short) raw));
return this;
}
/**
* Get a copy of the ingredients map.
*
* @return The mapping of character to ingredients.
*/
public Map<Character, ItemStack> getIngredientMap()
{
HashMap<Character, ItemStack> result = new HashMap<Character, ItemStack>();
for(Map.Entry<Character, ItemStack> ingredient : ingredients.entrySet())
{
if(ingredient.getValue() == null)
{
result.put(ingredient.getKey(), null);
}
else
{
result.put(ingredient.getKey(), ingredient.getValue().clone());
}
}
return result;
}
/**
* Get the shape.
*
* @return The recipe's shape.
*/
public String[] getShape()
{
return rows.clone();
}
/**
* Get the result.
*
* @return The result stack.
*/
public ItemStack getResult()
{
return output.clone();
}
}