/*
	For: Poker
	
	Created by Travis Roe
*/
import java.util.*;

public class Hand implements Comparable<Hand>{

	/*
		Hands have Cards. To store them I'm using
		an ArrayList
	*/
	private ArrayList<Card> cards;
	
	public Hand(){
		//initialize the ArrayList of Cards
		cards = new ArrayList<Card>();
	}
	
	/*
		Adds a card to the hand.
		Notice that this function does not check to see
		if it already has 5 cards, it just adds them.
	*/
	public void add(Card c){
		cards.add(c);
	}
	
	/*
		Replaces the card at index with c
	*/
	public void replace(int index, Card c){
		cards.set(index, c);
	}
	
	/*
		Returns an array of all how often a single kind of
		card is in the hand.
		Index 0 is for 2,
		Index 1 is for 3,
		Index 12 is for the Ace,
		A given index, i, is how many of Card are in Hand
			with a corresponding value of Card.VALUES.charAt(i)
	*/
	
	public int[] getFrequency(){
		int[] freq = new int[Card.VALUES.length()];
		//for every card in the hand
		for(Card c : cards){
			//increment the number of that card in the hand
			freq[Card.VALUES.indexOf(c.getValue())]++;
		}
		return freq;
	}
	
	/*
		Compares one hand to another.
		if this > h, return > 0
		if this < h return < 0
		if this = h, return 0
	*/
	public int compareTo(Hand h){
	
		//get the card frequency of both hands
		int freq[] = getFrequency();
		int opFreq[] = h.getFrequency();
		
		//reserve the ints that will hold the index to the most frequent card
		int highFreqIndex = 0;
		int highOpFreqIndex = 0;
		
		//search through the arrays
		for(int x = 0; x < freq.length; x++){
			//if there is more of a given card, set the high index to that index
			if(freq[x] >= freq[highFreqIndex]) highFreqIndex = x;
			if(opFreq[x] >= opFreq[highOpFreqIndex]) highOpFreqIndex = x;
		}
		
		//if there are less of our more frequent hand than the opponents, return -1
		if(freq[highFreqIndex] < opFreq[highOpFreqIndex]) return -1;
		//if there are more of our most frequent hand than the opponents, return 1
		else if(freq[highFreqIndex] > opFreq[highOpFreqIndex]) return 1;
		
		/*
			Otherwise, both players have the same number of their most frequent card.
			In that case, then each the index doubles as the value of the card.
			(
				This is why Card.VALUE is ordered 2->A. 
				'A' (at index 12) is worth more than '5' (at index 3)
			)
			
			This handles all 3 of the situations:
			indexOf('A') - indexOf('5') = 9 > 0
			indexOf('5') - indexOf('A') = -9 < 0
			indexOf('A') - indexOf('A') = 0
		*/
		else return highFreqIndex - highOpFreqIndex;
	}
	
	public String toString(){
		
		/*
			to reduce the number of string concatonations that occur, a StringBuffer 
			was used. StringBuffers are powerful classes that are, in effect,
			changable and resizable Strings.
		*/
		StringBuffer buffer = new StringBuffer();
		int index = 1;
		for(Card c :  cards){
			buffer.append(index);
			buffer.append('.');
			buffer.append(c);
			buffer.append(" ");
			index++;
		}
		
		/*
			They're not strings, but wouldn't you know it? the toString() method
			returns a String of the data inside them.
		*/
		return buffer.toString();
	}
}