/**
 * Contribution Tracking
 *
 * @author  Terry Sergeant
 * @date    22 Oct 2007
 *
*/

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

public class ContribDebug1
{
  private static Scanner kb= new Scanner(System.in);
  public static void main(String [] args) throws Exception
  {
    String [] names;
    int [] candidates;
    int [] amounts;
    int numberOfEntries;
    int choice;

    names= new String[100000];
    candidates= new int[100000];
    amounts= new int[100000];

    numberOfEntries= readDataFile(names,candidates,amounts);
    System.out.println("There are currently "+numberOfEntries+" names/numbers");

    do {
      choice= menuChoice();
      switch(choice) {
        case 1: displayContributions(names,candidates,amounts,numberOfEntries); break;
        case 2: searchForContributor(names,candidates,amounts,numberOfEntries); break;
        case 3: numberOfEntries= addContribution(names,candidates,amounts,numberOfEntries); break;
        case 4: numberOfEntries= removeContribution(names,candidates,amounts,numberOfEntries); break;
      } 
    } while (choice != 0);

    writeDataFile(names,candidates,amounts,numberOfEntries); 
  }

  /**
   * Displays menu and gets selection from the user.
   *
   * @return the menu choice of the user
  */
  public static int menuChoice()
  {
    int choice;  // user's menu selection
    do {
      System.out.print("\n\n");
      System.out.println("----------------------------");
      System.out.println("        MENU OPTIONS        ");
      System.out.println("----------------------------");
      System.out.println("[1] Display Contributors");
      System.out.println("[2] Search for Contributor");
      System.out.println("[3] Add a Contribution");
      System.out.println("[4] Remove a Contribution");
      System.out.println("----");
      System.out.println("[0] Exit Program");
      System.out.println("----------------------------");
      System.out.print("Choice: ");
      choice= kb.nextInt();
    } while (choice < 0 || choice > 3);
    kb.nextLine();

    return choice;
  }



  /**
   * Reads contribution data from file into the appropriate arrays.
   *
   * @param names    An array of names to be loaded with data from the file
   * @param candidates An array of candidate codes that identify which
   *        candidate the contribution belongs to
   * @param amounts An array of dollar amounts (no cents) of contribution amounts
   * @return the number of name/phone pairs loaded into the arrays
  */
  public static int readDataFile(String [] names, int [] candidates, int [] amounts) throws FileNotFoundException
  {
    Scanner data= new Scanner(new File("contributions.txt"));
    int n;  // number of elements in the data file

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



  /**
   * Sorts by name; only to be used once to modify data file.
  */
  public static void sort(String [] names, int [] candidates, int [] amounts, int n) 
  {
    int i,j,tempi;
    String temps;

    for (i=0; i<n-1; i++)
      for (j=i+1; j<n; j++)
        if (names[i].compareTo(names[j])>0) {
          tempi= amounts[i];
          amounts[i]= amounts[j];
          amounts[j]= tempi;
          tempi= candidates[i];
          candidates[i]= candidates[j];
          candidates[j]= tempi;
          temps= names[i];
          names[i]= names[j];
          names[j]= temps;
        }
  }

  /**
   * Writes contribution info to file
   *
   * @param names    An array of names 
   * @param candidates An array of candidate codes that identify which
   *        candidate the contribution belongs to
   * @param amounts An array of dollar amounts (no cents) of contribution amounts
   * @param n The number of elements in the parallel arrays
  */
  public static void writeDataFile(String [] names, int [] candidates, int [] amounts, int n) throws Exception
  {
    int i;
    PrintStream out= new PrintStream(new File("contributions.txt"));

    for (i=0; i<n; i++)
      out.println(amounts[i]+" "+candidates[i]+" "+names[i]);

    out.close();
  }


  /**
   * Search for contributor by name.
   *
   * @param names    An array of names 
   * @param candidates An array of candidate codes that identify which
   *        candidate the contribution belongs to
   * @param amounts An array of dollar amounts (no cents) of contribution amounts
   * @param n The number of elements in the parallel arrays
  */
  public static void searchForContributor(String [] names, int [] candidates, int [] amounts, int n)
  {
    String name;
    int i,count= 0;

    System.out.print("\n\nEnter name of contributor to find: ");
    name= kb.nextLine();

    displayHeader();

    for (i=1; i<=n; i++) 
      if (names[i].matches(".*"+name+".*")) {
        count++;
        displayEntry(i,names[i],candidates[i],amounts[i]);
      }
    System.out.println("Done Searching ... "+count+" matches found.");

  }


  /**
   * Allows user to remove contribution by specifying a position number; we
   * confirm the deletion prior
   *
   * @param names    An array of names 
   * @param candidates An array of candidate codes that identify which
   *        candidate the contribution belongs to
   * @param amounts An array of dollar amounts (no cents) of contribution amounts
   * @param n The number of elements in the parallel arrays
  */
  public static int removeContribution(String [] names, int [] candidates, int [] amounts, int n)
  {
    int pos;
    String ans;

    System.out.print("Enter position: ");
    pos= kb.nextInt();
    kb.nextLine();

    if (pos < 0 || pos >= n) {
      System.out.println("There is no entry corresponding to the value you entered ...\n\n");
      return n;
    }

    displayHeader();
    displayEntry(pos,names[pos],candidates[pos],amounts[pos]);

    do {
      System.out.print("Is this the entry you want to delete (y/n): ");
      ans= kb.nextLine().toLowerCase();
    } while (!ans.equals("y") && !ans.equals("n"));
    
    if (ans.equals("n")) {
      System.out.println("Entry "+pos+" was NOT removed ...\n\n");
      return n;
    }
    else {
      for (;pos<n-1; pos++) {
        names[pos]= names[pos+1];
        candidates[pos]= candidates[pos+1];
        amounts[pos]= amounts[pos+1];
      }
      System.out.println("Entry "+pos+" has been removed ...\n\n");
      return n-1;
    }
  }


  /**
   * Allows user to enter a new entry (ordered by name, of course)
   *
   * @param names    An array of names 
   * @param candidates An array of candidate codes that identify which
   *        candidate the contribution belongs to
   * @param amounts An array of dollar amounts (no cents) of contribution amounts
   * @param n The number of elements in the parallel arrays
  */
  public static int addContribution(String [] names, int [] candidates, int [] amounts, int n)
  {
    String newName;
    int candNum,newAmount,pos;

    do {
      System.out.print("Enter name of contributor: ");
      newName= kb.nextLine();
    } while (newName.length()<2);

    do {
      System.out.print("Enter amount of contribution (dollars only): ");
      newAmount= kb.nextInt();
    } while (newAmount <= 0);

    do {
      System.out.print("Enter candidate's id number (1..10): ");
      candNum= kb.nextInt();
    } while (candNum<=0 || candNum>10);
    kb.nextLine();  // toss out extra \n

    pos= n;
    while (pos > 0 && newName.compareToIgnoreCase(names[pos-1]) < 0) {
      names[pos]= names[pos-1];
      amounts[pos]= amounts[pos-1];
      candidates[pos]= candidates[pos-1];
      pos--;
    }
    names[pos]= newName;
    amounts[pos]= newAmount;
    candidates[pos]= candNum;
    return n+1;
  }


  /**
   * Displays the contributions to the screen.
   *
   * @param names    An array of names 
   * @param candidates An array of candidate codes that identify which
   *        candidate the contribution belongs to
   * @param amounts An array of dollar amounts (no cents) of contribution amounts
   * @param n The number of elements in the parallel arrays
  */
  public static void displayContributions(String [] names, int [] candidates, int [] amounts, int n)
  {
    int i;
    displayHeader();
    for (i=0; i<n; i++)
      displayEntry(i,names[i],candidates[i],amounts[i]);
  }

  public static void displayHeader()
  {
    System.out.println("--------------------------------------------");
    System.out.printf("%5s   %-20s %10s %2s\n","Pos","Name of Contributor","Amount","CC");
    System.out.println("--------------------------------------------");
  }

  public static void displayEntry(int pos,String name, int cId, int amount)
  {
    System.out.printf("[%5d] %-20s %10d %2d\n",pos,name,amount,cId);
  }

}

