import java.awt.*;
import java.awt.event.*;
import javax.swing.*;


public class PokerValues implements ActionListener {
	//User Settings
	boolean INFINITE_DRAW = false;
	int DRAW_NUMBER = 5;
	String GAME_NAME = "Poker Hand Values";
	
	//Declares Swing Variables
	JFrame mainFrame;
	JPanel mainPanel;
	JPanel ActionPanel;
	JPanel ScorePanel;
	JButton card[] = new JButton[5];
	JButton redraw, draw, rules, exit;
	JLabel scoreLabel, total;
	
	//Declares variables used to store the random number
	String num[] = new String[5];
	String suit[] = new String[5];
	int number[] = new int[5];
	int cardSuit[] = new int[5];
	
	//Arrays for the cards
	String Cards[][] = {
		{"a","2","3","4","5","6","7","8","9","10","j","q","k"},
		{"h","s","c","d"}
	};
	int values[][] = {
		{1,2,3,4,5,6,7,8,9,10,11,12,13},
		{1,2,3,4}
	};
	
	//Declares the String that holds the card
	String strCard[] = new String[5];
	
	//Declares variables used for displaying the images
	Icon image[] = new Icon[5];
	Icon held[] = new Icon[5];
    Icon deal = new ImageIcon("images/deal.gif");
    Icon newHnd = new ImageIcon("images/new.gif");
    Icon Exit = new ImageIcon("images/exit.gif");
	
	//Declares boolean statements that check for a held card. And if redraw has already be clicked.
	boolean Held[] = new boolean[5];
	boolean keep[] = new boolean[5];
	boolean redrawChk;
	int redrawCnt;
	
	//Declares an array to keep track of cards used (Only saves 5x6 cards to prevent using too many cycles)
	int usedCnt=1;
	String used[][] = new String[5][6];
	
	//Declares Variables for the score and total points
	int point=0;
	String score;
    
    //Declares variables to store temporary data
    int Tnumber[] = new int[5];
	int TcardSuit[] = new int[5];
	String Tnum[] = new String[5];
	String Tsuit[] = new String[5];
	int Tnumber2[] = new int[5];
	int TcardSuit2[] = new int[5];
	String Tnum2[] = new String[5];
	String Tsuit2[] = new String[5];
	
	int cardNumbers[] = new int[5];
	int cardSuits[] = new int[5];
	int cardNumber[] = new int[5];
	int cardSuit2[] = new int[5];
	
	//Generates a random number and matches it with the "Cards" array
	public void random() {
		//Gets a Random number
		int card=0, card2=0;
		for(int j=0; j<5; j++) {
			for(int i=0; i<2; ) {
				card =(int) Math.round(Math.random() *13);
				if (card < 13) i++;
			}
			for(int i=0; i<2; ) {
				card2 =(int) Math.round(Math.random() *6);
				if (card2 < 4) i++;
			}
			
			//Matches the Number to Card array
			this.num[j] = Cards[0][card];
			this.suit[j] = Cards[1][card2];
			this.number[j] = values[0][card];
			this.cardSuit[j] = values[1][card2];
			
			//Makes sure the same card isn't used twice
			for(int k=0; k<j; k++) {
				if(this.num[j] == this.num[k] && this.suit[j] == this.suit[k]) j--;
			}
		}
	}
	
	//Sets the layout and draws the frame
	public PokerValues() {
		random();
		//Creates the frame and panel
		mainFrame = new JFrame(GAME_NAME);
		mainPanel = new JPanel();
		mainPanel.setLayout(new GridLayout());
		ActionPanel = new JPanel();
		ActionPanel.setLayout(new GridLayout());
		ScorePanel = new JPanel();
		ScorePanel.setLayout(new GridLayout(2,2));
		//Sets the window location and size
		mainFrame.setSize(600, 100);
		mainFrame.setLocation(200, 200);
		
		ButtonValues();
		ValueIfs();
		addButtons();
		//Adds the panel to the frame
		mainFrame.getContentPane().add(mainPanel, BorderLayout.NORTH);
		mainFrame.getContentPane().add(ScorePanel, BorderLayout.CENTER);
		mainFrame.getContentPane().add(ActionPanel, BorderLayout.SOUTH);
		//Exits when closed
		mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		//Displays the frame
		mainFrame.pack();
		mainFrame.setVisible(true);
	}
	
	//Adds the Values to the Buttons
	public void ButtonValues() {
		//Adds the card and suit to a string
		for(int i=0; i<5; i++) strCard[i] = num[i] + "-" + suit[i];
		//Uses the string to get the image
        for(int i=0; i<5; i++) image[i] = new ImageIcon("images/" + strCard[i] + ".gif");
        //Adds the image to the button
		for(int i=0; i<5; i++) card[i] = new JButton(image[i]);
		//Makes the Action Buttons
		redraw = new JButton(deal);
		draw = new JButton(newHnd);
		rules = new JButton("Rules");
		exit = new JButton(Exit);
		
		HandValue();
	}
	
	//initializes the variables used in checking the value
	public void HandValue() {
		
		for(int i=0; i<5; i++) {
			cardNumbers[i] = this.number[i];
			cardSuits[i] = this.cardSuit[i];
		}
		
		for(int i=0; i<5; i++) {
			cardNumber[i] = cardNumbers[i];
			cardSuit2[i] = cardSuits[i];
		}
	}
	
	//Checks for the Value of the Hand
	public void ValueIfs() {
		//Puts the array of card drawn in Numerical order
		for(int j=1; j<5; j++) {
			for(int i=4; i>=j; i--) {
				if(cardNumbers[i-1] > cardNumbers[i]) {
					int t=cardNumbers[i-1];
					cardNumbers[i-1] = cardNumbers[i];
					cardNumbers[i] = t;
				}
				if(cardSuits[i-1] > cardSuits[i]) {
					int tmp=cardSuits[i-1];
					cardSuits[i-1] = cardSuits[i];
					cardSuits[i] = tmp;
				}
			}
		}
        if(redrawChk || INFINITE_DRAW) {
        	//Starts Checking for any hands with points
        	if(cardNumbers[0] == 1 && cardSuits[0] == cardSuits[1] && cardNumbers[1] == cardNumbers[2]-1 && cardNumbers[1] >= 10 &&
            cardSuits[1] == cardSuits[2] && cardNumbers[2] == cardNumbers[3]-1 && cardSuits[2] == cardSuits[3] && cardNumbers[3] == cardNumbers[4]-1 &&
            cardSuits[3] == cardSuits[4]) {
            	score = "You got a Royal Flush. This is worth 500 points.";
            	point = point + 500;
            }		
            else if(cardNumbers[0] == cardNumbers[1]-1 && cardSuits[0] == cardSuits[1] && cardNumbers[1] == cardNumbers[2]-1 && cardSuits[1] == cardSuits[2] && 
            cardNumbers[2] == cardNumbers[3]-1 && cardSuits[2] == cardSuits[3] && cardNumbers[3] == cardNumbers[4]-1 && cardSuits[3] == cardSuits[4] || 
            cardNumbers[0] == 1 && cardNumbers[1] == cardNumbers[2]-1 && cardNumbers[2] == cardNumbers[3]-1 && cardNumbers[3] == cardNumbers[4]-1 && cardNumbers[4] == 13) {
            	score = "You got a Straight Flush. This is worth 300 points.";
            	point = point + 300;
            }
            else if(cardNumbers[0] == cardNumbers[1] && cardNumbers[1] == cardNumbers[2] && cardNumbers[2] == cardNumbers[3] ||
            cardNumbers[1] == cardNumbers[2] && cardNumbers[2] == cardNumbers[3] && cardNumbers[3] == cardNumbers[4]) {
                score = "You got Four of a Kind. This is worth 250 points.";
                point = point + 250;
            }
            else if(cardNumbers[0] == cardNumbers[1] && cardNumbers[1] == cardNumbers[2] && cardNumbers[3] == cardNumbers[4] ||
            cardNumbers[0] == cardNumbers[1] && cardNumbers[2] == cardNumbers[3] && cardNumbers[3] == cardNumbers[4]) {
                score = "You got a Full House. This is worth 200 points.";
                point = point + 200;
            }
            else if(cardSuits[0] == cardSuits[1] && cardSuits[1] == cardSuits[2] && cardSuits[2] == cardSuits[3] && cardSuits[3] == cardSuits[4]) {
                score = "You got a Flush. This is worth 150 points.";
                point = point + 150;
            }
            else if(cardNumbers[0] == cardNumbers[1]-1 && cardNumbers[1] == cardNumbers[2]-1 && cardNumbers[2] == cardNumbers[3]-1 &&
            cardNumbers[3] == cardNumbers[4]-1 || cardNumbers[0] == 1 && cardNumbers[1] == cardNumbers[2]-1 && cardNumbers[2] == cardNumbers[3]-1 &&
            cardNumbers[3] == cardNumbers[4]-1 && cardNumbers[4] == 13) {
                score = "You got a Straight. This is worth 150 points.";
                point = point + 150;
            }
            else if(cardNumbers[0] == cardNumbers[1] && cardNumbers[1] == cardNumbers[2] || cardNumbers[1] == cardNumbers[2] && cardNumbers[2] == cardNumbers[3] ||
            cardNumbers[2] == cardNumbers[3] && cardNumbers[3] == cardNumbers[4]) {
                score = "You got Three of a Kind. This is worth 100 points.";
                point = point + 100;
            }
            else if(cardNumbers[0] == cardNumbers[1] && cardNumbers[2] == cardNumbers[3] || cardNumbers[1] == cardNumbers[2] && cardNumbers[3] == cardNumbers[4] ||
            cardNumbers[0] == cardNumbers[1] && cardNumbers[3] == cardNumbers[4]) {
                score = "You got Two Pair. This is worth 75 points.";
                point = point + 75;
            }
            else if(cardNumbers[0] == cardNumbers[1] || cardNumbers[1] == cardNumbers[2] || cardNumbers[2] == cardNumbers[3] ||
            cardNumbers[3] == cardNumbers[4]) {
                score = "You got a Pair. This is worth 50 points.";
                point = point + 50;
            }
            else score = "You got nothing. This is worth 0 points.";
            //Adds the Hand value to the Label "scoreLabel"
            scoreLabel = new JLabel(score, SwingConstants.CENTER);
            }
            else scoreLabel = new JLabel("Click the card to hold, then click deal.", SwingConstants.CENTER);
            //Adds the total points to the label "total"
            total = new JLabel("Total: " + point, SwingConstants.CENTER);
	}
	
	//Adds the buttons to the pane
	public void addButtons() {
		//Adds the listeners that listen for when a button is pressed
		for(int i=0; i<5; i++) card[i].addActionListener(this);	
		redraw.addActionListener(this);
		draw.addActionListener(this);
		rules.addActionListener(this);
		exit.addActionListener(this);
		//Adds the buttons to the panels
		for(int i=0; i<5; i++) mainPanel.add(card[i]);
		ScorePanel.add(scoreLabel);
		ScorePanel.add(total);
		//ScorePanel.add(rules);
		if(redrawChk == false || INFINITE_DRAW)
		ActionPanel.add(redraw);
		ActionPanel.add(draw);
		ActionPanel.add(exit);
		
		scoreLabel.setBorder(BorderFactory.createEmptyBorder(5,5,2,5));
		total.setBorder(BorderFactory.createEmptyBorder(5,5,2,5));
		
	}
	
	//Changes the image of held cards
	public void hold() {
		for(int i=0; i<5; i++) keep[i] = false;
		//Adds the images of the held cards
		for(int i=0; i<5; i++) held[i] = new ImageIcon("images/" + strCard[i] + "-h.gif");
		//Changes the image if the card is held
		for(int i=0; i<5; i++) {
			if(Held[i]) {
				card[i] = new JButton(held[i]);
				keep[i] = true;
			}
			else card[i] = new JButton(image[i]);
		}
		//Runs the addButtons() method
		addButtons();
	}
	
	//Keeps cards being held and replaces the other cards
	public void redraw() {
		//Initializes the temporary variables
		for(int i=0; i<5; i++) {
			Tnum[i] = num[i];
			Tsuit[i] = suit[i];
			Tnumber[i] = number[i];
			TcardSuit[i] = cardSuit[i];
		}
		//If there are more than 6 values in the used array, then it starts over
		if(usedCnt == 6)
		usedCnt = 1;
		//Adds the last set of cards to the used array
		int t=usedCnt;
		for(int i=t-1; i<t; i++) {
			for(int j=0; j<5; j++) {
				used[j][i] = num[j] + "-" + suit[j];
			}
		}
		usedCnt+=1;
		//Checks for any duplicate answers and gets a new vlue for any
		for(int i=0; i<1; ) {
			random();
			ButtonValues();
			
			boolean diff=true;
			for(int j=0; j<5; j++) {
				for(int k=0; k<usedCnt; k++) {
					if(strCard[0].equals(used[j][k]) || strCard[1].equals(used[j][k]) || strCard[2].equals(used[j][k]) || strCard[3].equals(used[j][k]) || strCard[4].equals(used[j][k])) {
						random();
						num[j] = Tnum2[j];
						suit[j] = Tsuit2[j];
						number[j] = Tnumber2[j];
						cardSuit[j] = TcardSuit2[j];
						ButtonValues();
						
						diff = false;
					}
				}
			}
			if(diff) i=1;
		}
		
		for(int i=0; i<5; i++) {
			//Gets the temporary value for the card so that the card is held
			if(Held[i] || keep[i]) {
				num[i] = Tnum[i];
				suit[i] = Tsuit[i];
				number[i] = Tnumber[i];
				cardSuit[i] = TcardSuit[i];
				ButtonValues();
				card[i] = new JButton(image[i]);
				Held[i] = false;
				cardNumbers[i] = cardNumber[i];
				cardSuits[i] = cardSuit2[i];
				
				Tnum2[i] = num[i];
				Tsuit2[i] = suit[i];
				Tnumber2[i] = number[i];
				TcardSuit2[i] = cardSuit[i];
			}
			else {
				Tnum[i] = num[i];
				Tsuit[i] = suit[i];
				Tnumber[i] = number[i];
				TcardSuit[i] = cardSuit[i];
			}
		}
		ValueIfs();
		addButtons();
	}
	
	//Performs the action when a button is clicked
	public void actionPerformed(ActionEvent event) {
		mainPanel.setLayout(new GridLayout());
		ActionPanel.setLayout(new GridLayout());
		ScorePanel.setLayout(new GridLayout(2,2));
		//runs the method "hold()" if the card is clicked
		for(int i=0; i<5; i++) {
			if(event.getSource() == card[i] && redrawChk == false || event.getSource() == card[i] && INFINITE_DRAW) {
	            mainPanel.removeAll();
            	ActionPanel.removeAll();
            	ScorePanel.removeAll();
				if(Held[i])
				Held[i] = false;
				else Held[i] = true;
				hold();
			}
		}
		//Runs the redraw() method when clicked
		if(event.getSource() == redraw) {
            mainPanel.removeAll();
            ActionPanel.removeAll();
            ScorePanel.removeAll();
            redrawCnt++;
            if(redrawCnt == DRAW_NUMBER || INFINITE_DRAW) {
				redrawChk = true;
				redrawCnt = 0;
			}
			redraw();
			for(int i=0; i<5; i++) keep[i] = false;
		}
		//sets all values back to the original and starts over
		if(event.getSource() == draw) {
            mainPanel.removeAll();
            ActionPanel.removeAll();
            ScorePanel.removeAll();
            for(int i=0; i<5; i++) {
            	Held[i] = false;
            	keep[i] = false;
            }
			redrawChk = false;
			if(INFINITE_DRAW) 
			point=0;
			random();
			ButtonValues();
			ValueIfs();
			addButtons();
		}
		//Displays rules when clicked
		if(event.getSource() == rules) {
			JOptionPane.showMessageDialog(null,"Text","Rules",JOptionPane.PLAIN_MESSAGE);
		}
		//Exits the program
		if(event.getSource() == exit)
		System.exit(0);	
		
		mainFrame.getContentPane().add(mainPanel, BorderLayout.NORTH);
		mainFrame.getContentPane().add(ScorePanel, BorderLayout.CENTER);
		mainFrame.getContentPane().add(ActionPanel, BorderLayout.SOUTH);
		mainPanel.repaint();
		ScorePanel.repaint();
		ActionPanel.repaint();
		mainFrame.setVisible(true);
	}
	
	//What starts the program
	public static void main(String args[]) {
		PokerValues container = new PokerValues();
	}
}