COP 3503 Project 3 – Dinner Plans
7/2/14

DUE: Tuesday 7/15/14

Description
You will implement a program that reads, names, stores, and operates on recipes. Recipes consist of a title, an ingredient list, and a set of instructions. Instructions may also contain equipment information. Operations include combining a set of recipes to arrive at a combined ingredient list, combined equipment, and combined instructions. They also include taking inventory lists of available ingredients and equipment and subtracting them from combined lists to arrive at shopping lists of needed items. 

User Input
The user input is similar to earlier projects, but there are some differences regarding the meanings of the commands. 
The numbered commands are as follows:
 0.	exit
 1.	input recipe file <filename>: open and read a file containing recipes, storing each recipe as a separate item, named using the title provided in the recipe file
 2.	input inventory file <filename>: open and read a file containing inventory information, combining it with existing inventory information, if any
 3.	subtract inventory file <filename>: open and subtract inventory lists from a file from the current inventory lists
 4.	add <recipe name>: add a recipe from those stored to a current menu list
 5.	remove <recipe name>: remove a recipe from the current menu list
 6.	reset current menu list to the empty set
 7.	output menu <filename>: open and write the current menu to a file in RBML
 8.	print current menu list to the console in formatted plain text
 9.	print <recipe name>: find recipe if stored and print it to the console in formatted plain text
 10.	increase <ingredient inventory item>: add/increase inventory item to the current inventory list
 11.	reduce <ingredient inventory item>: decrease/remove item from the current inventory list
 12.	insert <equipment inventory item>: add inventory item to the current inventory list
 13.	delete <equipment inventory item>: remove inventory item from the current inventory list
 14.	print ingredient inventory: print ingredient inventory to console in formatted plain text
 15.	print equipment inventory: print equipment inventory to console in formatted plain text
 16.	print ingredients list: combine ingredient lists of recipes in current menu and print the combined ingredient list to the console in formatted plain text
 17.	print ingredient shopping list: combine ingredient lists of recipes in current menu, subtract the ingredient inventory list, and print the missing ingredient list to the console in formatted plain text
 18.	output ingredient shopping list <file>:  combine ingredient lists of recipes in current menu, subtract the ingredient inventory list, and store the combined ingredient list to the named file in RBML ingredient list format
 19.	print equipment list: combine equipment lists of recipes in current menu and print the combined equipment list to the console in formatted plain text
 20.	print equipment shopping list: combine equipment lists of recipes in current menu, subtract the equipment inventory list, and print the needed equipment list to the console in formatted plain text
 21.	output equipment shopping list <file>:  combine equipment lists of recipes in current menu, subtract the current equipment inventory list, and store the combined equipment list to the named file in RBML equipment list format
 22.	help

File input and output format
For storage of inventory lists and recipes, a form of XML will be used. We will use a simplified version of the Recipe Book ML available at http://www.happy-monkey.net/recipebook/, requiring only title, ingredient list, and preparation elements, with other elements optional. Multiple recipes may be stored per recipe file, and all recipes are to be read in and labeled by recipe title. The version we will use is commented with the required and optional parts; see http://www.cise.ufl.edu/~nemo/cop3503/recipebook.dtd. You may view it using wordpad or other text editor. It also has a few minor extensions. 
Inventory files use similar XML format, but only consist of lists of ingredients and/or equipment. 
A title is just a text string (perhaps with white space). Ingredients have a text description, an optional quantity, and an optional measurement unit. Equipment is simply a text description (or optionally, a URL). 
While several elements of (the already rather simple) Recipe Book ML are optional, your program must be able to skip over the parts that it does not process (e.g., optional recipeinfo, serving, notes, etc.) so that it can use existing recipe files. 

Functionality
The process will maintain a current collection of recipes, a current ingredient inventory, a current equipment inventory, and a current menu, which is just a subset of the recipe collection. 
Silent and verbose modes behave as they did in earlier projects. 
Writes indicating errors (e.g., failure to open a file), will be written to standard error (cerr stream). 

Program Command Line Arguments
The program will read in optional command line parameters for mode (-v for verbose, -s for silent), file input for the initial recipe set(s) (using -r <file_name> to indicate the file to read in), and initial inventory set(s) (using -i <file_name>). Note that multiple recipe and inventory files may be indicated.
 
User Interface Commands 
exit – exit the program
input recipe file <filename>: open and read a file containing recipes in RBML, storing each recipe as a separate item, named using the title provided in the recipe file
input inventory file <filename>: open and read a file containing inventory information, combining it with existing inventory information, if any. Inventory items are to be combined if their description matches exactly, and combination is performed by adding the quantities of like units. If units are different, then quantities for each unit must be maintained (e.g., 3 cups flour and 2 teaspoons flour have the same description, but different units, so must both cups and teaspoon quantities must be maintained. You are not expected to convert units, so although 3 tsp = 1 tbsp, you can keep an inventory item with 6 tsp and 2 tbsp without converting these to 4 tbsp or ¼ cup). 
subtract inventory file <filename>: open and subtract inventory lists from a file from the current inventory lists. Here, complain if an inventory item with quantity for a unit is subtracted from an inventory item with a smaller quantity in that unit (this may or may not be a problem in reality, since subtracting 2 tbsp from 10 cups of flour still leaves a lot of flour). Include the offending item information in the complaint, but carry on. Throw and catch an exception if any input quantity is negative, but simply remove the item from the resultant list if a greater or equal quantity is subtracted from the original list.  
add <recipe name>: add a recipe from those stored to a current menu list. Self-explanatory. 
remove <recipe name>: remove a recipe from the current menu list. Self-explanatory.
reset current menu list to the empty set. Self-explanatory.
output menu <filename>: open and write the current menu to a file in RBML. This must include all recipes in the current menu, but each recipe only has to include the required elements; you may either process the optional elements and output them, or simply store them without further processing and output them uninterpreted, or discard them on input and not output them. In other words, you may read in a recipe from a file that has optional tagged fields and just discard those fields, so if you output that same recipe, the output version will omit those optional fields; or you may store those fields and output them with the rest of the recipe so that the output version is substantially the same as the original. 
print current menu list to the console in formatted plain text. Here, just print out the name of each recipe left-justified on a line by itself (do NOT print out the rest of the recipe information). 
print <recipe name>: find recipe if stored and print it to the console in formatted plain text. Here, print out the recipe title left justified on one line, then sections. Each section shall have a section title preceded by two spaces on its own line (e.g., Ingredients, Preparation), followed by its elements. Ingredients shall be listed with one per line along with quantity and unit (if any). Preparation shall be listed one step per line. Equipment shall be listed in a separate equipment list, one item per line. No XML tags shall be included, and you should add spacing to provide for readability. Elements of each section shall be proceeded by a tab, and ingredients shall have quantity (if any) followed by a single space, then units (if any) followed by a single space, then the textual description. If quantity or units are omitted, then also omit the corresponding space. Equipment and steps shall simply be output verbatim. No additional spaces shall be inserted. 
increase <ingredient inventory item>: add ingredient inventory item to the current inventory list. Ingredient inventory item is of the form <item description> [<quantity> [<units>]], meaning that the item must have an identifier (its key), and may have a quantity, which may have units. Quantity is a positive number, units is a text string. If the ingredient is already on the inventory list, simply increase its quantity as noted above (no unit conversions needed) if a quantity is provided. If it is not already on the inventory list, then add it to the inventory list. 
reduce <ingredient inventory item>: remove inventory item from the current inventory list. Ingredient inventory item is of the form <item description> [<quantity> [<units>]], meaning that the item must have an identifier (its key), and may have a quantity, which may have units. Quantity is a positive number, units is a text string. If the ingredient is already on the inventory list, simply decrease its quantity as noted above (no unit conversions needed) if a quantity is provided. If it is not already on the inventory list, or if the quantity in the like units is reduced to less than zero, complain to cerr about the situation and reduce the quantity to zero. If all quantities for the item are reduced to zero, then delete the item.  
insert <equipment inventory item>: add equipment item to the current inventory list. If the item is already on the list then no change is made, but complain to cerr. 
delete <equipment inventory item>: remove equipment item from the current inventory list. If the item is not on the list then no change is made, but complain to cerr. 
print ingredient inventory: print ingredient inventory to console in formatted plain text. Output a title “Ingredients” left-justified on a line by itself, then on each following line list a single ingredient preceded by a tab. If the ingredient has a quantity, then print the quantity first, followed by a space. If the quantity has units, print the units followed by a space. Ingredient description shall then be printed verbatim.  If there are multiple units, then each unit shall be printed with the quantity and ingredient on its own line (e.g., if the inventory has “beer” listed with 12 cans and 1 keg, then output “12 cans beer” on one line and “1 keg beer” on another). 
print equipment inventory: print equipment inventory to console in formatted plain text. Output a title “Equipment” left-justified on a line by itself, then on each following line list a single equipment item preceded by a tab. Equipment description shall be printed verbatim. 
print ingredients list: combine ingredient lists of recipes in current menu and print the combined ingredient list to the console in formatted plain text. Output is described above. 
print ingredient shopping list: combine ingredient lists of recipes in current menu, subtract the ingredient inventory list, and print the missing ingredient list to the console in formatted plain text. Output is described above. 
output ingredient shopping list <file>:  combine ingredient lists of recipes in current menu, subtract the ingredient inventory list, and store the combined ingredient list to the named file in RBML ingredient list format. Self-explanatory.
print equipment list: combine equipment lists of recipes in current menu and print the combined equipment list to the console in formatted plain text. Use the same format as given above. 
print equipment shopping list: combine equipment lists of recipes in current menu, subtract the equipment inventory list, and print the needed equipment list to the console in formatted plain text. Use the same format as given above. 
output equipment shopping list <file>:  combine equipment lists of recipes in current menu, subtract the current equipment inventory list, and store the combined equipment list to the named file in RBML equipment list format. Self-explanatory. 
Help – Print a description of the supported commands to the console.
 
Errors
Your program must detect and handle in a reasonable way typical errors. All warnings are printed to standard error (cerr). These include but are not limited to:
 1.	File <filename> cannot be opened – print warning 
 2.	File is not in correct format – print warning. Items that are not in correct format must be discarded, with additional warning to the console in verbose mode
 3.	Item <item name> is not in correct format on user input line – issue warning to standard error and print help on correct format to the console
 4.	Command is invalid – issue warning to standard error and print verbose prompt to console

Submissions
Submit your project as project report, user documentation, readme, makefile, and code files. Code files should include one or more header files, one or more files with main(), and one or more implementation files, and should include comments as needed. You may use external code for XML parsing, provided that you give credit and document where you got it. You may use any built-in features of C++ including standard library facilities.

Extra Credit
You will receive extra credit for implementing additional features correctly. Note which of these you implement in your program documentation. 
Full implementation of Recipe Book ML – 3 pts. This means storing in the program, saving to files in correct format, and printing in readable way to console the fields marked as optional.
Implementation of units conversion – 5 pts. This means conversion of the following units in order to handle correctly ingredients lists and inventories, especially when subtracting.
Extension of equipment – 2 pts. Equipment items can have optional quantities as well, both for inventory and for preparation (similar to ingredient items). Default quantity is 1, but addition of more equipment can lead to larger numbers (e.g., baking dishes, bowls, etc.).

Unit Conventions and Conversions (extra credit)
The following units will taken as conventional for equivalence and for conversion. Capitalization and placement of a period following the unit shall be ignored. 

	Tsp	Tbsp	Oz	Cup	Pint	Quart	Gallon	
Tsp = teaspoon	1	3	6	48	96	192	768	
Tbsp = tablespoon		1	2	16	32	64	256	
Oz = ounce			1	8	16	32	128	
C = cu = cup				1	2	4	16	
Pt = pint					1	2	8	
Qt = quart						1	4	
G = gal = gallon							1