/* ===================================================================
 * RecipeBiz.java
 * 
 * Created Aug 4, 2004 11:16:49 AM
 * 
 * Copyright (c) 2004 Matt Magoffin (spamsqr@msqr.us)
 * 
 * This program is free software; you can redistribute it and/or 
 * modify it under the terms of the GNU General Public License as 
 * published by the Free Software Foundation; either version 2 of 
 * the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License 
 * along with this program; if not, write to the Free Software 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 
 * 02111-1307 USA
 * ===================================================================
 * $Id: RecipeBiz.java 39 2009-05-06 03:30:47Z msqr $
 * ===================================================================
 */

package magoffin.matt.ieat.biz;

import java.util.List;

import magoffin.matt.ieat.domain.Base;
import magoffin.matt.ieat.domain.Course;
import magoffin.matt.ieat.domain.Difficulty;
import magoffin.matt.ieat.domain.Ethnicity;
import magoffin.matt.ieat.domain.Ingredient;
import magoffin.matt.ieat.domain.Meal;
import magoffin.matt.ieat.domain.MealRecipe;
import magoffin.matt.ieat.domain.PrepTime;
import magoffin.matt.ieat.domain.Recipe;
import magoffin.matt.ieat.domain.RecipeComment;
import magoffin.matt.ieat.domain.RecipeRating;
import magoffin.matt.ieat.domain.System;
import magoffin.matt.ieat.domain.Unit;
import magoffin.matt.util.TemporaryFile;

/**
 * Business interface for recipes.
 * 
 * @author Matt Magoffin (spamsqr@msqr.us)
 * @version $Revision: 39 $ $Date: 2009-05-06 15:30:47 +1200 (Wed, 06 May 2009) $
 */
public interface RecipeBiz {
	
	/** The US measurement system constant. */
	public static final Integer US_SYSTEM_ID = 1;
	
	/** The Metric measurement system constant. */
	public static final Integer METRIC_SYSTEM_ID = 2;
	
	/**
	 * Get a Recipe by its ID.
	 * @param recipeId the ID of the recipe to get
	 * @return Recipe
	 */
	public Recipe getRecipeById(Long recipeId);

	/**
	 * Get a list of configured Base types.
	 * @return list of Base objects
	 */
	public List<Base> getAvailableBases();

	/**
	 * Get a list of configured Course types.
	 * @return list of Course objects
	 */
	public List<Course> getAvailableCourses();

	/**
	 * Get a list of configured Difficulty types.
	 * @return list of Difficulty objects
	 */
	public List<Difficulty> getAvailableDifficulties();

	/**
	 * Get a list of configured Ethnicity types.
	 * @return list of Ethnicity objects
	 */
	public List<Ethnicity> getAvailableEthnicities();
	
	/**
	 * Get a list of available Ingredient types.
	 * @return list of Ingredient objects
	 */
	public List<Ingredient> getAvailableIngredients();

	/**
	 * Get a list of configured PrepTime types.
	 * @return list of PrepTime objects
	 */
	public List<PrepTime> getAvailablePrepTimes();

	/**
	 * Get a list of configured system Unit types.
	 * @return list of Unit objects
	 */
	public List<System> getAvailableUnitSystems();
	
	/**
	 * Get a list of configured Units relevant to a given System.
	 * @param sys the System to get Units for
	 * @return list of Unit objects
	 */
	public List<Unit> getAvailableUnitsForSystem(System sys);
	
	/**
	 * Store a Recipe in the back end.
	 * @param r the recipe to store
	 * @param context the current context
	 * @return the stored recipe
	 */
	public Recipe storeRecipe(Recipe r, BizContext context);
	
	/**
	 * Remove a recipe from the back end.
	 * @param recipeId the ID of the recipe to remove
	 * @param context the current context
	 */
	public void removeRecipe(Long recipeId, BizContext context);
	
	/**
	 * Store an Ingredient in the back end.
	 * @param ingredient the ingredient to store
	 * @param context the current context
	 * @return the stored ingredient
	 */
	public Ingredient storeIngredient(Ingredient ingredient, BizContext context);
	
	/**
	 * Remove an Ingredient from the back end.
	 * @param ingredientId the ID of the Ingredient to remove
	 */
	public void removeIngredient(Integer ingredientId);
	
	/**
	 * Store a Meal in the back end.
	 * @param meal the meal to store
	 * @param context the current context
	 * @return the stored meal
	 */
	public Meal storeMeal(Meal meal, BizContext context);
	
	/**
	 * Get a list of Meal objects owned by a particular user.
	 * @param userId the ID of the User to get Meals for
	 * @param context the current context
	 * @return the list of Meal objects (never <em>null</em>)
	 */
	public List<Meal> getMealsForUser(Integer userId, BizContext context);

	/**
	 * Get a Meal by its ID.
	 * @param mealId the ID of the meal to get
	 * @param context the current context
	 * @return Meal
	 */
	public Meal getMealById(Long mealId, BizContext context);

	/**
	 * Remove a Meal from the back end.
	 * @param mealId the ID of the Meal to remove
	 * @param context the current context
	 */
	public void removeMeal(Long mealId, BizContext context);
	
	/**
	 * Add a meal to a recipe.
	 * @param mealId the ID of the meal to add the recipe to
	 * @param mr the recipe to add
	 * @param context the current context
	 * @return the complete Meal
	 */
	public Meal addRecipeToMeal(Long mealId, MealRecipe mr, BizContext context);
	
	/**
	 * Return a Recipe containing RecipeIngredient objects representing a shopping list.
	 * @param mealId the meal ID to generate the shopping list from
	 * @param systemId the ID of the system of measurements to convert to 
	 * (<em>null</em> to leave alone)
	 * @param context the current context
	 * @return a Recipe object, populated with RecipeIngredient objects
	 */
	public Recipe generateShoppingList(Long mealId, Integer systemId, BizContext context);
	
	/**
	 * Convert a Recipe to a specified system.
	 * @param recipeId the ID of the recipe
	 * @param systemId the ID of the system to convert to
	 * @return the converted Recipe
	 */
	public Recipe convertRecipeSystem(Long recipeId, Integer systemId);
	
	/**
	 * Alter the size (servings) of a recipe by a numrical factor.
	 * 
	 * @param recipeId the ID of the recipe
	 * @param size the factor to alter the size by (i.e. 2 to double, 0.5 to half)
	 * @return the recipe, altered to the specified size
	 */
	public Recipe alterRecipeSize(Long recipeId, float size);

	/**
	 * Save the rating for a specific recipe.
	 * 
	 * @param recipeId the ID of the recipe to set the rating on
	 * @param rating the rating to set
	 * @param context the current context
	 * @return the saved rating object
	 */
	public RecipeRating storeRecipeRating(Long recipeId, short rating, BizContext context);

	/**
	 * Add a comment to a recipe.
	 * 
	 * @param recipeId the ID of the recipe to add the comment to
	 * @param comment the comment to add
	 * @param context the current context
	 * @return the saved comment object
	 */
	public RecipeComment addCommentToRecipe(Long recipeId, String comment, BizContext context);
	
	/**
	 * Add an image to a recipe, or replace an existing image.
	 * 
	 * @param recipeId the ID of the recipe to add the image to
	 * @param image the image file
	 * @param context the current context
	 * @return the Recipe with the image added to it
	 */
	public Recipe storeRecipeImage(Long recipeId, TemporaryFile image, BizContext context);
	
	/**
	 * Remove the image saved with a recipe.
	 * 
	 * <p>If the recipe does not have an image associated with it, this method
	 * returns without error.</p>
	 * 
	 * @param recipeId the ID of the recipe to remove the image from
	 * @param context the current context
	 * @return the Recipe with the image removed
	 */
	public Recipe removeRecipeImage(Long recipeId, BizContext context);
	
}
