/**********************************
 * Assignment 5: Pacman
 * Date: 5/5/2006
 *
 * Jenna Holloway: jh382, 563324
 * Benji Shultz: bas67, 1786511
 **********************************/
package gui;

import game.Constants;
import game.Game;
import game.map.PacmanMap;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.InputStream;

import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineEvent;
import javax.sound.sampled.LineListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JProgressBar;
import javax.swing.JLabel;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.plaf.metal.MetalLookAndFeel;

/**
 * Class to create the GUI for the Game
 */
public class GUI extends JFrame implements Constants {

 private static final long serialVersionUID = 4322838670943725248L;
 private final Animator animator = new Animator();
 private final Game game;
 private final SplashScreen titleScreen;
 private final JLabel scorebar=new JLabel("Score: "+ 0);
 private final JLabel life= new JLabel ("Lives: "+3);
 private final JButton startButton = new JButton("Start");
 private final JProgressBar tummy=new JProgressBar();
 private final JLabel dookies=new JLabel("Dookies: "+0);
 private JPanel controlPanel = new JPanel();
 private Background bg;

 
 
 public final Sound openingSong = new Sound("openingSong");
 public final Sound eatDot = new Sound("eatdot");
 public final Sound eatBigDot = new Sound("eatBigDot2");
 public final Sound die = new Sound("die");
 public final Sound eatingGhosts = new Sound("eatingGhosts");
 public final Sound intermission = new Sound("intermission");
 public final Sound[] scream=new Sound[]{
   new Sound("scream1"),
   new Sound ("scream2")
   };
 public final Sound[] fart= new Sound[]{
   new Sound("fart1"),
   new Sound("fart2"),
   new Sound("fart3"),
   };
 public final Sound flush=new Sound("flush");
 public final Sound coin=new Sound("coin");
 public final Sound mushroom=new Sound("eatMushroom");
 public final Sound loseLife=new Sound("loseLife");
 public final Sound gameOver=new Sound("gameOver");
 public final Sound win=new Sound("stageClear");
 
 
 
 public final gui.HighScoreWindow hsw=new gui.HighScoreWindow(); 
 private static boolean silent = false; // silent mode
   
 public static void main(String[] args) {
      silent = args.length > 0 && args[0].equals("-s");
      try {
         UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
      } catch (Exception e) {}
     //new selectiongui();
      new GUI();
   }

 public GUI() {
  setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  setTitle("CS211 Pacman");

  game = new Game(this);
     bg = new Background(game);

  //layout components
  add(bg, BorderLayout.CENTER);
  
//  The title screen title
  PacmanMap map = game.map;
  titleScreen=new SplashScreen(map);
  //Add the title Screen
 add(titleScreen, BorderLayout.CENTER);
  

  /* end Title Screen */
  controlPanel.add(startButton);
  add(controlPanel, BorderLayout.SOUTH);
  
  
  
  
  //initialize listeners
  startButton.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent evt) {
    if (startButton.getText().equals("Start")) {
     controlPanel.removeAll();
       controlPanel.add(scorebar);
       controlPanel.add(startButton);
       controlPanel.add(life);
     if(game.isPoo()){
      controlPanel.add(new JLabel("Tummy: "));
         tummy.setMaximum(10);
         controlPanel.add(tummy);
         controlPanel.add(dookies);}
     controlPanel.repaint();
     titleScreen.setVisible(false);
     add(bg, BorderLayout.CENTER);
     openingSong.playAndWait(10);
     startButton.setText("Pause");
     GUI.this.requestFocusInWindow();
     game.playGame();
     try{
     animator.start();}
     catch(Exception e){
      restartAnimation();
  }
    } else if (startButton.getText().equals("Pause")) {
     animator.stopAnimation();  
     startButton.setText("Resume");
    } else { //button text = "Resume"
  
     startButton.setText("Pause");
     GUI.this.requestFocusInWindow();
     restartAnimation();
    }
   }
  });
  startButton.setEnabled(true);
  addKeyListener(game.localPlayer);
  pack();
  Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
  setLocation((screenSize.width - getWidth())/2, (screenSize.height - getHeight())/2);
  setVisible(true);
 }

 public void updateLocations(double dt) {
  game.updateUnits(game.localPlayer, dt);
  game.updateUnits(game.aiPlayer, dt);
 }

 public void stopAnimation() {
  animator.stopAnimation();
 }
 
 
//set up the gui for a new game
 public void reset(){
  game.setNorm();
  remove(bg);
  animator.stopAnimation();
  controlPanel.removeAll();
  controlPanel.add(startButton);
  splash();
  startButton.setText("Start");
  repaint();
 }
 
 public void setLives(int l){
  life.setText("Lives: "+l);
 }

 public void restartAnimation() {
  synchronized(animator) {
   animator.notify();
  }
 }
 
 public void splash(){
  titleScreen.setVisible(true);
  titleScreen.repaint();
 }
 /**
  * 
  * SplashScreen class sets up the mode select interface
  * It is made visible after every round
  *
  */
 class SplashScreen extends JPanel{
private static final long serialVersionUID = 1565276423243439625L;

public SplashScreen(PacmanMap map){
   setBackground(Color.BLACK);
   setAlwaysOnTop(true);
   JLabel thetitle=new JLabel("Welcome to Pacman!");
   thetitle.setForeground(Color.WHITE);
   thetitle.setFont(new Font("Sans Serif", Font.BOLD, 28));
   
   JLabel thesubtitle=new JLabel("Please choose a game mode and then press start.");
   thesubtitle.setForeground(Color.RED);
   thesubtitle.setFont(new Font("Sans Serif", Font.BOLD, 18));
   
   final JLabel themode=new JLabel("Just like the arcade, but free");
   themode.setForeground(Color.YELLOW);
   themode.setFont(new Font("Sans Serif", Font.BOLD, 18));
   
   
   //The Buttons for the Title Screen
   try {
    UIManager.setLookAndFeel(new MetalLookAndFeel());
    }
    catch(Exception e) {}

   //button 1
   JButton gameversions1 = new JButton("Normal Pacman");
   gameversions1.setFont(new Font("Sans Serif", Font.BOLD, 36));
   gameversions1.setBackground(Color.BLACK);
   gameversions1.setForeground(Color.YELLOW);
   
   gameversions1.addActionListener(
        new ActionListener() {
            public void actionPerformed(ActionEvent e) {
               
                themode.setText("Just like the arcade, but free");
                game.setNorm();
                remove(bg);
                bg=new Background(game);
                add(bg,BorderLayout.CENTER);
            }
        }
    );
   
   //button 2
   JButton gameversions2 = new JButton("Pooper Pacman");
   gameversions2.setFont(new Font("Sans Serif", Font.BOLD, 36));
   gameversions2.setBackground(Color.BLACK);
   gameversions2.setForeground(Color.BLUE);
   
   gameversions2.addActionListener(
        new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                themode.setText("Hit space bar to drop ghost-poisoning loads of poo");
                game.setPoo();  
                remove(bg);
                bg=new Background(game);
                add(bg,BorderLayout.CENTER);
                          
            }
        }
    );
   
   
   //button 3
   JButton gameversions3 = new JButton("Psychadelic Pacman");
   gameversions3.setFont(new Font("Sans Serif", Font.BOLD, 36));
   gameversions3.setBackground(Color.BLACK);
   gameversions3.setForeground(Color.GREEN);
   
   
   gameversions3.addActionListener(
        new ActionListener() {
            public void actionPerformed(ActionEvent e) {
            
    
                themode.setText("Nothing is crazier than a color change");
                game.setPsych();
                remove(bg);
                bg=new Background(game);
                add(bg,BorderLayout.CENTER);
            }
        }
    );
   
   //button 4
   JButton gameversions4 = new JButton("Super Mario Pacman");
   gameversions4.setFont(new Font("Sans Serif", Font.BOLD, 36));
   gameversions4.setBackground(Color.BLACK);
   gameversions4.setForeground(Color.RED);

   gameversions4.addActionListener(
        new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                themode.setText("Pacman's off somewhere with Peach,\n Mario's stuck in his place");
                game.setMario();
                remove(bg);
                bg=new Background(game);
                add(bg,BorderLayout.CENTER);
            }
        }
    );
   

   
   
   //The title screen
   
   
  
   setPreferredSize(new Dimension(CELL*map.getTileWidth(), CELL*map.getTileHeight()));
   setBackground(Color.BLACK);
   JLabel alabel = new JLabel(new ImageIcon(System.getProperty("user.dir")+"/"+iconDirectory+"tongue.gif"),JLabel.CENTER);
   alabel.setOpaque(true);
   
   add(thetitle);
   add(thesubtitle);
   
   add(alabel);
   
   add(gameversions1);
   add(gameversions2);
   add(gameversions3);
   add(gameversions4);
   add(themode);
   
   setVisible(true);
   
 }}
 /**
  * Class for running Animations.
  */

 
 class Animator extends Thread {
  final long FRAME_TIME = 60; // min # of milliseconds/frame
  final double DT_MAX = .03; // max frame latency
  boolean isRunning = false; // Is the simulator running?

  // start the simulation
  public synchronized void run() {
   double dt = 0; // delta time (change in time from frame to frame)
   long nextFrame = 0; // when the next frame should occur
   long lastFrame = System.currentTimeMillis(); // the time of the last frame
   long firstFrame = lastFrame;

   nextFrame = System.currentTimeMillis() + FRAME_TIME;
   isRunning = true; // Is the simulator running?
   long now = 0;

   // main game loop
   while (true) {
    while (isRunning) {
     now = System.currentTimeMillis();

     // incremental update
     if (now > nextFrame) {
      // update the locations of everything
      updateLocations(FRAME_TIME/1000.0);
      scorebar.setText("Score: "+game.getScore());
      tummy.setValue(game.poopometer());
      dookies.setText("Dookies: "+game.pooAmmo());
      

      game.checkCollisions();
      // redraw to the screen
      bg.repaint();

      // update the time
      lastFrame = now;
      nextFrame = now + FRAME_TIME;
     }

     // calculate the delta time and scale if running slowly
     dt = (double) (now - lastFrame) / 1000;
     if (dt > DT_MAX) dt = DT_MAX;
     bg.setAnimationTime(now - firstFrame);
    }

    //someone stopped us
    try {
     wait();         
    } catch (InterruptedException ie) {}
    isRunning = true;
   }
  }

  public void stopAnimation() {
   isRunning = false;
  }

  public boolean isRunning() {
   return isRunning;
  }
  
 }

 /**
  * Sounds
  */
 public class Sound implements LineListener {
  private Clip clip;

  Sound(String soundFileName) {
   InputStream sound = ClassLoader.getSystemResourceAsStream(soundDirectory + soundFileName + ".wav");
   try {
    clip = AudioSystem.getClip();
    clip.open(AudioSystem.getAudioInputStream(sound));
    clip.addLineListener(this);
   } catch (Exception e) {
    clip = null;
   }
  }

  public void play() {
   if (silent || clip == null) return;
   clip.setFramePosition(0);
   clip.loop(0);
  }
  
  //wait the specified number of seconds, or until
  //the song is over, whichever comes first
  public synchronized void playAndWait(int seconds) {
   if (silent || clip == null) return;
   clip.setFramePosition(0);
   clip.loop(0);
   try {
    wait(seconds * 1000);
   } catch (InterruptedException ie) {}
  }

  //to implement the LineListener interface
  public synchronized void update(LineEvent le) {
   if (le.getType().equals(LineEvent.Type.STOP)) notify();
  }
 }
}
