/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package tetris2;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Arrays;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

/**
 *
 * @author Fmunch
 */
public class Main implements ScoreRegistrar {

  File score_file;
  MaxSizedPriorityQueue<Score> mspq;

  static class Score implements Comparable<Score>, java.io.Serializable {
//        static long serialVersionUID = -2687277721316825005L;

    String name;
    int score;

    Score(String str, int i) {
      name = str;
      score = i;
    }

    String getName() {
      return name;
    }

    int getScore() {
      return score;
    }

    @Override
    public String toString() {
      return name + " : " + String.format("%5.2f", score / 1000.0f);
    }

    public int compareTo(Score o) {
      return score - o.score;
    }
  }

  Main() {
    score_file = new File(System.getProperty("user.home") + "/Tetris/Scores");
  }

  public void registerScore(String name, int score) {
    loadScore();
    if (mspq == null) {
      return;
    }
    mspq.add(new Main.Score(name, score));
    saveScore();
  }

  public void loadScore() {
    FileInputStream fis;
    ObjectInputStream ois;
    mspq = null;
    //System.out.println(">>" + score_file.getParentFile().getAbsolutePath());
    if (!score_file.getParentFile().exists()) {
      score_file.getParentFile().mkdirs();
    }
    if (score_file.exists()) {
      try {
        fis = new FileInputStream(score_file);
        ois = new ObjectInputStream(fis);
        mspq = (MaxSizedPriorityQueue<Score>) ois.readObject();
      } catch (FileNotFoundException ex) {
        Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
      } catch (IOException ex) {
        Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
      } catch (ClassNotFoundException ex) {
        Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
      }
    }
    if (mspq == null) {
      mspq = new MaxSizedPriorityQueue<Score>(10);
    }
  }

  public void saveScore() {
    FileOutputStream fos;
    ObjectOutputStream oos;
    try {
      fos = new FileOutputStream(score_file);
      oos = new ObjectOutputStream(fos);
      oos.writeObject(mspq);
      oos.close();
    } catch (FileNotFoundException ex) {
      Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
    } catch (IOException ioe) {
      System.err.println("IOErr");
      Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ioe);
    }
  }
  /**
   * @param args the command line arguments
   */
  static TetrisPanel tp;
  static JPanel score_panel;

  public void updateScorePanel() {
    String game_name = null;
    loadScore();
    score_panel.removeAll();
    score_panel.setPreferredSize(new Dimension(200, 400));
    if (mspq == null) {
      return;
    }
    score_panel.setLayout(new GridLayout(mspq.getMaxHeight() + 1, 1));
    score_panel.add(new JLabel());
    Score[] score_array = new Score[0];
    score_array = mspq.toArray(score_array);
    Arrays.sort(score_array);
    for (int i = score_array.length - 1; i >= 0; i--) {
      JPanel score_p = new JPanel();
      score_p.setLayout(new FlowLayout());
      score_p.add(new JLabel(score_array[i].getName()));
      score_p.add(new JLabel(String.format("%d", score_array[i].getScore())));
      score_panel.add(score_p);
    }
  }
  static String restart_str="Restart";
  static String pause_str="Pause";
  static String score_str="score";
  static String about_str="About";
  static String exit_str="Exit";
  static String doneby_str="Done by François Munch";
  static String scorepanel_str="Score Panel";
  public static void main(String[] args) {
    final Main maingame = new Main();
    GameTypes<TetrisGameType> gt = new GameTypes<TetrisGameType>();
    gt.add(new TetrisGameType("beg1:0:250:10:2"));
    gt.add(new TetrisGameType("beg2:200:230:15:3"));
    gt.add(new TetrisGameType("beg3:500:210:25:5"));
    gt.add(new TetrisGameType("beg4:1000:190:40:8"));
    gt.add(new TetrisGameType("avg1:2000:180:50:10"));
    gt.add(new TetrisGameType("avg2:3500:170:80:16"));
    final JFrame jf = new JFrame("Playing tetris");
    JMenuBar menubar = new JMenuBar();
    JMenu file_m = new JMenu();
    menubar.add(file_m);
    tp = new TetrisPanel();
    jf.setJMenuBar(menubar);
    JMenu restart_m = new JMenu(restart_str);
    JMenuItem pause_m = new JMenuItem(pause_str);
    JMenuItem scores_m = new JMenuItem(score_str);
    JMenuItem about_m = new JMenuItem(about_str);
    JMenuItem exit_m = new JMenuItem(exit_str);
    menubar.add(restart_m);
    menubar.add(pause_m);
    menubar.add(scores_m);
    menubar.add(about_m);
    menubar.add(exit_m);
    pause_m.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        tp.setPause(!tp.getPause());
      }
    });
    exit_m.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        System.exit(0);
      }
    });
    about_m.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        boolean startstate = tp.getPause();
        tp.setPause(true);
        JOptionPane.showMessageDialog(jf, doneby_str,
                about_str, JOptionPane.INFORMATION_MESSAGE);
        tp.setPause(startstate);
      }
    });

    scores_m.addActionListener(new ActionListener() {

      JDialog jd;
      boolean prevstate;

      public void actionPerformed(ActionEvent e) {
        if (jd == null) {
          prevstate = tp.getPause();
          tp.setPause(true);
          jd = new JDialog(jf, scorepanel_str);
          jd.setLayout(new BorderLayout());
          score_panel = new JPanel();
          jd.add(new JLabel(score_str), BorderLayout.NORTH);
          jd.add(score_panel, BorderLayout.CENTER);
          //jp.setLayout(new GridLayout(mspq.getMaxHeight()+1, 2));
          maingame.updateScorePanel();
          jd.pack();
          jd.addWindowListener(new WindowAdapter() {

            @Override
            public void windowClosing(WindowEvent e) {
              tp.setPause(prevstate);
            }
          });
        } else {
          maingame.updateScorePanel();
        }
        jd.setVisible(true);
      }
    });
    Iterator<TetrisGameType> it = gt.iterator();
    int i = 0;
    while (it.hasNext()) {
      JMenuItem menuitem = new JMenuItem(it.next().getName());
      menuitem.addActionListener(new MenuListener(i));
      restart_m.add(menuitem);
      i++;
    }
    jf.setPreferredSize(new Dimension(533, 600));
    jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    tp.setGameTypes(gt);
    jf.getContentPane().add(tp);
    jf.pack();
    jf.setVisible(true);
    tp.setScoreRegistrar(maingame, System.getProperty("user.name"));
  }

  static String restart_game_str="Restart a game";
  static String ask_restart_str="Do you want to restart ?";
  static class MenuListener implements ActionListener {

    int tgtindex;

    MenuListener(int i) {
      tgtindex = i;
    }

    public void actionPerformed(ActionEvent e) {
      boolean startstate = tp.getPause();
      tp.setPause(true);
      int res = JOptionPane.showConfirmDialog(null, ask_restart_str ,
              restart_game_str, JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);

      if (res == 0) {
        tp.restart(tgtindex);
      }
      tp.setPause(startstate);
    }
  };
}

