/* *****************************************************************
	Homework #6
	Author: Butler, Martin
	Date: 2004.12.02
	Due: 2004.12.09
	CMPT 505
***************************************************************** */
import java.applet.Applet.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.lang.*;
import java.io.*;

public class BubbleGame extends JFrame implements ActionListener
{
	final int MAXBUBBLE = 100;
	boolean playMode = false;
	boolean boolSaveGame = false;
	boolean boolLoadGame = false;
	boolean exitGame = false;
	
	int exitCounter = 0;  // counter for exit timer.
	
	// **************************
	// south panel components
	// **************************
	JPanel soPanel = new JPanel();
	JButton startButton = new JButton ("Start");
	JButton stopButton = new JButton ("Stop");
	JButton saveButton = new JButton ("Save");
	JButton loadButton = new JButton ("Load");
	JButton exitButton = new JButton ("Exit");
	
	// **************************
	// north panel components
	// **************************
	JPanel noPanel = new JPanel();
	JLabel totBubbles = new JLabel("Number of Bubbles:");
	int intTotBubbles = 0;
	String strTotBubbles = "" + intTotBubbles;
	JLabel numTotBubbles = new JLabel(strTotBubbles);
	JLabel totHit = new JLabel("Bubbles Hit:");
	int intTotHit = 0;
	String strTotHit = "" + intTotHit;
	JLabel numTotHit = new JLabel(strTotHit);
	
	// **************************
	// center panel components
	// **************************
	JPanel  contentPane = new JPanel(new BorderLayout());
  	CanvasPanel canvas  = new CanvasPanel (MAXBUBBLE);
  	Dimension appSize;

	// *************************************************
	// Random number to control random aspects of game,
	// including where to create of move a circle
	// *************************************************
	Random r = new Random ();
	final float OFFSET = 0;
	final float RANGE = 50;
		
  	int appWidth = 800 , appHeight = 600;
  	
  	final int DELAY = 25;
  	javax.swing.Timer timer;
  	javax.swing.Timer timerExit;
  	
  	public BubbleGame ()
  	{
    	System.out.println ("Bubble constructed");
  	}
  	
  	public static void main (String args[])
  	{
  		BubbleGame bg = new BubbleGame ("The Game of Bubbles");
  	}
  	
  	public BubbleGame (String title)
  	{
  		super (title);
  		System.out.println ("Bubble Game constructed");
  		init();
  	}

  	public void init ()
  	{
    	System.out.println ("Bubble initialized with contentPane size "+
		contentPane.getSize ());
		
		timer = new javax.swing.Timer (DELAY, null);
		timerExit = new javax.swing.Timer (2000, null);

    	startButton.addActionListener (this);
    	stopButton.addActionListener (this);
    	saveButton.addActionListener (this);
    	loadButton.addActionListener (this);
    	exitButton.addActionListener (this);
    	
    	timer.addActionListener (new ReboundListener());
    	timerExit.addActionListener (new ExitListener());

    	/*String widthS = getParameter ("width");
    	String heightS = getParameter ("height");

    	appWidth = Integer.parseInt(widthS);
    	appHeight = Integer.parseInt(heightS);
    	System.out.println("width="+widthS+" height="+heightS);*/
    	appSize = new Dimension (appWidth, appHeight);

		soPanel.setPreferredSize (new Dimension(150, 50));
		soPanel.setBackground (Color.blue);
		soPanel.add (startButton);
		soPanel.add (stopButton);
		soPanel.add (saveButton);
		soPanel.add (loadButton);
		soPanel.add (exitButton);
	
		noPanel.setPreferredSize (new Dimension (150, 50));
		noPanel.setBackground (Color.blue);
		noPanel.add (totBubbles);
		noPanel.add (numTotBubbles);
		noPanel.add (totHit);
		noPanel.add (numTotHit);
	

	
    	contentPane.setSize (appSize);
    	contentPane.setPreferredSize (appSize);
    	contentPane.add (canvas, BorderLayout.CENTER);
    	contentPane.add (noPanel, BorderLayout.NORTH);
    	contentPane.add (soPanel,  BorderLayout.SOUTH);
    	contentPane.setOpaque (true);

    	this.setContentPane(contentPane);
    	pack();
    	show();
  	}

	public void actionPerformed (ActionEvent e)
  	{  	
    	JButton b = (JButton) e.getSource();
    	
    	if (b == startButton) 
      	{
      		playMode = true;
      		
      					
			canvas.reset();
			repaint();
      		
      		System.out.println ("Timer Started");
      		timer.start();
 								
      	}
      	
      	if (b == stopButton)
      	{
      		playMode = false;
      	}
      	
      	if (b == saveButton)
      	{
      		// *****************************
      		// only save the setting if the game has been started.
      		// the saving is handled by the game timer as the game continues run
      		// ****************************
      		if (playMode == true)
      		{
      			boolSaveGame = true;
      		}
      	}
      	if (b == loadButton)
      	{
      		// *********************************
      		// loads in the last saved game regardless of state of game.
      		// keeps/turns on game mode
      		// *********************************
      		String loadFile = "firegame.ser";
			System.out.println ("loading game from file " + loadFile);
			loadGame (loadFile);
			boolLoadGame = false;
			if (!playMode)
			{
				playMode = true;
				timer.start();
			}
			repaint();
      	}
      	if (b == exitButton)
      	{
      		// ********************************
      		// if game was in play, it will save game to file before exiting
      		// otherwise it will end the game after a period of time
      		// as defined by the timerexit
      		// ********************************
      		if (playMode == true)
      		{
      			String saveFile = "firegame.ser";
				System.out.println ("saving game to file " + saveFile +
				  " with " + canvas.totHit + " Hits of " + canvas.totBubbles 
				  + " Bubbles.");
				saveGame (saveFile);
				playMode = false;
      		}
      		canvas.gbExit();
      		repaint();
      		timerExit.start();
      		
      	}
    }
    
    public class ReboundListener implements ActionListener
    {
    	public void actionPerformed (ActionEvent e)
    	{
    		// ****************************************************
    		// generate a random to determine actions during each
    		// loop through the timer
    		// ****************************************************
    		float bubbleAction = r.nextFloat() * RANGE + OFFSET;
			
			System.out.println("bubbleAction="+bubbleAction);
			
			// *******************************************************
			// only creates bubbles if random number is less then 10
			// *******************************************************
			if (bubbleAction < 10)
			{
				canvas.createBubble();
				strTotBubbles = "" + intTotBubbles;
			}
			
			// ********************************************************
			// verify if circles are needed to move by calling
			// movebubble and passing the random number to
			// compare against the circles speed attribute
			// ********************************************************
			canvas.moveBubble(bubbleAction);
			
			// ********************************************************
			// updated the counter displays
			// ********************************************************
			strTotBubbles = "" + canvas.totBubbles;
			strTotHit = "" + canvas.totHit;
			numTotBubbles.setText(strTotBubbles);
			numTotHit.setText(strTotHit);
			
			repaint();
			
			// *************************
			// if boolean is turned on by the button press action
			// the game will be saved in its current state and continue
			// running.
			// ***************************
			if (boolSaveGame == true)
			{
				String saveFile = "firegame.ser";
				System.out.println ("saving game to file " + saveFile +
				  " with " + canvas.totHit + " Hits of " + canvas.totBubbles 
				  + " Bubbles.");
				saveGame (saveFile);
				boolSaveGame = false;
			}
			
			// ************************************************************
			// performed if the stop button was clicked for the first time
			// after the start button clicked.
			// ************************************************************
			if (playMode == false)
			{
				timer.stop();
				canvas.clear();
				
				repaint();
			}
		}
    }

	// ************************
	// Exit timer for delayed closing of game
	// *************************
    public class ExitListener implements ActionListener
    {
    	public void actionPerformed (ActionEvent e)
    	{
    		exitCounter++;
    		canvas.gbExit();
    		
			repaint();
			if (exitCounter == 3)
			{
				System.out.println("Goodbye!");
      			System.exit(0);
      		}
      	}
      	
    }
    
    public void saveGame (String fileName)
    {
    	try
    	{
    		FileOutputStream fos = new FileOutputStream (fileName);
    		ObjectOutputStream oos = new ObjectOutputStream (fos);
    		oos.writeObject (this);
    		oos.close();
    	}
    	catch (IOException IOException)
    	{
    		System.out.println (IOException);
    	}
    }
    
    public void loadGame (String fileName)
    {
    	try
    	{
    		FileInputStream fis = new FileInputStream (fileName);
    		ObjectInputStream ois = new ObjectInputStream (fis);
    		BubbleGame bg = (BubbleGame) ois.readObject ();
    		System.out.println ("game loaded from file "+fileName);
    		canvas.loadGame (bg);
    		ois.close();
    	}
    	catch (IOException IOException)
    	{
    		System.out.println (IOException);
    	}
    	catch (ClassNotFoundException ClassNotFoundException)
    	{
    		System.out.println (ClassNotFoundException);
    	}
    }
    	
}

