import java.awt.*;
import java.awt.event.*;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Color;

public class Craps extends java.applet.Applet implements Runnable {
	// constant variables for status of game
	final int WON = 0, LOST = 1, CONTINUE = 2;  

	// other variables used in program
	boolean firstRoll = true;   // true if first roll
	int sumOfDice = 0;          // sum of the dice
	int myPoint = 0;   // point if no win/loss on first roll
	int gameStatus = CONTINUE;  // game not over yet
	int bankBalance = 1000; // gamblers' balance
	int betAmount = 100;  // amount to be changed by gambler
	int randomStatusNumber; 

	Image diceRollPics[] = new Image[3];
	Image diceLandPics[] = new Image[6];
	Image moodModePics[] = new Image[5];
	Image currentImg, currentImg2, modeImg, moodImg;
	Thread runner;
	int rollValue, stopValue, rollValue2, stopValue2;
	boolean diceRolling = false;

	String thisPlayer = null;

	// visual components
	Label die1Label, die2Label, sumLabel, pointLabel, bankLabel, betLabel,
		x1Label, x2Label;
	TextField nameText, firstDie, secondDie, sum, point, bank, bet;
	Button roll, reset, incrBank;
	ThisChatter tc;

	void buildGridBagConstraints(GridBagConstraints gbc, int gx, int gy,
		int gw, int gh, int wx, int wy) {

		gbc.gridx = gx;
		gbc.gridy = gy;
		gbc.gridwidth = gw;
		gbc.gridheight = gh;
		gbc.weightx = wx;
		gbc.weighty = wy;
	}


	// setup graphical user interface components
	public void init() 
	{

		// Assign pictures to arrays
		String diceRollSrc[] = { "rolling1.gif", "rolling2.gif",
			"rolling3.gif"};

		String diceLandSrc[] = { "one.gif", "two.gif",
			"three.gif","four.gif", "five.gif",
			"six.gif" };

		String moodModeSrc[] = { "blank.gif", "win.gif", "lose.gif",
			"smile.gif", "frown.gif" };

		for (int i=0; i < diceRollPics.length; i++) {
			diceRollPics[i] = getImage(getCodeBase(),
				"images/" + diceRollSrc[i]);
		}

		for (int i=0; i < diceLandPics.length; i++) {
			diceLandPics[i] = getImage(getCodeBase(),
			"images/" + diceLandSrc[i]);
		}

		for (int i=0; i < moodModePics.length; i++) {
			moodModePics[i] = getImage(getCodeBase(),
			"images/" + moodModeSrc[i]);
		}

		currentImg = diceLandPics[0];
		currentImg2 = diceLandPics[0];

		modeImg = moodModePics[0];
		moodImg = moodModePics[0];

		String nameTemp = getParameter ( "thisname" );
		if (nameTemp.length() > 2 ) thisPlayer = nameTemp;

		//Assign components to layout manager
		//setLayout(layout);

		GridBagLayout gridbag = new GridBagLayout();
		GridBagConstraints constraints = new GridBagConstraints();
		setLayout(gridbag);



		buildGridBagConstraints(constraints, 0, 0, 4, 1, 100, 20);
		constraints.fill = GridBagConstraints.HORIZONTAL;
		constraints.anchor = GridBagConstraints.WEST;
		ThisChatter myChatter = ( thisPlayer == null ? new ThisChatter() :
			new ThisChatter( thisPlayer ));
		gridbag.setConstraints( myChatter, constraints);
		add( myChatter );

		buildGridBagConstraints(constraints, 0, 1, 4, 1, 0, 20);
		constraints.fill = GridBagConstraints.NONE;
		constraints.anchor = GridBagConstraints.EAST;
		Canvas can = new Canvas();
		gridbag.setConstraints( can, constraints);
		add( can );

		buildGridBagConstraints(constraints, 0, 2, 1, 1, 25, 10);
		constraints.fill = GridBagConstraints.NONE;
		constraints.anchor = GridBagConstraints.EAST;
		die1Label = new Label( "Die 1" );
		gridbag.setConstraints( die1Label, constraints);
		add( die1Label );

		buildGridBagConstraints(constraints, 1, 2, 1, 1, 25, 0);
		constraints.fill = GridBagConstraints.NONE;
		constraints.anchor = GridBagConstraints.WEST;
		firstDie = new TextField( 10 );
		gridbag.setConstraints( firstDie, constraints);
		firstDie.setEditable( false );
		add( firstDie );

		buildGridBagConstraints(constraints, 2, 2, 1, 1, 25, 0);
		constraints.fill = GridBagConstraints.NONE;
		constraints.anchor = GridBagConstraints.EAST;
		die2Label = new Label( "Die 2" );
		gridbag.setConstraints( die2Label, constraints);
		add( die2Label );

		buildGridBagConstraints(constraints, 3, 2, 1, 1, 25, 0);
		constraints.fill = GridBagConstraints.NONE;
		constraints.anchor = GridBagConstraints.WEST;
		secondDie = new TextField( 10 );
		gridbag.setConstraints( secondDie, constraints);
		secondDie.setEditable( false );
		add( secondDie );

		buildGridBagConstraints(constraints, 0, 3, 1, 1, 0, 10);
		constraints.fill = GridBagConstraints.NONE;
		constraints.anchor = GridBagConstraints.EAST;
		sumLabel = new Label( "Sum is" );
		gridbag.setConstraints( sumLabel, constraints);
		add( sumLabel );

		buildGridBagConstraints(constraints, 1, 3, 1, 1, 0, 0);
		constraints.fill = GridBagConstraints.NONE;
		constraints.anchor = GridBagConstraints.WEST;
		sum = new TextField( 10 );
		gridbag.setConstraints( sum, constraints);
		sum.setEditable( false );
		add( sum );

		buildGridBagConstraints(constraints, 2, 3, 1, 1, 0, 0);
		constraints.fill = GridBagConstraints.NONE;
		constraints.anchor = GridBagConstraints.EAST;
		pointLabel = new Label( "Point is" );
		gridbag.setConstraints( pointLabel, constraints);
		add( pointLabel );

		buildGridBagConstraints(constraints, 3, 3, 1, 1, 0, 0);
		constraints.fill = GridBagConstraints.NONE;
		constraints.anchor = GridBagConstraints.WEST;
		point = new TextField( 10 );
		gridbag.setConstraints( point, constraints);
		point.setEditable( false );
		add( point );

		buildGridBagConstraints(constraints, 0, 4, 1, 1, 0, 10);
		constraints.fill = GridBagConstraints.NONE;
		constraints.anchor = GridBagConstraints.EAST;
		betLabel = new Label( "Bet:" );
		gridbag.setConstraints( betLabel, constraints);
		add( betLabel );

		buildGridBagConstraints(constraints, 1, 4, 1, 1, 0, 0);
		constraints.fill = GridBagConstraints.NONE;
		constraints.anchor = GridBagConstraints.WEST;
		bet = new TextField( 10 );
		gridbag.setConstraints( bet, constraints);
		bet.setEditable( true );
		add( bet );
		bet.setText( Integer.toString( betAmount ) );
		bet.selectAll();
		bet.requestFocus();

		buildGridBagConstraints(constraints, 2, 4, 1, 1, 0, 0);
		constraints.fill = GridBagConstraints.NONE;
		constraints.anchor = GridBagConstraints.EAST;
		bankLabel = new Label( "Bank:" );
		gridbag.setConstraints( bankLabel, constraints);
		add( bankLabel );

		buildGridBagConstraints(constraints, 3, 4, 1, 1, 0, 0);
		constraints.fill = GridBagConstraints.NONE;
		constraints.anchor = GridBagConstraints.WEST;
		bank = new TextField( 10 );
		gridbag.setConstraints( bank, constraints);
		bank.setEditable( false );
		add( bank );
		bank.setText( Integer.toString( bankBalance ) );

		buildGridBagConstraints(constraints, 0, 5, 1, 1, 0, 10);
		constraints.fill = GridBagConstraints.NONE;
		constraints.anchor = GridBagConstraints.CENTER;
		reset = new Button( "Reset Game" );
		gridbag.setConstraints( reset, constraints);
		add( reset );
		reset.addActionListener( new java.awt.event.ActionListener() { 
                public void actionPerformed( java.awt.event.ActionEvent e) { 
                                        resetGame();
                                }
                        });
		

		buildGridBagConstraints(constraints, 1, 5, 2, 1, 0, 10);
		constraints.fill = GridBagConstraints.NONE;
		constraints.anchor = GridBagConstraints.CENTER;
		roll = new Button( "Roll Dice" );
		gridbag.setConstraints( roll, constraints);
		add( roll );
		roll.addActionListener( new java.awt.event.ActionListener() { 
                public void actionPerformed( java.awt.event.ActionEvent e) { 
                                        diceRolling = true;
                                }
                        });
		

		buildGridBagConstraints(constraints, 3, 5, 1, 1, 0, 10);
		constraints.fill = GridBagConstraints.NONE;
		constraints.anchor = GridBagConstraints.CENTER;
		incrBank = new Button( "Add 1000" );
		gridbag.setConstraints( incrBank, constraints);
		add( incrBank );
		incrBank.addActionListener( new java.awt.event.ActionListener() { 
                public void actionPerformed( java.awt.event.ActionEvent e) { 
                                        add1000();
                                }
                        });
		

		buildGridBagConstraints(constraints, 0, 6, 4, 1, 0, 20);
		constraints.fill = GridBagConstraints.NONE;
		constraints.anchor = GridBagConstraints.EAST;
		Canvas can2 = new Canvas();
		gridbag.setConstraints( can2, constraints);
		add( can2 );


/*
		buildGridBagConstraints(constraints, 0, 6, 4, 1, 0, 20);
		constraints.fill = GridBagConstraints.NONE;
		constraints.anchor = GridBagConstraints.CENTER;
		//ThisBank myBank = new ThisBank();
		gridbag.setConstraints( myBank, constraints);
		add( myBank );
*/   
		}

	public void start() 
	{
		if (runner == null) {
			runner = new Thread(this);
			runner.start();
		}
	}

	public void stop() 
	{
		runner = null;
	}

	public void run() 
	{
		setBackground(Color.white);
		while (runner != null)
		{
			if (diceRolling)
			{
				play();  //one play of the game //roll the dice
				diceRolling = false;
			}
			pause(0);  // Let other applets have a chance to run.
		}

	}

	void pause(int time) 
	{
		try {
			Thread.sleep(time);
		} catch (InterruptedException e) { }
	}


	// process one roll of the dice
	public void play()
	{

		modeImg = moodModePics[0];
		moodImg = moodModePics[0];

		betAmount =  Integer.parseInt( bet.getText() );
		bankBalance =  Integer.parseInt( bank.getText() );

		if  (bankBalance - betAmount <= 0) {
			betAmount = bankBalance;
			bet.setText( Integer.toString( betAmount ) );
		}

		if ( firstRoll ) {             // first roll of the dice
			sumOfDice = rollDice();        
   
			switch ( sumOfDice ) {
				case 7: case 11:         // win on first roll
					gameStatus = WON;
					point.setText( "" );  // clear point text field
					bet.selectAll();  // Can now change bet.
					bet.setEditable(true);
					bet.requestFocus();  //keyboard ready
					break;
				case 2: case 3: case 12: // lose on first roll
					gameStatus = LOST;
					point.setText( "" );  // clear point text field
					bet.selectAll();  // Can now change bet.
					bet.setEditable(true);
					bet.requestFocus();  //keyboard ready
					break;
				default:                 // remember point
					gameStatus = CONTINUE;
					myPoint = sumOfDice;
					point.setText( Integer.toString( myPoint ) );
					bet.select(0,0);  // deselect bet amount.
					bet.setEditable(false);  //not allowed to change bet.
					firstRoll = false;
					break;
			}
		}
		else {
			sumOfDice = rollDice();
      
			if ( sumOfDice == myPoint ){    // win by making point
				gameStatus = WON; 
				bet.selectAll();  // Can now change bet.
				bet.setEditable(true);
				bet.requestFocus();  //keyboard ready
			}
			else {
				if ( sumOfDice == 7 ){       // lose by rolling 7
					gameStatus = LOST;
					bet.selectAll();  // Can now change bet.
					bet.setEditable(true);
					bet.requestFocus();  //keyboard ready
				}
			}
		}

		if ( gameStatus == CONTINUE ){
			randomStatusNumber = 1 + ( int ) ( Math.random() * 3 );
			
			switch ( randomStatusNumber ) {
				case 1:  
					showStatus( "Roll again." );
					break;
				case 2:
					showStatus( "Come On " + myPoint + "!");
					break;
				case 3:
					showStatus( "Don't let those dice cool down!");
					break;

			} 
		}
		else {
			if ( gameStatus == WON ){
				randomStatusNumber = 1 + ( int ) ( Math.random() * 3 );
				switch ( randomStatusNumber ) {
					case 1:  
						showStatus( "YOU WIN! " +
							"Place your bet and play again!" );
						modeImg = moodModePics[1];
						moodImg = moodModePics[3];
						repaint();
						break;
					case 2:
						showStatus( "YOU WIN! " +
							"Thats great, do that again!" );
						modeImg = moodModePics[1];
						moodImg = moodModePics[3];
						repaint();
						break;
					case 3:
						showStatus( "YOU WIN! " +
							"Where are we going for lunch?" );
						modeImg = moodModePics[1];
						moodImg = moodModePics[3];
						repaint();
						break;
				}

				bank.setText( Integer.toString( bankBalance + betAmount ) );
			} 
			else { 
			showStatus( "Ahhhh, YOU LOSE. " + 
					"Play again?" );
				bank.setText( Integer.toString( bankBalance - betAmount ) );
				modeImg = moodModePics[2];
				moodImg = moodModePics[4];
				repaint();
			}
         
		firstRoll = true;
		}
	}
   
	// roll the dice
	public int rollDice()
	{
		int die1, die2, workSum; 

		for (int i = 6; i > 0; i--) {
			rollValue = (int) ( Math.random() * 3);
			currentImg = diceRollPics[rollValue];
			rollValue2 = (int) ( Math.random() * 3);
			currentImg2 = diceRollPics[rollValue2];
			repaint();
			pause(150);

		}

		stopValue = (int) ( Math.random() * 6);
		currentImg = diceLandPics[stopValue];
		stopValue2 = (int) ( Math.random() * 6);
		currentImg2 = diceLandPics[stopValue2];
		repaint();

		die1 = stopValue + 1;
		die2 = stopValue2 + 1;
		workSum = die1 + die2;

		firstDie.setText( Integer.toString( die1 ) );
		secondDie.setText( Integer.toString( die2 ) );
		sum.setText( Integer.toString( workSum ) );

		return workSum;
	}


	public void add1000()
	{
		bankBalance = bankBalance + 1000;
		bank.setText( Integer.toString( bankBalance ) );


	}


	public void resetGame()
	{
		firstRoll = true;   
		sumOfDice = 0;         
		myPoint = 0;  
		gameStatus = CONTINUE;  
		bankBalance = 1000;
		betAmount = 100; 
		firstDie.setText("");
		secondDie.setText("");
		sum.setText("");
		point.setText("");
		bank.setText( "1000" );
		bet.setText( "100" );
		currentImg = diceLandPics[0];
		currentImg2 = diceLandPics[0];
		modeImg = moodModePics[0];
		moodImg = moodModePics[0];
		repaint();

	}
	
	
	public void paint(Graphics screen) 
	{
			screen.drawImage(modeImg, 40, 70, this);
			screen.drawImage(currentImg, 120, 70, this);
			screen.drawImage(currentImg2, 190, 70, this);
			screen.drawImage(moodImg, 260, 70, this);
	}
}