//****************************************************************************
// File:    cardTest.cpp
// Author:  Dr. Thomas C. Bressoud
// Date:    February 8, 2008
// Class:   CS 173-01, Professor Bressoud
// Purpose: Client program to test out functions for each of the Card, Deck
//          and PokerHand classes
// Input:   None
// Output:  Results of creating and invoking function members on objects of
//          the above three classes
//****************************************************************************
#include <iostream>
using namespace std;

// Include class declarations so they may be used to declare and use object
// instances from each of the classes

#include "Card.h"
#include "Deck.h"
#include "PokerHand.h"

int main() {

  // Create 5 card instances, defining the cards that could make up a 
  // straight flush.
  
  // Note that to refer to the enumerated type Suit in the Card class,
  // I need to qualify the name of the constant with the Card:: scope
  // resolution operator.
  
  Card c1(9, Card::HEARTS);
  Card c2(8, Card::HEARTS);
  Card c3(7, Card::HEARTS);
  Card c4(6, Card::HEARTS);
  Card c5(5, Card::HEARTS);   
  
  // Invoke the toString function on a couple of the Card instances
  
  cout << c1.toString() << endl;
  cout << c2.toString() << endl;
  
  // Create a Deck object and shuffle it
  
  Deck deck;
  deck.shuffle();
  
  // Loop through and print the cards in the suffled deck by dealing them
  // out and printing the resulting cards
  
  int count = 1;
  while (deck.cardsRemaining() > 0) {
    Card dealt = deck.dealCard();
    cout << count << ": " << dealt.toString() << endl;
    count++;
  }
  
  // Then reshuffle the deck
  
  deck.shuffle();
  
  // Create a PokerHand object from the deck and print it out
  
  PokerHand h1(deck);
  h1.print();
  
  // Demonstrate the use of a static class constant
  cout << "Number of cards in a deck: " << Deck::COUNT << endl;
  
  // Create a PokerHand object not from a deck, but from five explicit cards
  
  PokerHand h2(c1,c2,c3,c4,c5);
  h2.print();
  
  // Demonstrate the counting of ranks within a PokerHand
  
  int ranks[13];
  h2.rankCount(ranks);
  for (int i = 0; i < 13; i++) {
    cout << i+1 << ": " << ranks[i] << endl;
  }
  
  // Now go through and determine which poker hand categories that this
  // hand satisfies
   
  if (h2.isFlush()) {
    cout << "Flush detected" << endl;
  } else {
    cout << "Hand is not a flush" << endl;
  }
  int high;
  if (high = h2.isStraight()) {
    cout << high << " high straight detected" << endl;
  } else {
    cout << "Hand is not a straight" << endl;
  }
  int val;
  if (val = h2.isFourOfKind()) {
    cout << val << " four of a kind detected" << endl;
  } else {
    cout << "Hand is not four of a kind" << endl;
  }
  if (val = h2.isThreeOfKind()) {
    cout << val << " three of a kind detected" << endl;
  } else {
    cout << "Hand is not three of a kind" << endl;
  }
  if (val = h2.isOnePair()) {
    cout << val << " pair detected" << endl;
  } else {
    cout << "Hand is not pair" << endl;
  }
  if (h2.isTwoPair()) {
    cout << "Two pair detected" << endl;
  } else {
    cout << "Hand is not two pair" << endl;
  }
  if (h2.isFullHouse()) {
    cout << "Full House detected" << endl;
  } else {
    cout << "Hand is not full house" << endl;
  }
  if (h2.isStraightFlush()) {
    cout << "Straight Flush detected" << endl;
  } else {
    cout << "Hand is not straight flush" << endl;
  }
  if (h2.isRoyalFlush()) {
    cout << "Royal Flush detected" << endl;
  } else {
    cout << "Hand is not royal flush" << endl;
  }
  return 0;
}

