import java.util.LinkedList;
import java.util.Scanner;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.time.LocalDateTime;

/**Loads menu, reservation and table objects from file. 
 * Presents user with a list of options.
 * On shutdown, saves menu, reservation and table objects to file.
 * @author Nicholas Koh
 *
 */
public class ConsoleApplication {


	private static Menu[] menuArray = new Menu[999];
	private static int noOfMenus = 0;
	private static Order[] orderArray = new Order[999];
	private static int noOfOrders = 0;
	private static ReservationHandler ReservationHandler = new ReservationHandler();
	private static TableHandler TableHandler = new TableHandler();
	private static CurrentSessionTableHandler currentSessionTable;

	/**
	 * Main function
	 */
	public static void main(String[] args) {

		Scanner sc = new Scanner(System.in);
		int k = 0, back = 1, choice;
		String menuName;

		// intialize menus, orders, reservations, tables objects by loading them from file / disk.
		initialiseMenu();
		initialiseReservation();
		initialiseTableBookings();
		saveReservation(); // save to file after expired reservations are removed

		System.out.println("Type 0 for AM Session, if not 1 for PM session.");
		int session = sc.nextInt();
		// initialise tables for current session, be it AM or PM
		int[] currentTable = TableHandler.getArrayForCurrentSession(session);
		currentSessionTable = new CurrentSessionTableHandler(currentTable);
		// remove expired reservations
		ReservationHandler.removeExpiredReservations(TableHandler,currentSessionTable);

		while (back == 1) {

			System.out.println();
			System.out.println("Choose one of the following:");
			System.out.println("1. Create/Update/Remove menu");
			System.out.println("2. Create/Update/Remove promotion");
			System.out.println("3. Order");
			System.out.println("4. Reservation bookings");
			System.out.println("5. Check table availability");
			System.out.println("6. Print sale revenue report by period (eg day or month)");
			System.out.println("7. Quit.");
			System.out.println();
			choice = sc.nextInt();

			switch (choice) {
			case 1:
				int choice1 = 0;
				while (choice1 != 8) {
					back = 0;
					System.out.println();
					System.out.println("<<<<     Create/Update/Remove menu     >>>>");
					System.out.println("1. Create menu.");
					System.out.println("2. Create menu item and add it to an existing menu.");
					System.out.println("3. Update menu item.");
					System.out.println("4. Remove menu item.");
					System.out.println("5. Print menu/promotion.");
					System.out.println("6. Delete menu.");
					System.out.println("7. Print entire menu incl promotions.");
					System.out.println("8. Return to previous menu.");
					choice1 = sc.nextInt();

					switch (choice1) {
					case 1: // create new menu

						System.out.println("Enter menu name:");
						menuName = sc.nextLine();
						menuName = sc.nextLine();

						boolean success = false;

						for (int i = 0; i < noOfMenus; i++) {
							if (menuArray[i].getMenuName().equalsIgnoreCase(menuName)) {
								System.out.println("Menu called " + menuName + " already exists.");
								success = true;
								break;
							}
						}
						if (!success) {
							menuArray[noOfMenus] = new Menu(menuName);
							noOfMenus++;
							saveMenu();
							System.out.println("Menu " + menuName + " created.");
							System.out.println("Current menus:");
							k = menuDisplay(0, 1, 0);
						}
						break;

					case 2: // add item to existing menu

						// menuDisplay prints out the existing menus and lets the user select a menu by typing in the menu name.
						//returns the index of the selected menu where it is stored in the menu array.
						//returns -1 if menu is not found or user inputs something funny.
						
						//menuDisplay(int displayoption, int readonly, int printdishes)
						//display option: 0 for all, 1 for menus only, 2 for promos only
						//readonly option: 0 to enable user choice, 1 to print menus only
						//printdishes option: 0 to print dishes, 1 to omit dishes

						k = menuDisplay(1, 0, 0);
						while (k == -1)
							k = menuDisplay(1, 0, 0);
						menuArray[k].addItemUserInput();
						saveMenu();
						break;

					case 3: // update menu item
						k = menuDisplay(1, 0, 0);
						while (k == -1)
							k = menuDisplay(1, 0, 0);
						menuArray[k].updateItemUserInput();
						break;

					case 4: // remove menu item
						k = menuDisplay(1, 0, 0);
						while (k == -1)
							k = menuDisplay(1, 0, 0);
						menuArray[k].removeItemUserInput();
						saveMenu();
						break;

					case 5: // print menu
						k = menuDisplay(0, 0, 0);
						while (k == -1)
							k = menuDisplay(0, 0, 0);
						menuArray[k].printMenuItems();
						saveMenu();
						break;

					case 6: // delete menu
						k = menuDisplay(1, 0, 0);
						while (k == -1)
							k = menuDisplay(1, 0, 0);
						String menuToDelete = menuArray[k].getMenuName();
						for (int y = k; y < noOfMenus; y++)
							menuArray[y] = menuArray[y + 1];
						noOfMenus--;
						saveMenu();
						System.out.println("Menu " + menuToDelete + " deleted.");
						System.out.println("Current menus:");
						k = menuDisplay(0, 1, 0);
						break;

					case 7: // print all menus out, incl promotions
						k = menuDisplay(0, 1, 1);
						break;

					case 8:
						back = 1;
						break;
					}
				}
				break;

			case 2:
				int choice2 = 99;
				while (choice2 != 0) {
					back = 0;

					System.out.println();
					System.out.println("<<<<     Create/Update/Remove Promotion     >>>>");
					System.out.println("1. Create promotion");
					System.out.println("2. Create promotion item and add it to an existing promotion");
					System.out.println("3. Update promotion item");
					System.out.println("4. Remove promotion item");
					System.out.println("5. Print promotion.");
					System.out.println("6. Delete promotion.");
					System.out.println("7. Convert an existing menu into a promotion.");
					System.out.println("8. Convert a promotion into a regular menu.");
					System.out.println("9. Change promotion price.");
					System.out.println("0. Return to previous menu");
					choice2 = sc.nextInt();

					switch (choice2) {
					case 0: //return to previous menu
						back = 1;
						break;
					case 1: // create new promotion
						System.out.println("Enter promotion name:");
						menuName = sc.nextLine();
						menuName = sc.nextLine();
						int success = -1;

						// check if a menu by that name already exists.
						for (int i = 0; i < noOfMenus; i++) {
							if (menuArray[i].getMenuName().equalsIgnoreCase(menuName)) {
								System.out.println("Promotion called " + menuName + " already exists.");
								success = 0;
								break;
							}
						}
						if (success != 0) {
							menuArray[noOfMenus] = new Menu(menuName);
							System.out.println("Enter promotion price: ");
							float promotionPrice;
							Scanner userinput = new Scanner(System.in);
							promotionPrice = userinput.nextFloat();
							menuArray[noOfMenus].setPromotion(promotionPrice);
							noOfMenus++;
							System.out.println("Promotion " + menuName + " created.");
							saveMenu();
						}
						break;
					case 2: // add item to existing promotion - SAME AS MENU
						k = menuDisplay(2, 0, 0);
						while (k == -1)
							k = menuDisplay(2, 0, 0);
						menuArray[k].addItemUserInput();
						saveMenu();
						break;

					case 3: // update promotion item - SAME AS MENU
						k = menuDisplay(2, 0, 0);
						while (k == -1)
							k = menuDisplay(2, 0, 0);
						menuArray[k].updateItemUserInput();
						saveMenu();
						break;

					case 4: // remove promotion item - SAME AS MENU
						k = menuDisplay(2, 0, 0);
						while (k == -1)
							k = menuDisplay(2, 0, 0);
						menuArray[k].removeItemUserInput();
						saveMenu();
						break;

					case 5: // print promotion - SAME AS MENU
						k = menuDisplay(2, 0, 0);
						while (k == -1)
							k = menuDisplay(2, 0, 0);
						menuArray[k].printMenuItems();
						saveMenu();
						break;

					case 6: // delete promotion - SAME AS MENU
						k = menuDisplay(2, 0, 0);
						while (k == -1)
							k = menuDisplay(2, 0, 0);
						for (int y = k; y < noOfMenus; y++)
							menuArray[y] = menuArray[y + 1];
						noOfMenus--;
						saveMenu();
						break;

					// PROMOTION SPECIFIC OPERATIONS
					case 7: // convert an existing menu into a promotion
						k = menuDisplay(1, 0, 0);
						while (k == -1)
							k = menuDisplay(1, 0, 0);
						System.out.println("Enter promotion price: ");
						float promotionPrice = sc.nextFloat();
						menuArray[k].setPromotion(promotionPrice);
						saveMenu();
						break;
					case 8: // convert a promotion into a regular menu
						k = menuDisplay(2, 0, 0);
						while (k == -1)
							k = menuDisplay(2, 0, 0);
						menuArray[k].removePromotion();
						saveMenu();
						break;
					case 9: // change promotion price
						k = menuDisplay(2, 0, 0);
						while (k == -1)
							k = menuDisplay(2, 0, 0);
						System.out.println("Current promotion price: " + menuArray[k].getPromotionPrice());
						System.out.println("Enter new promotion price: ");
						promotionPrice = sc.nextFloat();
						menuArray[k].setPromotion(promotionPrice);
						saveMenu();
						break;

					}
				}
				break;
			case 3:
				int back3 = 1;
				while (back3 == 1) {
					int choice3;
					back = back3 = 0;
					System.out.println();
					System.out.println("<<<<     Order     >>>>");
					System.out.println("1. Create order");
					System.out.println("2. View order");
					System.out.println("3. Add to order");
					System.out.println("4. Remove from order");
					System.out.println("5. Clear order");
					System.out.println("6. Finalize order");
					System.out.println("7. Return to previous menu");
					int inputTableID;
					int orderID;
					int userchoice2;
					choice3 = sc.nextInt();
					switch (choice3) {
					case 1: // create order

						int isReservation;
						ReservationHandler.removeExpiredReservations(TableHandler,currentSessionTable);
						System.out.println("1. Walk-in, 2. Reservation");
						isReservation = sc.nextInt();
						
						if (isReservation == 2) {
							System.out.println("Enter in the customer phone number/ reservation ID.");
							int reservationIDtoRemove = sc.nextInt();
							Reservation reservationToOrder = ReservationHandler.removeReservation(reservationIDtoRemove);
							currentSessionTable.setTableOccupancy(2, reservationToOrder.getAssignedTable());
							int newOrderPax = reservationToOrder.getPax();

							System.out.println("Enter staff ID: ");
							int staffID = sc.nextInt();
							int tableID = currentSessionTable.assignTable(newOrderPax);

							if (tableID != -1) {
								orderArray[noOfOrders] = new Order(staffID, tableID);
								System.out.println("Order successfully created.");
								System.out.println("Table ID: " + orderArray[noOfOrders].getTableId());
								noOfOrders++;
							} else {
								System.out.println("All tables occupied.");
							}
						} else if (isReservation == 1) {
							int pax, tableID, staffID;
							System.out.println("Enter pax: ");
							pax = sc.nextInt();
							tableID = currentSessionTable.assignTable(pax);

							if ((tableID != -1) && (tableID != -2)) {
								System.out.println("Enter staff ID: ");
								staffID = sc.nextInt();
								orderArray[noOfOrders] = new Order(staffID, tableID);
								System.out.println("Order successfully created.");
								System.out.println("Table ID: " + orderArray[noOfOrders].getTableId());
								noOfOrders++;
							} else if (tableID != -2) {
								System.out.println("All tables occupied.");
							}
						}
						back3 = 1;
						break;
					case 2: // view order
						System.out.println("Input table ID of order you wish to view:");
						inputTableID = sc.nextInt();
						orderID = orderCheck(inputTableID);
						if (orderID == -1)
							System.out.println("Table not occupied.");
						else
							orderArray[orderID].printOrder();
						back3 = 1;
						break;
					case 3: // add to order
						System.out.println("Input table ID of order you wish to add to:");
						inputTableID = sc.nextInt();
						orderID = orderCheck(inputTableID);
						if (orderID == -1) {
							System.out.println("Table not occupied.");
						}
						else{
							userchoice2 = 0;
							while (!(userchoice2 == 1 || userchoice2 == 2)) {
								System.out.println("Choose what to add:");
								System.out.println("1. Dish");
								System.out.println("2. Promo");
								userchoice2 = sc.nextInt();
							}
							if (userchoice2 == 1) {
								Dish tempDishToAdd = getDishFromID();
								while (tempDishToAdd == null) {
									System.out.println("Invalid dish, please try again.");
									tempDishToAdd = getDishFromID();
								}
								orderArray[orderID].addDish(tempDishToAdd);
							} else if (userchoice2 == 2) {
								Menu tempPromoToAdd = getPromoFromName();
								while (tempPromoToAdd == null) {
									System.out.println("Invalid promo, please try again.");
									tempPromoToAdd = getPromoFromName();
								}
								orderArray[orderID].addPromo(tempPromoToAdd);
							}
						}
						back3 = 1;
						break;
					case 4: // remove from order
						System.out.println("Input table ID of order you wish to remove:");
						inputTableID = sc.nextInt();
						orderID = orderCheck(inputTableID);
						if (orderID == -1) {
							System.out.println("Table not occupied.");
						}
						else{
							userchoice2 = 0;
							while (!(userchoice2 == 1 || userchoice2 == 2)) {
								System.out.println("Choose what to remove:");
								System.out.println("1. Dish");
								System.out.println("2. Promo");
								userchoice2 = sc.nextInt();
							}
							if (userchoice2 == 1) { // remove dish
								Dish tempDishToRemove = getDishFromID();
								while (tempDishToRemove == null) {
									System.out.println("Invalid dish, please try again.");
									tempDishToRemove = getDishFromID();
								}
								int userchoice3 = 0;
								while (!(userchoice3 == 1 || userchoice3 == 2)) {
									System.out.println("1. Remove 1 of " + tempDishToRemove.getDishName());
									System.out.println("2. Remove all of " + tempDishToRemove.getDishName());
									userchoice3 = sc.nextInt();
								}
								if (userchoice3 == 1) {
									orderArray[orderID].removeOneDish(tempDishToRemove);
									System.out.println("1 " + tempDishToRemove.getDishName() + " removed.");
								} else if (userchoice3 == 2) {
									orderArray[orderID].removeAllDish(tempDishToRemove);
									System.out.println("ALL " + tempDishToRemove.getDishName() + " removed.");
								}
							} else if (userchoice2 == 2) { // remove promo
								Menu tempPromoToRemove = getPromoFromName();
								while (tempPromoToRemove == null) {
									System.out.println("Invalid promo, please try again.");
									tempPromoToRemove = getPromoFromName();
								}
								int userchoice3 = 0;
								while (!(userchoice3 == 1 || userchoice3 == 2)) {
									System.out.println("1. Remove 1 of " + tempPromoToRemove.getMenuName());
									System.out.println("2. Remove all of " + tempPromoToRemove.getMenuName());
								}
								if (userchoice3 == 1) {
									orderArray[orderID].removeOnePromo(tempPromoToRemove);
									System.out.println("1 " + tempPromoToRemove.getMenuName() + " removed.");
								} else if (userchoice3 == 2) {
									orderArray[orderID].removeAllPromo(tempPromoToRemove);
									System.out.println("ALL " + tempPromoToRemove.getMenuName() + " removed.");
								}
							}
						}
						back3 = 1;
						break;
					case 5: // clear order
						System.out.println("Input table ID of order you wish to clear:");
						inputTableID = sc.nextInt();
						orderID = orderCheck(inputTableID);
						if (orderID == -1) {
							System.out.println("Table not occupied.");
						}
						else{
							orderArray[orderID].clearOrder();
							System.out.println("Order cleared.");
						}
						
						back3 = 1;
						break;
					case 6: // finalize order
						System.out.println("Input table ID of order you wish to finalise:");
						inputTableID = sc.nextInt();
						orderID = orderCheck(inputTableID);
						if (orderID == -1) {
							System.out.println("Table not occupied.");
						}
						else{
							orderArray[orderID].finalizedOrder();
							for (int z = orderID; z < noOfOrders; z++)
								orderArray[z] = orderArray[z+1];
							noOfOrders--;
							currentSessionTable.setTableOccupancy(0, inputTableID);
							System.out.println("Table " + inputTableID + " cleared and unoccupied.");
						}
						back3 = 1;
						break;
					case 7: // go back
						back = 1;
						break;
					}
				}
				break;
			case 4:
				int back4 = 1;
				while (back4 == 1) {
					int choice4;
					back = 0;
					back4 = 0;
					System.out.println();
					System.out.println("<<<<       Reservations       >>>>");
					System.out.println("1. Create reservation booking");
					System.out.println("2. Check reservation booking");
					System.out.println("3. Remove specific reservation booking");
					System.out.println("4. Return to previous menu");
					choice4 = sc.nextInt();
					switch (choice4) {
					case 1:
						ReservationHandler.removeExpiredReservations(TableHandler,currentSessionTable);
						System.out.println("Enter in the year of reservation.");
						int year = sc.nextInt();
						System.out.println("Enter in the month of reservation. 1 for January, 12 for December.");
						int month = sc.nextInt();
						System.out.println("Enter in the day of reservation.");
						int day = sc.nextInt();
						System.out.println("Enter in the hour of reservation.");
						int hour = sc.nextInt();
						System.out.println("Enter in the minute of reservation.");
						int minute = sc.nextInt();
						System.out.println("Enter in the pax.");
						int pax = sc.nextInt();
						System.out.println("Enter in the customer name.");
						String custName = sc.next();
						System.out.println("Enter in the customer phone number which will be used as the ID.");
						int custID = sc.nextInt();
						Reservation newReservation = new Reservation(year, month, day, hour, minute, pax, custName,
								custID);
						if (newReservation.getSession() == -1) {
							System.out.println("Timing doesnt fit AM or PM session.");
							newReservation = null;
						} else if (newReservation != null) {
							int errorMessage = ReservationHandler.addReservation(newReservation);
							if (errorMessage == -1)
								System.out.println("Error: you can only make reservations within 30 days from now.");
							else if (errorMessage == -2)
								System.out.println("Error: cannot make reservations in the past.");
							else if (errorMessage < 0)
								System.out.println("Error: unspecified error, reservation not created.");
							else if (errorMessage == 1){
								int assignedTable = TableHandler.assignTable(newReservation.getArrivalDateTime(), newReservation.getSession(), newReservation.getPax());
								newReservation.setTableAssigned(assignedTable);
								System.out.println("Reservation successfully created.");
							}
						}
						back4 = 1;
						break;
					case 2:
						ReservationHandler.removeExpiredReservations(TableHandler,currentSessionTable);
						System.out.println("Enter in the customer phone number/ reservation ID.");
						int reservationID = sc.nextInt();
						Reservation checkReservation = ReservationHandler.getReservation(reservationID);
						if (checkReservation == null) {
							System.out.println("Something is wrong at getReservation.");
						} else {
							System.out.println(
									"Arrival time is: " + checkReservation.getArrivalDateTime().toString() + ".");
							System.out.println("Pax is: " + checkReservation.getPax() + ".");
							System.out.println("Assigned table is: " + checkReservation.getAssignedTable() + ".");
							System.out.println("Customer Name is: " + checkReservation.getCustomerName() + ".");
							System.out.println(
									"Customer ID (phone number) is: " + checkReservation.getReservationID() + ".");
						}
						back4 = 1;
						break;
					case 3:
						ReservationHandler.removeExpiredReservations(TableHandler,currentSessionTable);
						System.out.println("Enter in the customer phone number/ reservation ID.");
						int reservationIDtoRemove = sc.nextInt();
						Reservation removedR = ReservationHandler.removeReservation(reservationIDtoRemove);
						if (removedR != null){
							TableHandler.removeBooking(removedR.getArrivalDateTime(), removedR.getSession(), removedR.getAssignedTable());
						}
						back4 = 1;
						break;
					case 4:
						back = 1;
						break;
					}
				}
				break;
			case 5:
				int table_id;
				back = 0;
				System.out.println();
				System.out.println("<<<<       Check Table Availability       >>>>");
				System.out.println("Enter the table to be checked:");
				table_id = sc.nextInt();
				int tableStatus = currentSessionTable.getTableOccupancy(table_id);
				if (tableStatus == 0) {
					System.out.println("Table is NOT occupied and NOT reserved.");
				} else if (tableStatus == 1) {
					System.out.println("Table is NOT occupied BUT reserved.");
				} else if (tableStatus == 2) {
					System.out.println("Table is occupied.");
				} else {
					System.out.println("Something is wrong here.");
				}
				back = 1;
				break;
			case 6:
				System.out.println();
				System.out.println("<<<<       Sales Report       >>>>");
				SalesReport tempSalesReport = new SalesReport();
				int year, month, day;
				Scanner userinput = new Scanner(System.in);
				System.out.println("Input year YYYY");
				year = userinput.nextInt();
				System.out.println("Input month, 1 = january, 12 = december");
				month = userinput.nextInt();
				System.out.println("Input day if desired; if month only then input 0.");
				day = userinput.nextInt();
				// some way of checking that user input is valid
				if (year > 1900 && year < 2020 && month > 0 && month < 13 && day > -1 && day < 32)
					tempSalesReport.printSalesReport(year, month, day);

				back = 1;
				break;
			case 7:
				back = 0;
				break;
			}
			saveMenu();
			saveReservation();
			saveTableBookings();
		}
		System.out.println("Program exiting.");

	}
	
	/**
	Prints out all the menus, allows user to select menu by typing in menu name, then returns the corresponding index of the menu in the current menu array.
	If menu is not found, -1 is returned.
	@param	displayOption	0 = print out all menus and promos; 1 = print menus only; 2 = print promos only
	@param	readOnly	0 = user can input menu choice; 1 = only print menus, no user input allowed.
	@param	printDishes	0 = don't print individual dishes in menus, 1 = print dishes in menus
	@return	menuIndex	Index of user's chosen menu. -1 if menu is not found.
	*/	
	public static int menuDisplay(int displayOption, int readOnly, int printDishes) {


		Scanner userinput = new Scanner(System.in);
		String menuName;

		boolean printmenu = false, printpromo = false;
		if (displayOption == 0)
			printmenu = printpromo = true;
		else if (displayOption == 1) {
			printpromo = false;
			printmenu = true;
		} else if (displayOption == 2) {
			printpromo = true;
			printmenu = false;
		}

		System.out.println();
		if (readOnly == 0) {
			if (printpromo && printmenu)
				System.out.println("Choose menu or promotion:");
			else if (printpromo && !printmenu)
				System.out.println("Choose promotion:");
			else if (!printpromo && printmenu)
				System.out.println("Choose menu:");
		}

		for (int q = 0; q < noOfMenus; q++) {
			if (printmenu && !(menuArray[q].isPromotion())) {
				// print menu title
				if ((readOnly == 1) && (printDishes == 1)) {
					System.out.println("");
					System.out.println("Menu: " + menuArray[q].getMenuName());
				} else {
					System.out.println(menuArray[q].getMenuName());
				}
				// print menu dishes if they exist
				if ((printDishes == 1) && (menuArray[q].getNoOfItems() > 0)) {
					Dish[] tempDishArray = menuArray[q].getDishArray();
					for (int z = 0; z < menuArray[q].getNoOfItems(); z++) {
						System.out.println("Name: " + tempDishArray[z].getDishName() + ";Price = $"
+ tempDishArray[z].getDishPrice() + ";ID = " + tempDishArray[z].getDishID() + ";Description = "
+ tempDishArray[z].getDishDescription());
					}
				}
			}

			if (printpromo && menuArray[q].isPromotion()) {
				// print promo name
				if ((readOnly == 1) && (printDishes == 1)) {
					System.out.println("");
					System.out.println("Promotion: " + menuArray[q].getMenuName() + ", Promotion price = $"
							+ menuArray[q].getPromotionPrice());
				} else {
					System.out.println(
							menuArray[q].getMenuName() + ", Promotion price = " + menuArray[q].getPromotionPrice());
				}
				// print dishes if they exist
				if ((printDishes == 1) && (menuArray[q].getNoOfItems() > 0)) {
					Dish[] tempDishArray = menuArray[q].getDishArray();
					for (int z = 0; z < menuArray[q].getNoOfItems(); z++) {
						System.out.println("Name = " + tempDishArray[z].getDishName() + ";Price = $"
+ tempDishArray[z].getDishPrice() + ";ID = " + tempDishArray[z].getDishID() + ";Description = "
+ tempDishArray[z].getDishDescription());
					}
				}
			}
		}

		// accept user input
		if (readOnly == 0) {
			menuName = userinput.nextLine();

			// searches through menu array for menu with matching name
			int w = 0;
			while (!((menuArray[w].getMenuName()).equalsIgnoreCase(menuName)) && (w < (noOfMenus - 1))) {
				w++;
			}

			// returns matching index if match, else -1
			if ((menuArray[w].getMenuName()).equalsIgnoreCase(menuName))
				return w;
			else {
				System.out.println("No menu by that name found.");
				return -1;
			}
		} else
			return -2;
	}

	
	/**
	Prompts user to input the table ID of the order to be edited.
	If the current table is occupied, it returns the index of the table's order in the order array.
	If the table ID is invalid, or the table is not occupied, -1 is returned.
	@param inputTableID	Table ID of the order.
	@return	orderIndex	Index of the table's order in the current order array. -1 if table id is invalid, or table is not occupied.
	*/
	public static int orderCheck(int inputTableID) {

		for (int i = 0; i < noOfOrders; i++) {
			if (orderArray[i].getTableId() == inputTableID)
				return i;
		}
		return -1;
	}

	/**
	Given a dish ID, the index of the dish in the current dish array is returned.
	If dish is not found, -1 is returned.
	@return	dishIndex	Index of dish in current dish array.
	*/
	public static Dish getDishFromID() {
		Dish dishToAdd = null;
		int dishIDofDishToAdd;
		Scanner userinput = new Scanner(System.in);

		System.out.println("Enter dish ID:");
		dishIDofDishToAdd = userinput.nextInt();

		// search for dish in current menus.
		for (int i = 0; i < noOfMenus; i++) {
			int tempNoOfMenuItems = menuArray[i].getNoOfItems();
			Dish[] tempDishArray = menuArray[i].getDishArray();
			for (int j = 0; j < tempNoOfMenuItems; j++) {
				if (tempDishArray[j].getDishID() == dishIDofDishToAdd) {
					dishToAdd = tempDishArray[j];
					return dishToAdd;
				}
			}
		}
		return dishToAdd;
	}

	/**
	Given a promotion's name, the index of the promotion in the current promotion array is returned.
	If promotion is not found, -1 is returned.
	@return	promoIndex	Index of promotion in current promotion array.
	*/
	public static Menu getPromoFromName() {

		Menu promoToAdd = null;
		String promoNameInput, promoName;
		Scanner userinput = new Scanner(System.in);

		System.out.println("Enter promo name: ");
		promoNameInput = userinput.nextLine();

		promoName = (String) promoNameInput;

		for (int i = 0; i < noOfMenus; i++) {
			if (menuArray[i].getMenuName().equalsIgnoreCase(promoName)) {
				if (menuArray[i].isPromotion()) {
					promoToAdd = menuArray[i];
					return promoToAdd;
				}
			}
		}
		System.out.println("Couldn't find promoToAdd.");
		return promoToAdd;
	}

	/**
	Menus from file on disk is read and converted into Menu objects which are stored in an array of Menus.
	Promotions are set accordingly.
	*/
	public static void initialiseMenu() {
		// count how many menus there are from list of menus
		try {
			File ListOfMenus = new File("ListofMenus.txt");

			if (!ListOfMenus.exists())
				ListOfMenus.createNewFile();
			else {
				FileReader fr = new FileReader(ListOfMenus);
				BufferedReader br = new BufferedReader(fr);
				String line;

				while ((line = br.readLine()) != null)
					noOfMenus++;

				br.close();
				fr.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}

		// create array with menu objects. (listofmenus.txt)
		// for each menu object, create array with dish objects.
		// (menu<menuname>.txt)
		try {
			File ListOfMenus = new File("ListofMenus.txt");

			FileReader fr1 = new FileReader(ListOfMenus);
			BufferedReader br1 = new BufferedReader(fr1);
			String line1;

			int i = 0;

			// create menu array from list of menus in listofmenus.txt
			while ((line1 = br1.readLine()) != null) {
				menuArray[i] = new Menu(line1);
				i++;
			}

			for (int j = 0; j < noOfMenus; j++) {
				File file2 = new File("Menu" + menuArray[j].getMenuName() + ".txt");

				if (!file2.exists()) {
					file2.createNewFile();
				} else {
					FileReader fr2 = new FileReader(file2);
					BufferedReader br2 = new BufferedReader(fr2);
					String line3;

					while ((line3 = br2.readLine()) != null) {
						String line2 = line3.replace("\n", "").replace("\r", "");
						String dishName;
						float dishPrice;
						String dishDescription;
						int dishID;

						String[] inputStringArray = line2.split("~");
						dishName = inputStringArray[0];
						dishPrice = Float.valueOf(inputStringArray[1]);
						dishDescription = inputStringArray[2];
						dishID = Integer.parseInt(inputStringArray[3]);
						menuArray[j].addItem(dishName, dishPrice, dishDescription, dishID);
					}
					br2.close();
					fr2.close();
				}
			}
			br1.close();
			fr1.close();

		} catch (IOException f) {
			f.printStackTrace();
		}

		// modify menus to promotions from separate listofpromotions.txt
		try {
			File ListofPromotions = new File("ListofPromotions.txt");

			if (!ListofPromotions.exists())
				ListofPromotions.createNewFile();
			else {
				FileReader fr = new FileReader(ListofPromotions);
				BufferedReader br = new BufferedReader(fr);
				String line;

				while ((line = br.readLine()) != null) {
					String[] promotionArray = line.split(",");
					String promoName = promotionArray[0];
					float promoPrice = Float.parseFloat(promotionArray[1]);
					for (int y = 0; y < noOfMenus; y++) {
						if (menuArray[y].getMenuName().equalsIgnoreCase(promoName))
							menuArray[y].setPromotion(promoPrice);
					}
				}
				br.close();
				fr.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	Menu and promo objects in the current menu/promo arrays are saved to disk.
	*/	
	public static void saveMenu() {

		// save current menu/promotion/dish objects to file.

		// record list of menus
		try {
			if (menuArray.length != 0) {
				File ListofMenus = new File("ListofMenus.txt");
				if (ListofMenus.exists())
					ListofMenus.delete();
				File ListofMenus1 = new File("ListofMenus.txt");
				if (!ListofMenus1.exists())
					ListofMenus1.createNewFile();

				FileWriter fw1 = new FileWriter(ListofMenus1.getAbsoluteFile());
				BufferedWriter bw1 = new BufferedWriter(fw1);

				for (int z = 0; z < noOfMenus; z++) {
					bw1.write(menuArray[z].getMenuName() + "\n");
				}
				bw1.close();
				fw1.close();
			}

			File ListofPromotions = new File("ListofPromotions.txt");

			if (!ListofPromotions.exists())
				ListofPromotions.createNewFile();
			else {
				FileWriter fw1 = new FileWriter(ListofPromotions.getAbsoluteFile());
				BufferedWriter bw1 = new BufferedWriter(fw1);

				// write menu name to list of menus
				for (int z = 0; z < noOfMenus; z++) {
					if (menuArray[z].isPromotion() && (menuArray[z].getPromotionPrice() != -1)) {
						bw1.write(menuArray[z].getMenuName() + "," + menuArray[z].getPromotionPrice() + "\n");
					}
				}
				bw1.close();
				fw1.close();
			}

			// record dish items for specific menus
			for (int k = 0; k < noOfMenus; k++) {
				// delete existing file since menu contents may have changed
				// since initialization
				File file = new File("Menu" + menuArray[k].getMenuName() + ".txt");
				if (file.exists())
					file.delete();
				File file1 = new File("Menu" + menuArray[k].getMenuName() + ".txt");
				if (!file1.exists())
					file1.createNewFile();

				FileWriter fw = new FileWriter(file1.getAbsoluteFile());
				BufferedWriter bw = new BufferedWriter(fw);

				for (int h = 0; h < menuArray[k].getNoOfItems(); h++) {
					Dish[] DishArray = menuArray[k].getDishArray();
					String content = DishArray[h].getDishName() + "~" + DishArray[h].getDishPrice() + "~"
							+ DishArray[h].getDishDescription() + "~" + DishArray[h].getDishID() + "\n";
					bw.write(content);
				}
				bw.close();
				fw.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Reads from ReservationList.txt to initialise the 
	 * ReservationHandler object. Runs on startup.
	 * @see ReservationHandler
	 */
	public static void initialiseReservation() {
		try {
			File ReservationList = new File("ReservationList.txt");
			if (!ReservationList.exists()) {
				ReservationList.createNewFile();
			} else {
				FileReader fr = new FileReader(ReservationList);
				BufferedReader br = new BufferedReader(fr);
				String line;

				while (((line = br.readLine()) != null) && !(line.equals("\n"))) {
					String[] reservationData = line.split(",");
					int rYear = Integer.parseInt(reservationData[0]);
					int rMonth = Integer.parseInt(reservationData[1]);
					int rDay = Integer.parseInt(reservationData[2]);
					int rHour = Integer.parseInt(reservationData[3]);
					int rMinute = Integer.parseInt(reservationData[4]);
					String rName = reservationData[5];
					int rID = Integer.parseInt(reservationData[6]);
					int rPax = Integer.parseInt(reservationData[7]);
					int rTable = Integer.parseInt(reservationData[8]);
					Reservation newReservation = new Reservation(rYear, rMonth, rDay, rHour, rMinute, rPax, rName, rID);
					newReservation.setTableAssigned(rTable);
					ReservationHandler.addReservation(newReservation);
				}

				br.close();
				fr.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * From current ReservationHandler, saves to ReservationList.txt
	 * Runs on program exit
	 * @see ReservationHandler
	 */
	public static void saveReservation() {

		if (ReservationHandler.getReservationsList().size() < 1)
			return;

		try {
			File ReservationListCheck = new File("ReservationList.txt");

			// delete ReservationListCheck file since menu contents may have
			// changed since initialization
			if (ReservationListCheck.exists())
				ReservationListCheck.delete();
			File ReservationList = new File("ReservationList.txt");
			ReservationList.createNewFile();

			// write reservations to file
			FileWriter fw = new FileWriter(ReservationList.getAbsoluteFile());
			BufferedWriter bw = new BufferedWriter(fw);
			String content;

			for (int i = 0; i < ReservationHandler.getReservationsList().size(); i++) {
				Reservation currentR = ReservationHandler.getReservationsList().get(i);
				content = currentR.getArrivalDateTime().getYear() + "," + currentR.getArrivalDateTime().getMonthValue()
						+ "," + currentR.getArrivalDateTime().getDayOfMonth() + ","
						+ currentR.getArrivalDateTime().getHour() + "," + currentR.getArrivalDateTime().getMinute()
						+ "," + currentR.getCustomerName() + "," + currentR.getReservationID() + "," + currentR.getPax()
						+ "," + currentR.getAssignedTable() + "\n";
				bw.write(content);
			}

			bw.close();
			fw.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Reads from TableBooking.txt to initialise the 
	 * TableHandler object. Runs on startup
	 * @see TableHandler
	 */
	public static void initialiseTableBookings() {
		try {
			File TableBooking = new File("TableBooking.txt");

			if (!TableBooking.exists())
				TableBooking.createNewFile();
			else {
				FileReader fr = new FileReader(TableBooking);
				BufferedReader br = new BufferedReader(fr);
				String line;

				while ((line = br.readLine()) != null) {
					String[] tableBookingData = line.split(",");
					LocalDateTime tableLDT = LocalDateTime.parse(tableBookingData[0]);
					int tableNo = Integer.parseInt(tableBookingData[1]);
					TableHandler.initialiseTableHandler(tableLDT, tableNo);
				}

				br.close();
				fr.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * From current TableHandler, saves to TableBooking.txt
	 * Runs on program exit
	 * @see TableHandler
	 */
	public static void saveTableBookings() {

		File TableBooking = new File("TableBooking.txt");
		LinkedList<LocalDateTime>[] tablearray = TableHandler.getTableArray();
		// delete existing file since menu contents may have changed since
		// initialization
		if (TableBooking.exists())
			TableBooking.delete();

		try {
			FileWriter fw1 = new FileWriter(TableBooking.getAbsoluteFile());
			BufferedWriter bw1 = new BufferedWriter(fw1);
			PrintWriter pw1 = new PrintWriter(bw1);

			for (int i = 0; i < 30; i++) {
				for (int j = 0; j < tablearray[i].size(); j++) {
					pw1.write(tablearray[i].get(j).toString() + "," + i + "\n");
				}
			}

			pw1.close();
			bw1.close();
			fw1.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
