/***
 *
 * This program defines testing functions and utilities for cards.h,c.  See the
 * documentation in cards.h for further details.
 *
 * Author: Gene Fisher (gfisher@calpoly.edu)
 * Created: 23apr12
 * Modified: 26apr12
 */

#include "cards.h"

#define MAX_SHUFFLES 10        /* Maximum number of times to test shuffle */


/***
 *
 * Function test_compare_two_cards calls compare_two_cards up to DECK_SIZE * 3
 * times.  The first DECK_SIZE calls compare the cards of the given
 * unshuffled_deck offset up by one card in the 2nd card of the comparison.
 * I.e., unshuffled_deck[i] is compared with unshuffled_deck[(i+1) %
 * DECK_SIZE], for each 0 <= i < DECK_SIZE.  This should yield all false
 * comparisons, except for the last.  The second DECK_SIZE calls compare the
 * cards of unshuffled_deck offset up by one card in the 1st card of the
 * comparison.  I.e., unshuffled_deck[(i+1) % CARD_SIZE] is compared with
 * unshuffled_deck[i].  This should yield all true comparisons, except for the
 * last.  The final DECK_SIZE (or fewer) calls compare cards of the unshuffled
 * and shuffled decks in order, except where the cards are the same.
 *
 */
void test_compare_two_cards(
    Deck unshuffled_deck,       /* Unshuffled deck to use in testing */
    Deck shuffled_deck          /* shuffled deck to use in testing */
);

/***
 *
 * Function test_deal_two_hands calls deal_two_hands six times, with hand sizes
 * 0, 1, 2, 3, 10, and 26.  It does these six calls on two differet decks, in
 * the given inputs deck1 and deck2.  The deal starts from the 0th position of
 * the decks.  The dealt hands for each call are output to the terminal.  In
 * the last call, the deck runs out of cards, so only partial hands are dealt.
 *
 */
void test_deal_two_hands(
    Deck deck1,                 /* First deck to start dealing from */
    Deck deck2                  /* Second deck to start dealing from */
);
    
/***
 *
 * Function test_shuffle calls shuffle a number of times and outputs the results
 * to the terminal in a side-by-side display of each shuffled deck.  The
 * new_deck input is the starting unshuffled deck.  The num_shuffles input is
 * the number of times to call shuffle.  Num_shuffles must be less than
 * MAX_SHUFFLES, which is the maximum size of the side-by-side display.  The
 * first of the shuffled decks is returned in the shuffled_deck reference
 * parameter.
 *
 */
void test_shuffle(
    Deck new_deck,              /* New deck to send to shuffle the 1st time */
    int num_shuffles,           /* Number of times to call shuffle */
    Deck shuffled_deck          /* Return shuffle deck */
);

/***
 *
 * Function deal_and_dump is called from test_deal_two_hands to call the dealing
 * function once and output the results.  The deck, top, and num_cards
 * parameters are passed on to deal_two_hands.  The number of cards dealt is
 * passed back from the dealing function.
 *
 */
int deal_and_dump(
    Deck deck,                  /* Deck to deal from */
    int top,                    /* Index of top of deck */
    int num_cards               /* Number of cards to deal */
);

/***
 *
 * Function dump_hand dumps the given hand to the terminal, preceded by the
 * given message string.
 *
 */
void dump_hand(
    Hand hand,                  /* Hand to dump */
    char* message               /* String to print in front hand cards */
);

/***
 *
 * Function dump_n_decks is a testing utility that dumps up to NUM_SHUFFLES
 * decks in a tab-separated, side-by-side display on the terminal.  The decks
 * to dump are in the given decks parameter, and the number of decks to dump is
 * in the num_decks parameter.
 *
 */
void dump_n_decks(
    Deck* decks,                /* Array of decks do dump */
    int num_decks               /* Number of decks in the array */
);

/***
 *
 * Function copy_deck is a testing utility that copies all of the cards from
 * src_deck into dest_deck.
 *
 */
void copy_deck(
    Deck dest_deck,             /* Destination deck, to be copied into */
    Deck src_deck               /* Source deck, to be copied from */
);

/***
 *
 * Function card_appears_in_deck_exactly_once is a testing utility that returns
 * true if the given card appears exactly one time as an element of the given
 * deck, false otherwise.  The times_found output parameter is set to the exact
 * number of times the card is found in the deck.
 *
 */
int card_appears_in_deck_exactly_once(
    Card card,                  /* Card to check for */
    Deck deck,                  /* Deck to search in */
    int* times_found            /* Counter of number of times */
);