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

package MineSweeper;

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.awt.event.WindowFocusListener;
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.ButtonGroup;
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.JPanel;
import javax.swing.JRadioButtonMenuItem;

/**
 *
 * @author Cecile
 */
public class Main implements ScoreRegistrar{
//    static long serialVersionUID = -2687277721316825004L;
    static String PATH="C:\\MineSweeper\\";
    static MaxSizedPriorityQueue<Score> mspq=null;
    static String game_type="simple";
    static class Score implements Comparable<Score>,java.io.Serializable
    {
//        static long serialVersionUID = -2687277721316825005L;
        String name;
        int time;
        Score(String str,int i)
        {
            name = str;
            time = i;
        }
        String getName()
        {
            return name;
        }
        int getTime()
        {
            return time;
        }
        @Override
        public String toString()
        {
            return name + " : "+String.format("%5.2f", time/1000.0f);
        }

        public int compareTo(Score o) {
            return o.time-time;
        }
    }
    static String curr_game=null;
    public void registerScore(String name, int time) {
        loadScore(curr_game);
        if(mspq==null)
        {
          mspq=new MaxSizedPriorityQueue(10);
        }
        mspq.add(new Score(name, time));
        saveScore(curr_game);
    }
    private static String []getScors(int i)
    {
        String []res=new String[2];
        res[0]="A";
        res[1]="B";
        return res;
    }


    static File score_file;// = new File(PATH+"scores.os");

    public static void loadScore(String game_name)
    {
        score_file=new File(PATH+game_name+"_scores.os");
        //System.out.println("Loading score from : "+score_file.getName());
        if(score_file.exists() && score_file.canRead())
        {
            try {
                FileInputStream fis = new FileInputStream(score_file);
                ObjectInputStream ois = new ObjectInputStream(fis);
                mspq = (MaxSizedPriorityQueue<Main.Score>
)ois.readObject();
                ois.close();
            } catch (ClassNotFoundException ex) {
                Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
            } 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);
            }
        }
        else
        {
            mspq=null;
        }
    }

    static public MineSweeperGameType []getTypeList()
    {
        //File input_file=new File("MineSweeper_GamesTypes.os");
        File input_file=new File("MineSweeper_GamesTypes.os");
        FileInputStream fis;
        GameTypes gts=null;
        MineSweeperGameType []result=null;
        try {
            fis = new FileInputStream(input_file);
            ObjectInputStream ois = new ObjectInputStream(fis);
            System.out.println("Going to extract games");
            gts=(GameTypes)ois.readObject();
            System.out.println("Games types extracted");
        } 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 cnfe) {
                Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, cnfe);
        }
        if(gts!=null)
        {
            Iterator<GameType> it=gts.iterator();
            result=new MineSweeperGameType[gts.size()];
            int i = 0;
            while(it.hasNext())
            {
                GameType curr=it.next();
                if(curr instanceof MineSweeperGameType)
                {
                    result[i]=MineSweeperGameType.class.cast(curr);
                    i++;
                }
            }
        }
        return result;
    }

    public static void saveScore(String game_name)
    {
        score_file=new File(PATH+game_name+"_scores.os");
        if(!score_file.getParentFile().exists())
        {
          score_file.getParentFile().mkdir();
        }
        System.out.println(score_file.canWrite());
        System.out.println(score_file.getAbsolutePath());
        {
            ObjectOutputStream oos = null;
            try {
                FileOutputStream 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 ex) {
                Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
            } finally {
                try {
                    oos.close();
                } catch (IOException ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
        
    }
    static JPanel score_panel;

    static MineSweeperGameType []gameslist;
    static JRadioButtonMenuItem []jrbmi;
    public static void updateScorePanel()
    {
       String game_name=null;
       for(int i = 0 ; i < jrbmi.length;i++)
       {
           if(jrbmi[i].isSelected())
           {
               game_name=gameslist[i].getName();
           }
       }
       loadScore(game_name);
       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("%5.1f",score_array[i].getTime()/1000.f)));
           score_panel.add(score_p);
       }
    }
    
    /**
     * @param args the command line arguments
     */

    public static void main(String[] args) {
        PATH = System.getProperty("user.home")+"/MineSweeper/";
        final JFrame jf = new JFrame("Testing cards");
        JMenuBar mb=new JMenuBar();
        jf.setJMenuBar(mb);
        JMenu game_m=new JMenu("File");
        JMenu help_m=new JMenu("Help");
        mb.add(game_m);
        mb.add(help_m);

        String user = System.getProperty("user.name");

        final JRadioButtonMenuItem simple_rmit=new JRadioButtonMenuItem("Simple");
        final JRadioButtonMenuItem avg_rmit=new JRadioButtonMenuItem("Average");
        final JRadioButtonMenuItem long_rmit=new JRadioButtonMenuItem("Long");
        JMenuItem score_mit=new JMenuItem("Scores");
        JMenuItem restart_mit=new JMenuItem("Restart");
        JMenuItem pause_mit=new JMenuItem("Pause");
        JMenuItem exit_mit=new JMenuItem("Exit");
        ButtonGroup group = new ButtonGroup();
        gameslist = getTypeList();
        jrbmi = new JRadioButtonMenuItem [gameslist.length];
        for(int i = 0 ; i < gameslist.length;i++)
        {
            JRadioButtonMenuItem butt = new JRadioButtonMenuItem(gameslist[i].getName());
            jrbmi[i]=butt;
            group.add(butt);
            game_m.add(butt);
        }
        jrbmi[0].setSelected(true);
        curr_game=gameslist[0].getName();
        final MineSweeper minesweeper = new MineSweeper(gameslist[0]);
        minesweeper.setRegistrar((ScoreRegistrar) new Main(), user);
        game_m.add(score_mit);
        game_m.add(restart_mit);
        game_m.add(pause_mit);
        game_m.add(exit_mit);
        simple_rmit.setSelected(true);

        score_mit.addActionListener(new ActionListener()
        {
            JDialog jd;
            public void actionPerformed(ActionEvent e) {
                if(jd==null)
                {
                    jd = new JDialog(jf,"Score panel");
                    jd.setLayout(new BorderLayout());
                    score_panel=new JPanel();
                    jd.add(new JLabel("Scors"),BorderLayout.NORTH);
                    jd.add(score_panel,BorderLayout.CENTER);
                    //jp.setLayout(new GridLayout(mspq.getMaxHeight()+1, 2));
                    updateScorePanel();
                    jd.pack();
                }
                else
                {
                    updateScorePanel();
                }
                jd.setVisible(true);
            }

        });

        restart_mit.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                for(int i = 0 ; i <  jrbmi.length ;i++)
                {
                    if(jrbmi[i].isSelected())
                    {
                        int w = gameslist[i].getWidth();
                        int h = gameslist[i].getHeight();
                        int n = gameslist[i].getMines();
                        minesweeper.restart(w, h, n);
                        Main.curr_game = gameslist[i].getName();
                        break;
                    }
                }
            }
        });

        pause_mit.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                minesweeper.pause();
                //System.exit(0);
            }
        });
        exit_mit.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                minesweeper.pause();
                saveScore(curr_game);
                System.exit(0);
            }
        });
        jf.addWindowFocusListener(new WindowFocusListener(){

            public void windowGainedFocus(WindowEvent e) {
                minesweeper.pause(false);
            }

            public void windowLostFocus(WindowEvent e) {
                minesweeper.pause(true);
            }


        });

        jf.setPreferredSize(new Dimension(600,400));
        //jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.addWindowListener(new WindowAdapter(){
            @Override
            public void windowClosing(WindowEvent e)
            {
                saveScore(curr_game);
                System.exit(0);
            }
        });
        jf.getContentPane().add(minesweeper);
        jf.setVisible(true);
        jf.pack();
    }

}


