import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.util.*;
import java.text.*;
 
public class Poker extends Applet implements MouseListener
{
	// Screen constants	
	static final int HOLDW = 50;
	static final int HOLDH = 20;
	static final int HOLDY = 150;
	static final int TinyOFFSET = 5; 
	static final int SmOFFSET = 10; 
	static final int MedOFFSET = 15;
	static final int LgOFFSET = 20; 
	static final int COINSIZE = 30; 
	static final int CARDOFFSET = 140; 
	static final int CARDWIDTH = 60; 
	static final int CARDHEIGHT = 100; 
	
	// the cards
	boolean Hold[] = new boolean[5]; 
	boolean Deck[] = new boolean[52]; 
	boolean FirstTime = true;

	Card Hand[] = new Card[5];

	// the money
	NumberFormat Dollar = NumberFormat.getCurrencyInstance();	
	float Money[] = new float[3];
	static final String Boxes[]={"Bank", "Bet", "Paid"};
	
	static final String Desc[]={"Jacks or Better",
					    "Two Pair",
					    "Three of a Kind",
					    "Straight",
					    "Flush",
				          "Full House",
					    "Four of a Kind",
				          "Straight Flush",
					    "Royal Flush"};
	static final String Odds[]={"  1:1",
					    "  2:1",
					    "  3:1",
					    "  4:1",
					    "  5:1",
				          "  8:1",
					    " 25:1",
				          " 50:1",
					    "250:1"};
	Random rand = new Random();
	
	// Set up clicking areas
	Rectangle Hold1 = new Rectangle(150, HOLDY, HOLDW, HOLDH); 
	Rectangle Hold2 = new Rectangle(225, HOLDY, HOLDW, HOLDH); 
	Rectangle Hold3 = new Rectangle(300, HOLDY, HOLDW, HOLDH); 
	Rectangle Hold4 = new Rectangle(375, HOLDY, HOLDW, HOLDH); 
	Rectangle Hold5 = new Rectangle(450, HOLDY, HOLDW, HOLDH); 
	Rectangle Deal = new Rectangle(260, 210, 220, 30);
	Rectangle Coin1 = new Rectangle(435, 200, COINSIZE, COINSIZE);
	Rectangle Coin5 = new Rectangle(475, 200, COINSIZE, COINSIZE);
	Rectangle Coin10 = new Rectangle(435, 240, COINSIZE, COINSIZE);
	Rectangle Coin25 = new Rectangle(475, 240, COINSIZE, COINSIZE);

      Font smallFont = new Font("SansSerif", Font.BOLD, 12);
      Font RegFont = new Font("SansSerif", Font.BOLD, 16);

    public void init() 
    {
	 setBackground(Color.white);
	 addMouseListener(this);
	 Money[0] = 100;
    }

   public void update(Graphics g)
   {
	paint(g);
   }
	
   public void paint(Graphics g)
   {
	g.setFont(smallFont);

	// Add Hold buttons
	int TempX = 150;
	for (int x = 0; x < 5; x++)
	{
         g.setColor(Color.lightGray);
	   g.fill3DRect(TempX, HOLDY, HOLDW, HOLDH, true);
	   g.setColor(Color.black);
	   g.drawRect(TempX - 2, HOLDY - 2, HOLDW, HOLDH);
	   g.drawString("HOLD", TempX + SmOFFSET, HOLDY + MedOFFSET); 
	   TempX += 75;
	}

	// Add a Deal button
	g.setFont(RegFont);
	g.setColor(Color.lightGray);
	g.fill3DRect(260, 210, 80, 30, true);
	g.setColor(Color.black);
	g.drawRect(260 - 2, 210 - 2, 80, 30);
	g.drawString("DEAL", 260 + MedOFFSET, 210 + LgOFFSET); 

	// Add the odds
	g.setColor(Color.red);
	int OddsW = 130;
	int OddsH = 150;
	int OddsY = 170;
	g.fillRect(TinyOFFSET, OddsY, OddsW, OddsH);
	g.setColor(Color.black);
	g.drawString("Pay Offs", 30, 165);
	g.fillRect(TinyOFFSET, OddsY, OddsW, 3);
	g.fillRect(TinyOFFSET, OddsY, 3, OddsH);
	g.fillRect(TinyOFFSET + OddsW, OddsY, 3, OddsH);
	g.fillRect(TinyOFFSET, OddsY + OddsH, OddsW + 3, 3);
	g.setFont(smallFont);
	int TempY = 190;
	for(int i = 0; i < 9; i++)
	{
	   g.setColor(Color.black);
	   g.drawString(Desc[i], 13, TempY);
	   g.drawString(Odds[i], 103, TempY);
	   g.setColor(Color.white);
	   g.drawString(Desc[i], 13 + 1, TempY + 1);
	   g.drawString(Odds[i], 103 + 1, TempY + 1);
	   TempY += 15;
	}
	
	// Add Money boxes
	PaintMoneyBoxes(g);

	// Add coin selectors
	TempX = 435;
	TempY = 200;
	int HalfCoin = COINSIZE / 2;
	for (int k = 0; k < 4; k++)
	{
	   g.setColor(Color.black);
	   g.fillOval(TempX -1, TempY - 1, COINSIZE + 2, COINSIZE + 2);
	   String Dollar = null; 	 
	   if (k == 0) 
	   {
		Dollar = "$1";
	    	g.setColor(Color.cyan);
	   } 
	   if (k == 1) 
	   {
		Dollar = "$5"; 
		g.setColor(Color.magenta);	
	   }
	   if (k == 2) 
	   {
		Dollar = "$10";
	    	g.setColor(Color.yellow);
	   } 
	   if (k == 3) 
	   {
		Dollar = "$25"; 
		g.setColor(Color.pink);	
	   }
	
	   g.fillOval(TempX, TempY , COINSIZE, COINSIZE);
	   g.setColor(Color.white);
	   g.fillRect(TempX, TempY  + 13, SmOFFSET, TinyOFFSET);
	   g.fillRect(TempX + LgOFFSET, TempY+13, SmOFFSET, TinyOFFSET);
	   g.fillRect(TempX + 13, TempY , TinyOFFSET, SmOFFSET);
	   g.fillRect(TempX + 13, TempY+LgOFFSET, TinyOFFSET, SmOFFSET);
	   g.setColor(Color.black);
	   g.drawLine(TempX, TempY + HalfCoin, TempX+7, TempY + HalfCoin);
	   g.drawLine(TempX+23, TempY+HalfCoin, TempX+COINSIZE, TempY+ HalfCoin);
	   g.drawLine(TempX +HalfCoin, TempY, TempX +HalfCoin, TempY+ 7);
	   g.drawLine(TempX +HalfCoin, TempY + 23, TempX +HalfCoin, TempY + COINSIZE);
	   g.drawOval(TempX, TempY, COINSIZE, COINSIZE);
         g.setFont(smallFont);
         g.drawString(Dollar, TempX + 7, TempY + LgOFFSET); 
	   TempX += 40;
	   if(k==1)
	   {
	      TempY += 40;
		TempX = 435;
	   }
	}
	PaintCards();
   }

   private void PaintMoneyBoxes(Graphics g)
   {
	g.setFont(RegFont);
	int TempX = 160;
	int w = 85;
	int h = 30;
	int p = 3;
	int y = 290;
      g.clearRect(TempX, y - 15, 300, 15);
	for (int x = 0; x < 3; x++)
	{
         g.setColor(Color.lightGray);
	   g.fillRect(TempX, y, w, h);
	   g.setColor(Color.black);
	   g.drawString(Boxes[x], TempX + 10, y - 2);
	   g.fillRect(TempX, y, w, p);
	   g.fillRect(TempX, y, p, h);
	   g.fillRect(TempX + w, y, p, h);
	   g.fillRect(TempX, y + h, w + p, p);
	   g.drawString(Dollar.format(Money[x]), TempX + 10, y + 25); 
	   TempX += 95;
	}
   }	

   private void PaintCards()
   {
	Graphics g = getGraphics();
	g.setFont(RegFont);
	int TempX = CARDOFFSET;
	int TempY = 25;
	g.clearRect(TempX, 0, 400, HOLDY - 2);
	for(int i = 0; i < 5; i++)
	{
	   g.drawImage(Hand[i].pic, TempX, TempY, this); 
	   if((Hold[i] == true)&&(!FirstTime))
	   {
		g.setColor(Color.red);
	      g.drawString("HOLD", TempX + 10, TempY + 110); 
		g.setColor(Color.black);
	   }			
   	   TempX += CARDWIDTH + 15;
	}
	
   }	

   private void DealHand()
   {
	int cards;
	for(int i = 0; i < 5; i++)
	{
	   if(Hold[i]== false)
	   {
	      while(true)
	      {
		   cards = (int)(Math.random() * 52);
		   if(Deck[cards] == false)
		      break;
	      }
	      Hand[i] = new Card(cards);
	      Deck[cards] = true;
	   }
	} 
	repaint();	
   }

   private void CalculateResults()
   {
	int Temp;
	//Sort Hand
	for(int i = 0; i < 4; i++)
	{
	   for(int x = 1; x < 5 - i; x++)
	   {
	      if(Hand[x].Value > Hand[x-1].Value)
	      {
		   Temp = Hand[x-1].Value;
		   Hand[x-1].Value = Hand[x].Value;
		   Hand[x].Value = Temp; 	  	  
	      }	
	   }
	}
	while(true)
	{
	   // Check for royal flush
	   if((Hand[0].Value == 1) && (Hand[4].Value == 13) && (Hand[3].Value == 12) &&
		 (Hand[2].Value == 11) && (Hand[1].Value == 10)) 
	   {
		if((Hand[0].Suit == Hand[1].Suit) && (Hand[0].Suit == Hand[2].Suit)&& (Hand[0].Suit == Hand[3].Suit)&& (Hand[0].Suit == Hand[4].Suit))
	   	{
		   Money[2] = Money[1] * 250;
		   Money[0] += Money[2];
	         break;
		}
	   }	 				
	
	   // Check for straight flush
         if((Hand[4].Value - Hand[3].Value == 1) && (Hand[3].Value - Hand[2].Value == 1) && 
		(Hand[2].Value - Hand[1].Value == 1) && (Hand[1].Value - Hand[0].Value == 1))
	   {
		if((Hand[0].Suit == Hand[1].Suit) && (Hand[0].Suit == Hand[2].Suit)&& (Hand[0].Suit == Hand[3].Suit)&& (Hand[0].Suit == Hand[4].Suit))
	      {
	         Money[2] = Money[1] * 50;
		   Money[0] += Money[2];
	 	   break;
		}
	   }
	
	   // Check for straight
         if(((Hand[0].Value == 1) && (Hand[4].Value == 13) && (Hand[3].Value == 12) &&
		 (Hand[2].Value == 11) && (Hand[1].Value == 10)) || ((Hand[4].Value - Hand[3].Value	== 1) &&
	       (Hand[3].Value - Hand[2].Value == 1) && (Hand[2].Value - Hand[1].Value == 1) && 
		 (Hand[1].Value - Hand[0].Value == 1)))
	   {
		Money[2] = Money[1] * 4;
		Money[0] += Money[2];
		break;
	   }	 				
 		
	   // Check for flush
	   if((Hand[0].Suit == Hand[1].Suit) && (Hand[0].Suit == Hand[2].Suit)&& (Hand[0].Suit == Hand[3].Suit)&& (Hand[0].Suit == Hand[4].Suit))
	   {
		Money[2] = Money[1] * 5;
		Money[0] += Money[2];
		break;
	   }
	   // Check for 4 of a kind
	   if((Hand[0].Value == Hand[1].Value) && (Hand[0].Value == Hand[2].Value)&& (Hand[0].Value == Hand[3].Value) ||
		(Hand[1].Value == Hand[2].Value) && (Hand[1].Value == Hand[3].Value)&& (Hand[1].Value == Hand[4].Value))
	   {
            Money[2] = Money[1] * 25;
		Money[0] += Money[2];
		break;
	   }
	   // Check for full house
	   if(((Hand[0].Value == Hand[1].Value) && (Hand[0].Value == Hand[2].Value) && 
		(Hand[3].Value == Hand[4].Value)) || ((Hand[2].Value == Hand[3].Value) && 
		(Hand[2].Value == Hand[4].Value) && (Hand[0].Value == Hand[1].Value)))
	   {
		Money[2] = Money[1] * 8;
	      Money[0] += Money[2];
	      break;
	   }

	   // Check for 2 pair
	   if(Hand[0].Value == Hand[1].Value)
	   {
		if((Hand[2].Value == Hand[3].Value) ||(Hand[3].Value == Hand[4].Value))
	   	{
		   Money[2] = Money[1] * 2;
	         Money[0] += Money[2];
		   break;
	      }
	   }
	   if((Hand[1].Value == Hand[2].Value)&& (Hand[3].Value == Hand[4].Value))
	   {
	      Money[2] = Money[1] * 2;
	      Money[0] += Money[2];
	      break;
	   }
 		
	   // Check for 3 of a kind
	   if(((Hand[0].Value == Hand[1].Value) && (Hand[0].Value == Hand[2].Value)) || 
	      ((Hand[1].Value == Hand[2].Value) && (Hand[1].Value == Hand[3].Value)) ||
		((Hand[2].Value == Hand[3].Value) && (Hand[2].Value == Hand[4].Value)))
	   {
		   Money[2] = Money[1] * 3;
	         Money[0] += Money[2];
		   break;
	   }

	   // Check for pair - jacks or better
	   if(((Hand[0].Value == Hand[1].Value) && ((Hand[0].Value == 1) || (Hand[0].Value > 10))) || 
	      ((Hand[1].Value == Hand[2].Value) && ((Hand[1].Value == 1) || (Hand[1].Value > 10))) ||
		((Hand[2].Value == Hand[3].Value) && ((Hand[2].Value == 1) || (Hand[2].Value > 10))) ||
		((Hand[3].Value == Hand[4].Value) && ((Hand[3].Value == 1) || (Hand[3].Value > 10))))
	   {
		   Money[2] = Money[1];
	         Money[0] += Money[2];
		   break;
 	   }
	   break;	
	}
	// Reset the bet and the deck
	Money[1] = 0;
	for(int i = 0; i < 52; i++)
	   Deck[i] = false;
   }

// The user has clicked the applet. Figure out where and what they
// want.
   public void mouseReleased(MouseEvent e)
   {	
	int MEx = e.getX();
	int MEy = e.getY();
	Graphics g = getGraphics();

	// User pressed one of the hold buttons
	if((Deal.contains(MEx, MEy)) && (Money[1] > 0))
	{
	   if(FirstTime)
	   {
	      FirstTime = false;
		Money[2] = 0;
		for(int i = 0; i < 5; i++)
		   Hold[i] = false;
		// Select and display five random cards
	      DealHand();
	   }	
	   else
	   {
		FirstTime = true;
	      DealHand();
		CalculateResults();	
	   }
	}

	// User pressed one of the hold buttons
	if(Hold1.contains(MEx, MEy))
	{
	   if(Hold[0] == true)
	      Hold[0] = false;
	   else
		Hold[0] = true;
	   PaintCards();	
	}	

	if(Hold2.contains(MEx, MEy))
	{
	   if(Hold[1] == true)
	      Hold[1] = false;
	   else
		Hold[1] = true;
	   PaintCards();	
	}	
	if(Hold3.contains(MEx, MEy))
		{
	   if(Hold[2] == true)
	      Hold[2] = false;
	   else
		Hold[2] = true;
	   PaintCards();	
	}	

	if(Hold4.contains(MEx, MEy))
	{
	   if(Hold[3] == true)
	      Hold[3] = false;
	   else
		Hold[3] = true;
	   PaintCards();	
	}	

	if(Hold5.contains(MEx, MEy))
	{
	   if(Hold[4] == true)
	      Hold[4] = false;
	   else
		Hold[4] = true;
	   PaintCards();	
	}	

	// User pressed one of the coin selectors
	if((Coin1.contains(MEx, MEy))&&(Money[0] > 0))
	{
	   Money[1] += 1;
	   Money[0] -= 1;
	   PaintMoneyBoxes(g);
	}

	if((Coin5.contains(MEx, MEy))&&(Money[0] > 4))
	{
   	   Money[1] += 5;
	   Money[0] -= 5;
	   PaintMoneyBoxes(g);
	}

	if((Coin10.contains(MEx, MEy))&&(Money[0] > 9))
	{
   	   Money[1] += 10;
	   Money[0] -= 10;
	   PaintMoneyBoxes(g);
	}

	if((Coin25.contains(MEx, MEy))&&(Money[0] > 24))
	{
   	   Money[1] += 25;
	   Money[0] -= 25;
	   PaintMoneyBoxes(g);
	}
   }

   public void mousePressed(MouseEvent e) {}

   public void mouseClicked(MouseEvent e) {}

   public void mouseEntered(MouseEvent e) {}

   public void mouseExited(MouseEvent e) {}

   public void destroy()
   {
      removeMouseListener(this);
   }
   
   public String getAppletInfo() 
   {
	return "Video Poker by Jay Lipp";
   }

   class Card
   {
      // 0=Clubs, 1=Diamonds, 2=Hearts, 3=Spades
	// 11=Jack, 12=Queen, 13=King 1=Ace

	public int Value;
	public int Suit;
	public String Name;
	public Image pic; 
	private String theSuit;

	public Card(int x)
	{
	   Suit = x % 4;
	   if(Suit == 0)	
	   	theSuit = "C";
	   else if(Suit == 1)	
	   	theSuit = "D";
	   else if(Suit == 2)	
	   	theSuit = "H";
	   else
	   	theSuit = "S";
	   Value = x % 13;
 	   if(Value == 0)
		Value = 13;
 	   Name = String.valueOf(Value) + theSuit;
	   pic = getImage(getCodeBase(),"Images/" + Name + ".gif"); 	
	}
   } 		
}
