/**
 * Reverse Phone Book Lookup (with extra features).
 *
 * @author Terry Sergeant
 * @version In Class Demo
 *
 * <pre>
 * Extra features include ordered insert and remove as well as write
 * back to file.
 * </pre>
*/

import java.util.Scanner;
import java.io.File;
import java.io.PrintStream;
import java.io.IOException;

public class NNDebug5
{
	public static void main(String [] args) throws IOException
	{
		String [] names;        // list of names
		String [] phoneNumbers; // list of phoneNumbers
		int numberOfEntries;    // how many names/phone numbers we have
		int choice;             // user's selection from the menu

		names= new String[10000];
		phoneNumbers= new String[10000];

		numberOfEntries= readNamesAndNumbers(names,phoneNumbers);
		do {
			choice= menuChoice();
			switch (choice) {
				case 1: displayAll(names,phoneNumbers,numberOfEntries); break;
				case 2: reverseLookup(names,phoneNumbers,numberOfEntries); break;
				case 3: numberOfEntries= insertEntry(names,phoneNumbers,numberOfEntries); break;
				case 4: numberOfEntries= removeEntry(names,phoneNumbers,numberOfEntries); break;
			}
		} while (choice!=5);

		saveNamesAndNumbers(names,phoneNumbers,numberOfEntries);
		System.out.println("\nTHE END");
	}


	/**
	 * Displays menu and get's user's selection
	 *
	 * @return the user's menu selection
	*/
	public static int menuChoice()
	{
		Scanner kb= new Scanner(System.in);
		int choice;   // user's selection

		System.out.println("\n\n");
		System.out.print("------------------------------------\n");
		System.out.print("[1] Display all Entries\n");
		System.out.print("[2] Search by Phone Number\n");
		System.out.print("[3] Insert a New Entry\n");
		System.out.print("[4] Remove an Entry\n");
		System.out.print("[5] Exit Program\n");
		System.out.print("------------------------------------\n");
		do {
			System.out.print("Your choice: ");
			choice= kb.nextInt();
		} while (choice < 1 || choice > 5);

		return choice;
	}


	/**
	 * Removes an existing entry from the list (unordered remove).
	 *
	 * @param names    our list of names 
	 * @param numbers  our list of phone numbers 
	 * @param n        number of names/phone numbers in our list
	 * @return the new number of entries in the list
	*/
	public static int removeEntry(String [] names, String [] numbers, int n)
	{
		Scanner kb= new Scanner(System.in);
		String  numberToRemove;  // entry to be removed (entered by user)
		int     pos;             // position at which numberToRemove is found

		System.out.print("Enter a phone number to be removed: ");
		numberToRemove= kb.nextLine();

		pos= findPosition(numbers,n,numberToRemove);
		System.out.println("\nFound "+numberToRemove+": "+names[pos]);
		for (; pos<n-1; pos++) {
			numbers[pos]= numbers[pos+1];
			names[pos]= names[pos+1];
		}
		n--;
		System.out.println("Entry has been removed!\n");

		System.out.print("-----------------------------------------\n");
		System.out.println("Press <Enter> to Continue");
		kb.nextLine();

		return n;
	}


	/**
	 * Inserts a new entry into the list (unordered insert).
	 *
	 * @param names    our list of names 
	 * @param numbers  our list of phone numbers 
	 * @param n        number of names/phone numbers in our list
	 * @return the new number of entries in the list
	*/
	public static int insertEntry(String [] names, String [] numbers, int n)
	{
		Scanner kb= new Scanner(System.in);
		String newName;   // name to be inserted into our list
		String newNumber; // phone number to be inserted into our list
		int i;            // location at which we will insert the new name

		System.out.print("Enter name to be inserted  : ");
		newName= kb.nextLine();
		System.out.print("Enter number to be inserted: ");
		newNumber= kb.nextLine();

		// find the location (shift as we search from end)
		i= n;
		while (i>0 && names[i-1].compareToIgnoreCase(newName) > 0) {
			names[i]= names[i-1];
			numbers[i]= numbers[i-1];
			i--;
		}

		// insert it
		names[i]= newName;
		numbers[i]= newNumber;

		return n+1;
	}


	/**
	 * Displays all entries in the list.
	 *
	 * @param names    our list of names 
	 * @param numbers  our list of phone numbers 
	 * @param n        number of names/phone numbers in our list
	*/
	public static void reverseLookup(String [] names, String [] numbers, int n)
	{
		Scanner kb= new Scanner(System.in);
		String numberToLookup;  // value entered to user to be looked up
		int pos;                // position in array where value is found

		System.out.print("Enter a phone number: ");
		numberToLookup= kb.nextLine();
		pos= findPosition(numbers,n,numberToLookup);
		if (pos==-1)
			System.out.print("\nThe number "+numberToLookup+" was not found in our list.\n");
		else {
			System.out.println("\nFound "+numberToLookup+": "+names[pos]);
		}

		System.out.print("-----------------------------------------\n");
		System.out.println("Press <Enter> to Continue");
		kb.nextLine();
	}


	/**
	 * Attempts to find searchVal in list of numbers.
	 *
	 * @param numbers   our list of phone numbers 
	 * @param n         number of phone numbers in our list
	 * @param searchVal value that we want to find in the array
	 * @return position at which searchVal was found; (-1 if not found)
	*/
	public static int findPosition(String [] numbers, int n, String searchVal)
	{
		int i;
		for (i=0; i<n; i++)
			if (numbers[i].equals(searchVal))
				return i;
		return -1;
	}


	/**
	 * Displays all entries in the list.
	 *
	 * @param names    our list of names 
	 * @param numbers  our list of phone numbers 
	 * @param n        number of names/phone numbers in our list
	*/
	public static void displayAll(String [] names, String [] numbers, int n)
	{
		Scanner kb= new Scanner(System.in);
		int i;

		System.out.print("\n\n-----------------------------------------\n");
		System.out.print("Phone Number   Name\n");
		System.out.print("-----------------------------------------\n");
		for (i=0; i<n; i++)
			System.out.println(numbers[i]+"       "+names[i]);

		System.out.print("-----------------------------------------\n");
		System.out.println("Press <Enter> to Continue");
		kb.nextLine();
	}


	/**
	 * Saves list of names and numbers back to the data file.
	 *
	 * @param names    our list of names 
	 * @param numbers  our list of phone numbers 
	 * @param n        number of names/phone numbers in our list
	*/
	public static void saveNamesAndNumbers(String [] names, String [] numbers, int n) throws IOException
	{
		PrintStream f= new PrintStream(new File("data.txt"));
		for (int i=0; i<n; i++)
			f.println(numbers[i]+" "+names[i]);
		f.close();
	}



	/**
	 * Reads names and numbers data file into the appropriate arrays.
	 *
	 * @param names    An array of names to be loaded with data from the * file.the number of name/phone pairs loaded into the arrays
	 * @param numbers  An array of phone numbers to be loaded with data from the * file.the number of name/phone pairs loaded into the arrays
	 * @return the number of name/phone pairs loaded into the arrays
	*/
	public static int readNamesAndNumbers(String [] names, String [] numbers) throws IOException
	{
		Scanner data= new Scanner(new File("data.txt"));
		int n;

		n= 0;
		while (data.hasNextLine())
		{
			numbers[n]= data.next();
			names[n]= data.nextLine().trim();  // read and then chop off leading space
			n= n + 1;
		}
		return n;
	}
}



