import java.util.*;
import java.net.*;
import java.applet.*;
import java.awt.*;
import java.awt.image.*;

public class pokerGame extends Applet {

	Frame dFrame = null;
	Dialog dDialog = null;
	
	Color backgroundColor = new Color(0, 135, 30);
	
	CardLayout cl = new CardLayout();
	CardLayout c_l = new CardLayout();
	
	Panel southPanel = new Panel();
	Panel northPanel = new Panel();
	Panel beforePanel = new Panel();
	Panel dealPanel = new Panel();
	Panel afterPanel = new Panel();
	Panel discardPanel = new Panel();
	Panel blankPanel = new Panel();

	int betValue;
	Integer earnings;

	boolean flush = false;
	boolean straight = false;
	boolean royal = false;
	boolean royalflush = false;
	boolean straightflush = false;
	boolean pair = false;
	boolean twopair = false;
	boolean threeofakind = false;
	boolean fourofakind = false;
	boolean fullhouse = false;
	boolean youlose = false;
	
	Font outputFont = new Font("TimesRoman", Font.BOLD, 48);

	Checkbox discardBox[] = new Checkbox[5];

	Button dealButton = new Button("Deal");
	Button discardButton = new Button("Discard");
	Button newHandButton = new Button("New Hand");
	Choice betChoice = new Choice();
	Label earningsLabel1 = new Label();
	Label earningsLabel2 = new Label();
	Label earningsLabel3 = new Label();

	Integer CardValue[] = new Integer[5];
	Integer SuitValue[] = new Integer[5];
	String NameValue[] = new String[5];

	Integer CardValueTemp[] = new Integer[5];

	Vector deckVector = new Vector();
	Vector deckValueVector = new Vector();
	Vector deckSuitVector = new Vector();

	int discardNumber = 0;
	
	static String CardName[] = new String[52];

	static {
		CardName[0] = "AceOfSpades.gif";
		CardName[1] = "TwoOfSpades.gif";
		CardName[2] = "ThreeOfSpades.gif";
		CardName[3] = "FourOfSpades.gif";
		CardName[4] = "FiveOfSpades.gif";
		CardName[5] = "SixOfSpades.gif";
		CardName[6] = "SevenOfSpades.gif";
		CardName[7] = "EightOfSpades.gif";
		CardName[8] = "NineOfSpades.gif";
		CardName[9] = "TenOfSpades.gif";
		CardName[10] = "JackOfSpades.gif";
		CardName[11] = "QueenOfSpades.gif";
		CardName[12] = "KingOfSpades.gif";
		CardName[13] = "AceOfHearts.gif";
		CardName[14] = "TwoOfHearts.gif";
		CardName[15] = "ThreeOfHearts.gif";
		CardName[16] = "FourOfHearts.gif";
		CardName[17] = "FiveOfHearts.gif";
		CardName[18] = "SixOfHearts.gif";
		CardName[19] = "SevenOfHearts.gif";
		CardName[20] = "EightOfHearts.gif";
		CardName[21] = "NineOfHearts.gif";
		CardName[22] = "TenOfHearts.gif";
		CardName[23] = "JackOfHearts.gif";
		CardName[24] = "QueenOfHearts.gif";
		CardName[25] = "KingOfHearts.gif";
		CardName[26] = "AceOfClubs.gif";
		CardName[27] = "TwoOfClubs.gif";
		CardName[28] = "ThreeOfClubs.gif";
		CardName[29] = "FourOfClubs.gif";
		CardName[30] = "FiveOfClubs.gif";
		CardName[31] = "SixOfClubs.gif";
		CardName[32] = "SevenOfClubs.gif";
		CardName[33] = "EightOfClubs.gif";
		CardName[34] = "NineOfClubs.gif";
		CardName[35] = "TenOfClubs.gif";
		CardName[36] = "JackOfClubs.gif";
		CardName[37] = "QueenOfClubs.gif";
		CardName[38] = "KingOfClubs.gif";
		CardName[39] = "AceOfDiamonds.gif";
		CardName[40] = "TwoOfDiamonds.gif";
		CardName[41] = "ThreeOfDiamonds.gif";
		CardName[42] = "FourOfDiamonds.gif";
		CardName[43] = "FiveOfDiamonds.gif";
		CardName[44] = "SixOfDiamonds.gif";
		CardName[45] = "SevenOfDiamonds.gif";
		CardName[46] = "EightOfDiamonds.gif";
		CardName[47] = "NineOfDiamonds.gif";
		CardName[48] = "TenOfDiamonds.gif";
		CardName[49] = "JackOfDiamonds.gif";
		CardName[50] = "QueenOfDiamonds.gif";
		CardName[51] = "KingOfDiamonds.gif";
	}

	public void init() {
	
		earnings = new Integer(1000);
		youlose = false;
		Integer tempInt;
		setLayout(new BorderLayout());
		discardPanel.setBackground(backgroundColor);
		discardPanel.setLayout(new GridLayout(1,5));
		for (int i = 0; i < 5; i++) {
			tempInt = new Integer(i + 1);
			discardBox[i] = new Checkbox(tempInt.toString());
			discardPanel.add(discardBox[i]);
		}
		betChoice.addItem("Place a bet: (Default is $1)");
		betChoice.addItem("$1");
		betChoice.addItem("$5");
		betChoice.addItem("$10");
		betChoice.addItem("$20");
		betChoice.addItem("$50");
		betChoice.addItem("$100");
		betChoice.addItem("$150");
		betChoice.addItem("$200");
		betChoice.addItem("$250");
		betChoice.addItem("$500");
		betChoice.addItem("$750");
		betChoice.addItem("$1000");
		southPanel.setLayout(cl);
		northPanel.setLayout(c_l);
		blankPanel.setBackground(backgroundColor);
		southPanel.add("One", blankPanel);
		southPanel.add("Two", discardPanel);
		beforePanel.setBackground(backgroundColor);
		beforePanel.setLayout(new FlowLayout());
		dealPanel.setBackground(backgroundColor);
		dealPanel.setLayout(new FlowLayout());
		afterPanel.setBackground(backgroundColor);
		afterPanel.setLayout(new FlowLayout());
		earningsLabel1.setText("You have: $" + earnings.toString());
		earningsLabel2.setText("You have: $" + earnings.toString());
		earningsLabel3.setText("You have: $" + earnings.toString());
		beforePanel.add(earningsLabel1);
		beforePanel.add(dealButton);
		beforePanel.add(betChoice);
		dealPanel.add(earningsLabel2);
		dealPanel.add(discardButton);
		afterPanel.add(earningsLabel3);
		afterPanel.add(newHandButton);
		northPanel.add("One", beforePanel);
		northPanel.add("Two", dealPanel);
		northPanel.add("Three", afterPanel);
		add("North", northPanel);
		add("South", southPanel);
		beforeDeal();
	}

	public void paint (Graphics g) {
	
		g.setColor(backgroundColor);
		g.fillRect(0, 0, size().width - 1, size().height - 1);
		g.setColor(Color.black);
		for (int i = 0; i < 5; i++) {
			MediaTracker theTracker = new MediaTracker(this);
			Image theCardImage = getImage(getCodeBase(), "CardImages/" + NameValue[i]);
			theTracker.addImage(theCardImage,0);
			try {
				theTracker.waitForID(0);
			} catch (InterruptedException e) {}
			g.drawImage(theCardImage, (i * 125) + 10, 35, 71, 96, this);
		}
		if (afterPanel.isVisible()) {
			g.setFont(outputFont);
			if (youlose) {
				g.setColor(backgroundColor);
				g.fillRect(0, 0, size().width - 1, size().height - 1);
				Image theCardImage = getImage(getCodeBase(), "CardImages/AceOfSpades.gif");
				g.setColor(Color.black);
				g.drawImage(theCardImage, 260, 35, 71, 96, this);
				g.drawString("You Have Lost Everything. You Are Bankrupt.", 20, 100);
				newHandButton.setLabel("Play Again");
			} else if (royalflush) {
				g.drawString("Royal Flush", 185, 150);
			} else if (straightflush) {
				g.drawString("Straight Flush", 175, 150);
			}else if (fourofakind) {
				g.drawString("Four of a Kind", 175, 150);
			} else if (fullhouse) {
				g.drawString("Full House", 195, 150);
			} else if ((straight) | (royal)) {
				g.drawString("Straight", 210, 150);
			} else if (flush) {
				g.drawString("Flush", 230, 150);
			} else if (twopair) {
				g.drawString("Two Pair", 205, 150);
			} else if (threeofakind) {
				g.drawString("Three of a Kind", 145, 150);
			} else if (pair) {
				g.drawString("A Pair", 225, 150);
			} else {
				g.drawString("You Lose", 195, 150);
			}
		}
	}

	public void beforeDeal() {
	
		betValue = 0;
		flush = false;
		straight = false;
		royal = false;
		royalflush = false;
		straightflush = false;
		pair = false;
		twopair = false;
		threeofakind = false;
		fourofakind = false;
		fullhouse = false;
		earningsLabel1.setText(earningsLabel3.getText());
		cl.first(southPanel);
		c_l.first(northPanel);
		deckVector.removeAllElements();
		deckValueVector.removeAllElements();
		deckSuitVector.removeAllElements();
		for (int i = 0; i < 5; i++) {
			NameValue[i] = "AceOfSpades.gif";
		}
	}

	public void Deal() {
	
		String betString = betChoice.getSelectedItem();
		if (betString == "$10000") betValue = 10000;
		if (betString == "$9000") betValue = 9000;
		if (betString == "$8000") betValue = 8000;
		if (betString == "$7000") betValue = 7000;
		if (betString == "$6000") betValue = 6000;
		if (betString == "$5000") betValue = 5000;
		if (betString == "$4000") betValue = 4000;
		if (betString == "$3000") betValue = 3000;
		if (betString == "$2000") betValue = 2000;
		if (betString == "$1500") betValue = 1500;
		if (betString == "$1000") betValue = 1000;
		if (betString == "$750") betValue = 750;
		if (betString == "$500") betValue = 500;
		if (betString == "$250") betValue = 250;
		if (betString == "$200") betValue = 200;
		if (betString == "$150") betValue = 150;
		if (betString == "$100") betValue = 100;
		if (betString == "$50") betValue = 50;
		if (betString == "$20") betValue = 20;
		if (betString == "$10") betValue = 10;
		if (betString == "$5") betValue = 5;
		if ((betString == "$1") | (betString == "Place a bet: (Default is $1)")) betValue = 1;
		for (int i = 0; i < 5; i++) {
			discardBox[i].setState(false);
		}
		earnings = new Integer(earnings.intValue() - betValue); 
		earningsLabel2.setText("You Have: $" + earnings.toString());
		cl.last(southPanel);
		c_l.next(northPanel);
		createDeck();
		pickCard();
	}

	public void afterDiscard() {
	
		checkMatches(CardValue);
		checkForFlush(SuitValue);
		checkForStraights(CardValue);
		if ((straight) & (flush)) {
			straightflush = true;
		} else if ((royal) & (flush)) {
			royalflush = true;
		}
		if (royalflush) {
			earnings = new Integer(earnings.intValue() + (40 * betValue));
		} else if (straightflush) {
			earnings = new Integer(earnings.intValue() + (35 * betValue));
		}else if (fourofakind) {
			earnings = new Integer(earnings.intValue() + (25 * betValue));
		} else if (fullhouse) {
			earnings = new Integer(earnings.intValue() + (15 * betValue));
		} else if ((straight) | (royal)) {
			earnings = new Integer(earnings.intValue() + (10 * betValue));
		} else if (flush) {
			earnings = new Integer(earnings.intValue() + (5 * betValue));
		} else if (threeofakind) {
			earnings = new Integer(earnings.intValue() + (3 * betValue));
		} else if (twopair) {
			earnings = new Integer(earnings.intValue() + (2 * betValue));
		} else if (pair) {
			earnings = new Integer(earnings.intValue() + betValue);
		} else if (earnings.intValue() <= 0) {
			youlose = true;
			repaint();
		}
		betChoice = new Choice();
		if (earnings.intValue() >= 1) betChoice.addItem("$1");
		if (earnings.intValue() >= 5) betChoice.addItem("$5");
		if (earnings.intValue() >= 10) betChoice.addItem("$10");
		if (earnings.intValue() >= 20) betChoice.addItem("$20");
		if (earnings.intValue() >= 50) betChoice.addItem("$50");
		if (earnings.intValue() >= 100) betChoice.addItem("$100");
		if (earnings.intValue() >= 150) betChoice.addItem("$150");
		if (earnings.intValue() >= 200) betChoice.addItem("$200");
		if (earnings.intValue() >= 250) betChoice.addItem("$250");
		if (earnings.intValue() >= 500) betChoice.addItem("$500");
		if (earnings.intValue() >= 750) betChoice.addItem("$750");
		if (earnings.intValue() >= 1000) betChoice.addItem("$1000");
		if (earnings.intValue() >= 1500) betChoice.addItem("$1500");
		if (earnings.intValue() >= 2000) betChoice.addItem("$2000");
		if (earnings.intValue() >= 3000) betChoice.addItem("$3000");
		if (earnings.intValue() >= 4000) betChoice.addItem("$4000");
		if (earnings.intValue() >= 5000) betChoice.addItem("$5000");
		if (earnings.intValue() >= 6000) betChoice.addItem("$6000");
		if (earnings.intValue() >= 7000) betChoice.addItem("$7000");
		if (earnings.intValue() >= 8000) betChoice.addItem("$8000");
		if (earnings.intValue() >= 9000) betChoice.addItem("$9000");
		if (earnings.intValue() >= 10000) betChoice.addItem("$10000");
		beforePanel.removeAll();
		beforePanel.add(earningsLabel1);
		beforePanel.add(dealButton);
		beforePanel.add(betChoice);
		earningsLabel3.setText("You Have: $" + earnings.toString());
		cl.first(southPanel);
		c_l.last(northPanel);
	}

	public void createDeck() {
	
		int SuitValInt = 0;
		for (int i = 0; i < 52; i++) {
			SuitValInt = 0;
			deckVector.addElement(CardName[i]);
			Integer CardVal = new Integer(i);
			while (CardVal.intValue() > 12) {
				int CardValInt = CardVal.intValue();
				CardVal = new Integer(CardValInt - 13);
				SuitValInt = SuitValInt + 1;
			}
			Integer SuitVal = new Integer(SuitValInt);
			deckValueVector.addElement(CardVal);
			deckSuitVector.addElement(SuitVal);
		}
	}

	public int randCard(int arrayNum) {
	
		double randomCard = Math.random() * (52 - arrayNum);
		randomCard = Math.floor(randomCard);
		Double randomDouble = new Double(randomCard);
		return randomDouble.intValue();
	}

	public void pickCard() {
	
		for (int i = 0; i < 5; i++) {
			Integer randomCard = new Integer(randCard(i));
			NameValue[i] = deckVector.elementAt(randomCard.intValue()).toString();
			deckVector.removeElementAt(randomCard.intValue());
			CardValue[i] = (Integer)deckValueVector.elementAt(randomCard.intValue());
			deckValueVector.removeElementAt(randomCard.intValue());
			SuitValue[i] = (Integer)deckSuitVector.elementAt(randomCard.intValue());
			deckSuitVector.removeElementAt(randomCard.intValue());
		}
	}

	public void checkForFlush(Integer[] hand) {
	
		if (hand[0].equals(hand[1])) {
			if (hand[0].equals(hand[2])) {
				if (hand[0].equals(hand[3])) {
					if (hand[0].equals(hand[4])) {
						flush = true;
					} else {
						flush = false;
					}
				} else {
					flush = false;
				}
			} else {
				flush = false;
			}
		} else {
			flush = false;
		}
	}

	public void checkMatches(Integer[] hand) {
		if (hand[0].equals(hand[1])) {
			pair = true;
			if ((hand[2].equals(hand[3])) & !(hand[2].equals(hand[0]))) {
				twopair = true;
			}
			if ((hand[2].equals(hand[4])) & !(hand[2].equals(hand[0]))) {
				twopair = true;
			}
			if ((hand[3].equals(hand[4])) & !(hand[3].equals(hand[0]))) {
				twopair = true;
			}
			if ((hand[2].equals(hand[3])) & (hand[3].equals(hand[4]))) {
				fullhouse = true;
			}
			if (hand[1].equals(hand[2])) {
				threeofakind = true;
				if ((hand[3].equals(hand[4])) & !(hand[3].equals(hand[0]))) {
					fullhouse = true;
				}
				if (hand[2].equals(hand[3])) {
					fourofakind = true;
				} else if (hand[2].equals(hand[4])) {
					fourofakind = true;
				}
			} else if (hand[1].equals(hand[3])) {
				threeofakind = true;
				if ((hand[2].equals(hand[4])) & !(hand[2].equals(hand[0]))) {
					fullhouse = true;
				}
				if (hand[3].equals(hand[4])) {
					fourofakind = true;
				}
			} else if (hand[1].equals(hand[4])) {
				threeofakind = true;
				if ((hand[2].equals(hand[3])) & !(hand[2].equals(hand[0]))) {
					fullhouse = true;
				}
			}
		} else if (hand[0].equals(hand[2])) {
			pair = true;
			if ((hand[1].equals(hand[3])) & !(hand[1].equals(hand[0]))) {
				twopair = true;
			}
			if ((hand[1].equals(hand[4])) & !(hand[1].equals(hand[0]))) {
				twopair = true;
			}
			if ((hand[3].equals(hand[4])) & !(hand[3].equals(hand[0]))) {
				twopair = true;
			}
			if ((hand[1].equals(hand[3])) & (hand[3].equals(hand[4]))) {
				fullhouse = true;
			}
			if (hand[2].equals(hand[3])) {
				threeofakind = true;
				if ((hand[1].equals(hand[4])) & !(hand[1].equals(hand[0]))) {
					fullhouse = true;
				}
				if (hand[3].equals(hand[4])) {
					fourofakind = true;
				}
			} else if (hand[2].equals(hand[4])) {
				threeofakind = true;
				if ((hand[1].equals(hand[3])) & !(hand[1].equals(hand[0]))) {
					fullhouse = true;
				}
			}
		} else if (hand[0].equals(hand[3])) {
			pair = true;
			if ((hand[1].equals(hand[2])) & !(hand[1].equals(hand[0]))) {
				twopair = true;
			}
			if ((hand[1].equals(hand[4])) & !(hand[1].equals(hand[0]))) {
				twopair = true;
			}
			if ((hand[2].equals(hand[4])) & !(hand[2].equals(hand[0]))) {
				twopair = true;
			}
			if ((hand[1].equals(hand[2])) & (hand[2].equals(hand[4]))) {
				fullhouse = true;
			}
			if (hand[3].equals(hand[4])) {
				threeofakind = true;
				if ((hand[1].equals(hand[2])) & !(hand[1].equals(hand[0]))) {
					fullhouse = true;
				}
			}
		} else if (hand[0].equals(hand[4])) {
			pair = true;
			if ((hand[1].equals(hand[2])) & !(hand[1].equals(hand[0]))) {
				twopair = true;
			}
			if ((hand[1].equals(hand[3])) & !(hand[1].equals(hand[0]))) {
				twopair = true;
			}
			if ((hand[2].equals(hand[3])) & !(hand[2].equals(hand[0]))) {
				twopair = true;
			}
			if ((hand[1].equals(hand[2])) & (hand[2].equals(hand[3]))) {
				fullhouse = true;
			}
		} else if (hand[1].equals(hand[2])) {
			pair = true;
			if ((hand[3].equals(hand[4])) & !(hand[3].equals(hand[1]))) {
				twopair = true;
			}
			if (hand[2].equals(hand[3])) {
				threeofakind = true;
				if (hand[3].equals(hand[4])) {
					fourofakind = true;
				} 
			} else if (hand[2].equals(hand[4])) {
				threeofakind = true;
			}
		} else if (hand[1].equals(hand[3])) {
			pair = true;
			if ((hand[2].equals(hand[4])) & !(hand[2].equals(hand[1]))) {
				twopair = true;
			}
			if (hand[3].equals(hand[4])) {
				threeofakind = true;
			}
		} else if (hand[1].equals(hand[4])) {
			pair = true;
			if ((hand[2].equals(hand[3])) & !(hand[2].equals(hand[1]))) {
				twopair = true;
			}
		} else if (hand[2].equals(hand[3])) {
			pair = true;
			if (hand[3].equals(hand[4])) {
				threeofakind = true;
			}
		} else if (hand[2].equals(hand[4])) {
			pair = true;
		} else if (hand[3].equals(hand[4])) {
			pair = true;
		} else {
			pair = false;
			threeofakind = false;
			fourofakind = false;
			twopair = false;
			fullhouse = false;
		}
	}

	public void checkForStraights(Integer[] hand) {
	
		int localArray[] = new int[5];
		int temp;
	
		for (int i = 0; i < 5; i++)
			localArray[i] = hand[i].intValue();
		
		for ( int j = 0; j < 5; j++) {
			for (int k = 0; k < 5; k++) {
				if (localArray[j] < localArray[k]) {
					temp = localArray[j];
					localArray[j] = localArray[k];
					localArray[k] = temp;
				}
			}
		}
		
		if (localArray[1] == localArray[2] - 1) {
			if (localArray[2] == localArray[3] - 1) {
				if (localArray[3] == localArray[4] - 1) {
					if (localArray[0] == localArray[1] - 1)
						straight = true;
					if (localArray[0] == localArray[1] - 9)
						royal = true;
				}
			}
		}
	}
	

	public boolean action(Event evt, Object arg) {
	
		if (Boolean.TRUE.equals(arg)) {
			discardNumber = discardNumber + 1;
		}
		if (Boolean.FALSE.equals(arg)) {
			discardNumber = discardNumber - 1;
		}
		if ("Discard".equals(arg)) {
			if (discardNumber > 3) {
				dFrame = ComponentUtil.getFrame(this);
				dDialog = new DiscardDialog(dFrame, "         You cannot discard more than three cards.");
				dDialog.reshape(100, 100, 400, 100);
				dDialog.show();
			} else {
				for (int i = 0; i < 5; i++) {
					if (discardBox[i].getState() == true) {
						Integer randomCard = new Integer(randCard(5 + i));
						NameValue[i] = deckVector.elementAt(randomCard.intValue()).toString();
						deckVector.removeElementAt(randomCard.intValue());
						CardValue[i] =(Integer)deckValueVector.elementAt(randomCard.intValue());
						deckValueVector.removeElementAt(randomCard.intValue());
						SuitValue[i] = (Integer)deckSuitVector.elementAt(randomCard.intValue());
						deckSuitVector.removeElementAt(randomCard.intValue());
						discardBox[i].setState(false);
						discardNumber = 0;
					}
				}
				afterDiscard();
				repaint();
			}
		}
		if ("Deal".equals(arg)) {
			Deal();
			repaint();
		}
		if ("New Hand".equals(arg)) {
			beforeDeal();
			repaint();
		}
		if ("Play Again".equals(arg)) {
			newHandButton.setLabel("New Hand");
			southPanel = new Panel();
			northPanel = new Panel();
			beforePanel = new Panel();
			dealPanel = new Panel();
			afterPanel = new Panel();
			discardPanel = new Panel();
			blankPanel = new Panel();
			cl = new CardLayout();
			c_l = new CardLayout();
			betChoice = new Choice();
			init();
		}
		return true;
	}
}
				
class DiscardDialog extends Dialog {

	Color backgroundColor = new Color(0, 135, 30);

	public DiscardDialog(Frame parent, String message) {
		super(parent, "Sorry, Pal...", true);
		setBackground(backgroundColor);
		add("Center", new Label(message));
		Panel thePanel = new Panel();
		thePanel.add(new Button("OK"));
		add("South", thePanel);
	}

	public boolean action(Event evt, Object arg) {
		if ("OK".equals(arg)) {
			dispose();
		}
		return true;
	}
}

class ComponentUtil {
	public static Frame getFrame(Component theComponent) {
		Component currParent = theComponent;
		Frame theFrame = null;
		while (currParent != null) {
			if (currParent instanceof Frame) {
				theFrame = (Frame)currParent;
				break;
			}
			currParent = currParent.getParent();
		}
		return theFrame;
	}
}
