#include "Deck.h"

Deck::Deck()
//postcondition: a deck of cards of size "size"
{
	int suitNum;
	for (int i = 0; i < 52; i++) {
		Card thisCard;					//create card to store information
		thisCard.numVal = (i % 13) + 2;	//i% 13 gives 0-12, need to adjust up to min value of 2
		suitNum = i % 4;				//gives 0-3, or 4 different suits
		switch (suitNum) {
		case 0:
			thisCard.suit = "spades";
			break;
		case 1:
			thisCard.suit = "diamonds";
			break;
		case 2:
			thisCard.suit = "clubs";
			break;
		case 3:
			thisCard.suit = "hearts";
			break;
		}

		//set value for number cards
		if (thisCard.numVal < 11) {
			thisCard.value = to_string(thisCard.numVal);
		}
		//set value for cards greater than 9
		else {
			switch (thisCard.numVal) {
			case 11:
				thisCard.value = "J";
				break;
			case 12:
				thisCard.value = "Q";
				break;
			case 13:
				thisCard.value = "K";
				break;
			case 14:	//Aces high
				thisCard.value = "A";
				break;
			}
		}

		//track number of cards added
		cards.push_back(thisCard);
	}
}

Deck::Deck(int numOfCards)
//postcondition: a deck of cards of size "size"
{
	int suitNum;
	for (int i = 0; i < numOfCards; i++) {
		Card thisCard;					//create card to store information
		thisCard.numVal = (i % 13) + 2;	//i% 13 gives 0-12, need to adjust up to min value of 2
		suitNum = i % 4;				//gives 0-3, or 4 different suits
		switch (suitNum) {
		case 0:
			thisCard.suit = "spades";
			break;
		case 1:
			thisCard.suit = "diamonds";
			break;
		case 2:
			thisCard.suit = "clubs";
			break;
		case 3:
			thisCard.suit = "hearts";
			break;
		}

		//set value for number cards
		if (thisCard.numVal < 11) {
			thisCard.value = to_string(thisCard.numVal);
		}
		//set value for cards greater than 9
		else {
			switch (thisCard.numVal) {
			case 11:
				thisCard.value = "J";
				break;
			case 12:
				thisCard.value = "Q";
				break;
			case 13:
				thisCard.value = "K";
				break;
			case 14:	//Aces high
				thisCard.value = "A";
				break;
			}
		}

		//track number of cards added
		cards.push_back(thisCard);
	}
}

void Deck::outputDeck()
{
	//output intro
	cout << "Your cards are:" << endl;
	//output each card starting with top of deck
	for (int i = 0; i < cards.size(); i++) {
		cout << cards[i].value << " of " << cards[i].suit << endl;
	}
	//blank line
	cout << endl;
}

Card Deck::dealCard()
{
	//return card at front of vector
	Card myCard = cards[0];
	//remove card from vector
	cards.erase(cards.begin());
	return myCard;
}

Deck Deck::dealCard(int numOfCards)
{
	Deck myDeck(0);					//Create deck of size 0
	for (int i = 0; i < numOfCards; i++) {
		myDeck.addCard(cards[0]);
		cards.erase(cards.begin());
	}
	return myDeck;
}

void Deck::addCard(Card myCard) {
	//add new card to bottom of deck
	cards.push_back(myCard);
}

void Deck::shuffle() {
	//set random seed
	srand(time(0));

	//for each card up to current size
	for (int i = 0; i < cards.size(); i++) {
		//find random postiion between 0 and vector size -1
		int position = rand() % cards.size();

		//swap card in random position with current card
		Card temp = cards[position];
		cards[position] = cards[i];
		cards[i] = temp;
	}
}

int Deck::getSize() {
	return cards.size();
}

//Card operator overloads
//========================================================================================
//overload less than for Card
bool operator <(Card card1, Card card2) {
	if (card1.numVal < card2.numVal)
		return true;
	else
		return false;
}

//overload greater than for Card
bool operator >(Card card1, Card card2) {
	if (card1.numVal > card2.numVal)
		return true;
	else
		return false;
}

//overload equal for Card
bool operator ==(Card card1, Card card2) {
	if (card1.numVal == card2.numVal)
		return true;
	else
		return false;
}

//overload insertion for card
ostream& operator <<(ostream& outStream, Card myCard) {
	outStream << myCard.value << " of " << myCard.suit;
	return outStream;
}