/**
 * 
 */
package ats_jp.activity.cardgame;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map.Entry;
import java.util.Set;

import ats_jp.activity.profile.PlayerProfile;

/**
 * @author TMS
 *
 */
public class PlayingCard implements Card 
{
	// constant field
	public static final int RANK=200;
	public static final int ACE = 1;
	public static final int TWO = 2;
	public static final int THREE = 3;
	public static final int FOUR = 4;
	public static final int FIVE = 5;
	public static final int SIX = 6;
	public static final int SEVEN = 7;
	public static final int EIGHT = 8;
	public static final int NINE = 9;
	public static final int TEN = 10;
	public static final int JACK = 11;
	public static final int QUEEN = 12;
	public static final int KING = 13;
	
	public static final int SUIT = 201;
	public static final int SPADES = 100;
	public static final int HEARTS = 101;
	public static final int DIAMOND = 102;
	public static final int CLUBS = 103;
	
	public static final int STR_RANK=202;
	public static final String STR_ACE = "Ace";
	public static final String STR_TWO = "Two";
	public static final String STR_THREE = "Three";
	public static final String STR_FOUR = "Four";
	public static final String STR_FIVE = "Five";
	public static final String STR_SIX = "Six";
	public static final String STR_SEVEN = "Seven";
	public static final String STR_EIGHT = "Eight";
	public static final String STR_NINE = "Nine";
	public static final String STR_TEN = "Ten";
	public static final String STR_JACK = "Jack";
	public static final String STR_QUEEN = "Queen";
	public static final String STR_KING = "King";
	
	public static final int STR_SUIT=203;
	public static final String STR_SPADES = "Spades";
	public static final String STR_HEARTS = "Hearts";
	public static final String STR_DIAMONDS = "Diamonds";
	public static final String STR_CLUBS = "Clubs";
	
	private static final HashMap<String, String> STR_RANK_MAP= new HashMap<String, String>() {{
		put("STR_ACE","");
		put("STR_TWO","");
		put("STR_THREE","");
		put("STR_FOUR","");
		put("STR_FIVE","");
		put("STR_SIX","");
		put("STR_SEVEN","");
		put("STR_EIGHT","");
		put("STR_NINE","");
		put("STR_TEN","");
		put("STR_JACK","");
		put("STR_QUEEN","");
		put("STR_KING","");
	
	}}
		
	// normal attribute
	
	private static HashMap<Integer, PlayingCard> myMapDeck = new HashMap<Integer, PlayingCard>();
	
	private int rank;
	private int suit;
			
	@Override
	public Object getCardAttribute(int attribute) throws CardException {

		Object resultObj=null;
		
		switch (attribute) 
		{
		
			case PlayingCard.RANK:
				resultObj=(Integer) getRank();
				break;
			case PlayingCard.SUIT:
				resultObj=(Integer) getSuit();
				break;
			case PlayingCard.STR_RANK:
				resultObj= (String) getStrRank(getRank());
				// come faccio??? Utilizzo una EnumTable???
				break;
			case PlayingCard.STR_SUIT:
				resultObj=(String) getStrSuit(getSuit());
				// come faccio??? Problema analogo a sopra...
				break;
		
			default:
				throw new IllegalArgumentException("Invalid argument");
		}
		
		return resultObj;
	}
	
	private String getStrRank(int paramRank)
	{
		String result="";
		
		switch (paramRank) 
		{
		
			case PlayingCard.ACE:
				result = PlayingCard.STR_ACE;
				break;
			case PlayingCard.TWO:
				result = PlayingCard.STR_TWO;
				break;
			case PlayingCard.THREE:
				result = PlayingCard.STR_THREE;
				break;
			case PlayingCard.FOUR:
				result = PlayingCard.STR_FOUR;
				break;
			case PlayingCard.FIVE:
				result = PlayingCard.STR_FIVE;
				break;
			case PlayingCard.SIX:
				result = PlayingCard.STR_SIX;
				break;
			case PlayingCard.SEVEN:
				result = PlayingCard.STR_SEVEN;
				break;
			case PlayingCard.EIGHT:
				result = PlayingCard.STR_EIGHT;
				break;
			case PlayingCard.NINE:
				result = PlayingCard.STR_NINE;
				break;
			case PlayingCard.TEN:
				result = PlayingCard.STR_TEN;
				break;
			case PlayingCard.JACK:
				result = PlayingCard.STR_JACK;
				break;
			case PlayingCard.QUEEN:
				result = PlayingCard.STR_QUEEN;
				break;
			case PlayingCard.KING:
				result = PlayingCard.STR_KING;
				break;
			
			default:
				throw new IllegalArgumentException("Invalid rank (doesn't exist!)");
		}
		
		return result;
	}
	
	private String getStrSuit(int paramSuit)
	{
		String result = "";
		switch (paramSuit) 
		{
		
			case PlayingCard.SPADES:
				result = PlayingCard.STR_SPADES;
				break;
			case PlayingCard.HEARTS:
				result = PlayingCard.STR_HEARTS;
				break;
			case PlayingCard.DIAMOND:
				result = PlayingCard.STR_DIAMONDS;
				break;
			case PlayingCard.CLUBS:
				result = PlayingCard.STR_CLUBS;
				break;
				
			default:
				throw new IllegalArgumentException("Invalid suit (doesn't exist!)");
		}
		
		return result;
	}
	
	private PlayingCard(int rank, int suit)
	{
		if((rank>0 && rank<14) && (suit>99 && suit<104)){
			this.setRank(rank);
			this.setSuit(suit);
		} else {
			throw new IllegalArgumentException("Invalid rank's value or suit's value");
		}

	}

	/**
	 * @return the rank
	 */
	public int getRank() {
		return rank;
	}

	/**
	 * @param rank the rank to set
	 */
	private void setRank(int rank) {
		this.rank = rank;
	}

	/**
	 * @return the suit
	 */
	public int getSuit() {
		return suit;
	}

	/**
	 * @param suit the suit to set
	 */
	private void setSuit(int suit) {
		this.suit = suit;
	}
	
	public String toString()
	{
		String resultString="";
		try {
			resultString=getCardAttribute(PlayingCard.STR_RANK)+" of "+getCardAttribute(PlayingCard.STR_SUIT);
		} catch (CardException e) {
			e.printStackTrace();
			System.out.println("Invalid attribute");
		}
		
		return resultString;
	}
	
	public boolean equals(PlayingCard card)
	{
		boolean flag=false;
		try
		{
			if(getCardAttribute(PlayingCard.RANK)==card.getCardAttribute(PlayingCard.RANK)
					&& getCardAttribute(PlayingCard.RANK)==card.getCardAttribute(PlayingCard.RANK))
			{
				flag=true;
			}
		} catch(CardException exc) {
			exc.printStackTrace();
			System.out.println("Invalid attribute");
		}
		
		return flag;
	}
	
	public static PlayingCard getCard(int paramRank, int paramSuit)
	{
		//**************************************//
		// start my beautiful code :D (I hope!) //
		//**************************************//
		
		// creo la carta coi parametri forniti
		
		PlayingCard paramPlayingCard = new PlayingCard(paramRank, paramSuit);
		
		// devo vedere se è presente
		
		Integer nextPos=null;
		
		if(!myMapDeck.containsValue(paramPlayingCard))
		{
			nextPos=new Integer(myMapDeck.size()+1);
			
			myMapDeck.put(nextPos, paramPlayingCard);
		} else {
			Set<Integer> tmpSet=myMapDeck.keySet();
			for(Integer pc : tmpSet)
			{
				if(myMapDeck.get(pc).equals(paramPlayingCard))
				{
					nextPos=pc;
					System.out.print("\n"+nextPos+"\n");
					break;
				}
			}
		}
				
		System.out.println(myMapDeck.get(nextPos));
		
		return myMapDeck.get(nextPos);
		
	}
	
}
