// Arup Guha
// 9/12/02
// Brief Description: This class uses a linked list of card objects to
//                    simulate a hand of cards. The user is allowed to
//                    add and delete cards from their hand, as well as
//                    print out the cards in their hand and score their
//                    hand.
import java.io.*;

public class cardhand {

  private cardnode begin;

  // Default constructor.
  public cardhand() {
    begin = null;
  }

  // Adds a card into the cardhand object.
  public void add(card one) {

    // Creates a node to store the card.
    cardnode c = new cardnode(one);
    
    // Takes care of the empty hand case.
    if (begin == null)
      begin = c;

    // Adding a card to a hand with at least one card.
    else {

      // Adds the new card to the beginning if necessary.
      if ((c.playcard).compareTo(begin.playcard) > 0) {
        c.next = begin;
        begin = c;
      }

      // Adds the card to the appropriate location in the middle/end
      // of the list.
      else {
    
        // Iterate to find the right location to add the card.
        cardnode helper = begin;
        while ((helper.next != null) && 
               (helper.next.playcard.compareTo(c.playcard) > 0))
          helper = helper.next;

        // Adjust the necessary references to add the card.
        c.next = helper.next;
        helper.next = c;
      }
    }

  }

  // Removes the card one from the cardhand object if an equivalent card
  // is in the cardhand object, and returns true in this case. If no such
  // card is found, false is returned.
  public boolean remove(card one) {

    // Take care of empty hand case.
    if (begin == null)
      return false;

    // Take care of the case of deleting from the front of the list.
    if (begin.playcard.compareTo(one) == 0) {
      begin = begin.next;
      return true;
    }

    // Iterate to the correct location in the list to perform the delete.
    cardnode helper = begin;
    while ((helper.next != null) && 
           (helper.next.playcard.compareTo(one) > 0))
      helper = helper.next;
    
    // Check for the case that the card was not in the list because it
    // would have been placed after the last card in the current hand.
    if (helper.next == null)
      return false;

    // Delete the card if it is actually in the list.
    if (helper.next.playcard.compareTo(one) == 0) {
      helper.next = helper.next.next;
      return true;
    }

    // Takes care of the other case where the card isn't in the list.
    return false;
  }

  // Prints out all the cards in the cardhand object in order.
  public void printHand() {

    System.out.println();
    cardnode helper = begin;
    // Iterate through the entire list!!!
    while (helper != null) {
      System.out.println(helper.playcard);
      helper = helper.next;
    }
  }
 
  // Determines the score of the hand.
  public int score() {

    // An array to tabulate the number of cards for each suit.
    int [] numcards = new int[4];
    int sum = 0, i;
    for (i=0; i<numcards.length; i++)
      numcards[i] = 0;

    // Iterate through the cards to score each face card and keep track
    // of how many cards are in each suit.
    cardnode helper = begin;
    while (helper != null) {
      sum += helper.playcard.getvalue();

      // Suite index can be calculated from the rank of the card.
      numcards[(helper.playcard.getrank()-1)/13]++;      
      helper = helper.next;
    }

    // Add extra points for void and singletons.
    for (i=0; i<numcards.length; i++)
      if (numcards[i] < 2)
        sum += (2-numcards[i]);

    return sum;
  }

  public static void main(String [] args) throws IOException {

    // cardhand object to use.
    cardhand myhand = new cardhand();
 
    // Loop until the user wants to quit.
    int menuchoice = menu();    
    while (menuchoice != 5) {

      // Add a card.
      if (menuchoice == 1) {
        System.out.println();
        String suit = getsuit("added");
        String kind = getkind("added");
        card temp = new card(suit,kind);
        myhand.add(temp);
      }

      // Delete a card.
      else if (menuchoice == 2) {
        System.out.println();
        String suit = getsuit("removed");
        String kind = getkind("removed");
        card temp = new card(suit,kind);

        // Display error message if necesary.
        if (!myhand.remove(temp))
          System.out.println("Sorry, you don't have that card to remove.");
      }
      else if (menuchoice == 3) {
        myhand.printHand();
      }
      else if (menuchoice == 4) {
        System.out.println("Total score of your hand: "+myhand.score());
      }
      menuchoice = menu();      
    }

  }

  // Ask the user for the suit of a card.
  public static String getsuit(String action) throws IOException {

    BufferedReader stdin = new BufferedReader
                           (new InputStreamReader(System.in));
  
    System.out.println("What is the suit of the card to be "+action+"?");
    String ans = stdin.readLine();
    return ans;
  }

  // Ask the user for the type/kind of the card.
  public static String getkind(String action) throws IOException {

    BufferedReader stdin = new BufferedReader
                           (new InputStreamReader(System.in));
  
    System.out.println("What is the kind of the card to be "+action+"?");
    String ans = stdin.readLine();
    return ans;
  }


  // Prompts the user with the menu and returns their choice.
  public static int menu() throws IOException {

    BufferedReader stdin = new BufferedReader
                           (new InputStreamReader(System.in));

    int ans=0;
    boolean done = false;

    while (!done) {
      System.out.println();
      System.out.println("Here are your menu choices.");
      System.out.println("1. Add a card to your hand.");
      System.out.println("2. Delete a card from your hand.");
      System.out.println("3. Print out a list of all of yoru cards, in order.");
      System.out.println("4. Print out the score of your hand.");
      System.out.println("5. Quit");

      ans = Integer.parseInt(stdin.readLine());
      if (ans >= 1 && ans <=5)
        done = true;
      else
        System.out.println("That was an invalid choice. Please try again.");
    }
    return ans;  
  }

}
