import java.util.*;

public class PokerHandAssessor
{

  // getRank returns the letter code representing the rank of a card
  public static String getRank(String card)
  {
    return card.substring(0, 1);
  }

  // getSuit returns the letter code representing the suit of a card
  public static String getSuit(String card)
  {
    return card.substring(1,2);
  }


  // getQuadsRank returns the letter code representing the rank of
  // a 4-of-a-kind in a hand, if there is one.
  // if there is no 4-of-a-kind (aka, Quads), then it returns the empty string ("").
  public static String getQuadsRank(String c1, String c2, String c3, String c4, String c5)
  {
    String rank1 = getRank(c1);
    String rank2 = getRank(c2);

    // counts for how often each of the first two ranks appears
    // Note that I only need two counts, because if there are quads,
    // then there are at most two distinct ranks among the five cards
    int count1 = 1;
    int count2 = 1;
    if(getRank(c2).equals(rank1)) {
      count1++;
    }
    if(getRank(c3).equals(rank1)) {
      count1++;
    }
    else if(getRank(c3).equals(rank2)) {
      count2++;
    }
    if(getRank(c4).equals(rank1)) {
      count1++;
    }
    else if(getRank(c4).equals(rank2)) {
      count2++;
    }
    if(getRank(c5).equals(rank1)) {
      count1++;
    }
    else if(getRank(c5).equals(rank2)) {
      count2++;
    }

    if(count1==4) {
      return rank1;
    } else if (count2==4) {
      return rank2;
    } else {
      return "";
    }
  }

  // getFlushSuit returns the single letter code for the suit corresponding to
  // the flush in the five cards, if there is a flush
  // if there is no flush, it returns the empty string ("")
  public static String getFlushSuit(String c1, String c2, String c3, String c4, String c5)
  {
    String suit = getSuit(c1);
    if(getSuit(c2).equals(suit) && getSuit(c3).equals(suit) && getSuit(c4).equals(suit) && getSuit(c5).equals(suit))
    {
      return suit;
    }
    else
    {
      return "";
    }
  }

  // getTripsRank returns the letter code representing the rank of a
  // 3-of-a-kind (Trips), if there is one in the five card hand.
  // if there is no 3-of-a-kind, it returns the empty string ("").
  public static String getTripsRank(String c1, String c2, String c3, String c4, String c5)
  {
    String rank1 = getRank(c1);
    String rank2 = getRank(c2);
    String rank3 = getRank(c3);
    String rank4 = getRank(c4);
    String rank5 = getRank(c5);

    // counts for how often each of the first three ranks appears
    // Note that I only need three counts, because if there are trips,
    // there are at most 3 distinct ranks in the five cards
    int count1 = 1;
    int count2 = 1;
    int count3 = 1;

    if(rank2.equals(rank1)) {
      count1++;
    }

    if(rank3.equals(rank1)) {
      count1++;
    } else if(rank3.equals(rank2)) {
      count2++;
    }

    if(rank4.equals(rank1)) {
      count1++;
    } else if(rank4.equals(rank2)) {
      count2++;
    } else if(rank4.equals(rank3)) {
      count3++;
    }

    if(rank5.equals(rank1)) {
      count1++;
    } else if(rank5.equals(rank2)) {
      count2++;
    } else if(rank5.equals(rank3)) {
      count3++;
    }

    if(count1==3) {
      return rank1;
    } else if(count2==3) {
      return rank2;
    } else if(count3==3) {
      return rank3;
    }

    return "";
  }

  // numericValue returns a numeric code corresponding to the value of the card's number
  // the numeric code is 14 for Aces, 13 for Kings, 12 for Queens, and so on, down to 2.
  public static int numericValue(String rank)
  {
    final String ranks = "23456789TJQKA";
    char c = rank.charAt(0);
    int where = ranks.indexOf(c);
    if (where >= 0)
      return 2 + where;
    return -1;
  }

  // highCard returns the card with the highest rank
  public static String highCard(String c1, String c2)
  {
    String r1 = getRank(c1);
    String r2 = getRank(c2);

    if(numericValue(r1)>numericValue(r2)) {
      return c1;
    } else {
      return c2;
    }
  }

  // Of the five cards in the hand, getHighCardRank returns the rank of the highest card
  public static String getHighCardRank(String c1, String c2, String c3, String c4, String c5)
  {
    String ret = highCard(c1, c2);
    ret = highCard(ret, c3);
    ret = highCard(ret, c4);
    ret = highCard(ret, c5);
    return getRank(ret);
  }

  // readCard prompts the user for the next card, and reads in and returns the 2-letter code representing
  // the rank and suit of the card
  public static String readCard(Scanner in, int whichCard)
  {
    System.out.print("Card " + whichCard + ". Please enter a card number (2-9,T,J,Q,K,A) and suit (c,d,h,s): ");
    String ret = in.next();
    System.out.println();
    return ret;
  }

  public static void assess(String card1, String card2, String card3, String card4, String card5)
  {
    String quadNum   = getQuadsRank   (card1, card2, card3, card4, card5);
    String flushSuit = getFlushSuit   (card1, card2, card3, card4, card5);
    String tripsNum  = getTripsRank   (card1, card2, card3, card4, card5);
    String highCard  = getHighCardRank(card1, card2, card3, card4, card5);

    if(!"".equals(quadNum)) {
      System.out.println("Quad " + quadNum + "'s!!!");
    } else if(!"".equals(flushSuit)) {
      System.out.println("A " + flushSuit + " flush!");
    } else if(!"".equals(tripsNum)) {
      System.out.println("Trip " + tripsNum + "'s!");
    } else {
      System.out.println(highCard + " high.");
    }
  }

  // main reads in a 5 card hand, and displays information about the best
  // hand that can be made with those 5 cards, out of
  // 4-of-a-kind (Quads)
  // Flush (Cards all of the same suit)
  // 3-of-a-kind (Trips)
  // High card
  public static void main(String [] args)
  {
    System.out.println("This program reads in your poker hand and tells you the best hand you can make.");
    System.out.println();

    Scanner console = new Scanner(System.in);
    String card1 = readCard(console, 1);
    String card2 = readCard(console, 2);
    String card3 = readCard(console, 3);
    String card4 = readCard(console, 4);
    String card5 = readCard(console, 5);

    String quadNum   = getQuadsRank   (card1, card2, card3, card4, card5);
    String flushSuit = getFlushSuit   (card1, card2, card3, card4, card5);
    String tripsNum  = getTripsRank   (card1, card2, card3, card4, card5);
    String highCard  = getHighCardRank(card1, card2, card3, card4, card5);

    if(!"".equals(quadNum)) {
      System.out.println("You made quad " + quadNum + "'s!!!");
    } else if(!"".equals(flushSuit)) {
      System.out.println("You made a " + flushSuit + " flush!");
    } else if(!"".equals(tripsNum)) {
      System.out.println("You made trip " + tripsNum + "'s!");
    } else {
      System.out.println("You have " + highCard + " high.");
    }
  }
}
