package uk.ac.york.minesweeper;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class MinesweeperFrame extends JFrame implements ActionListener
{
    private static final long serialVersionUID = 1L;

    // Constants
    private static final String[] DIFFICULTIES = { "Easy", "Medium", "Hard" };

    private static final String INCREMENT = "incr";
    private static final String RESET = "reset";

    // Interface
    private JPanel mainPanel =  new JPanel(new BorderLayout(10, 10));
    private JComboBox<String> difficultyBox = new JComboBox<String>(DIFFICULTIES);
    private MinefieldPanel minePanel;

    // Timer
    private Timer scoreTimer = new Timer(1000, this);
    private JLabel topTimer;
    private int time = 0;

    // Button Images
    private JButton topResetBtn;

    public MinesweeperFrame()
    {
        // Basic Interface Settings
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.setLayout(new BorderLayout(0,0));
        this.getContentPane().setBackground(Color.white);
        this.setSize(new Dimension(400, 500));
        this.setMinimumSize(new Dimension(400, 500));
        this.setTitle("Minesweeper");

        // Interface Structure
        JPanel topPanel = new JPanel(new GridLayout(1, 3, 10, 10));
        topPanel.setBackground(Color.white);

        JPanel centerPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 10));
        centerPanel.setBackground(Color.white);

        JPanel centerMidPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 10));

        minePanel = new MinefieldPanel(new Minefield(16, 16, 40));
        minePanel.addStateChangeListener(new MinefieldStateChangeListener()
        {
            @Override
            public void stateChanged(MinefieldStateChangeEvent event)
            {
                if(minePanel.getMinefield().getGameState() == GameState.RUNNING)
                {
                    topResetBtn.setIcon(new ImageIcon(Images.FACE_NORMAL));
                    scoreTimer.start();
                }
                else
                {
                    if(minePanel.getMinefield().getGameState() == GameState.WON)
                    {
                        topResetBtn.setIcon(new ImageIcon(Images.FACE_WON));
                    }
                    else if (minePanel.getMinefield().getGameState() == GameState.LOST)
                    {
                        topResetBtn.setIcon(new ImageIcon(Images.FACE_LOST));
                    }
                    scoreTimer.stop();
                }
                topResetBtn.repaint();
            }
        });

        centerMidPanel.add(minePanel);

        // Difficulty Chooser
        difficultyBox.setSelectedIndex(1);

        // Reset Button
        topResetBtn = new JButton();
        topResetBtn.setPreferredSize(new Dimension(50, 50));
        topResetBtn.setActionCommand(RESET);
        topResetBtn.addActionListener(this);
        centerPanel.add(topResetBtn);

        topResetBtn.setIcon(new ImageIcon(Images.FACE_NORMAL));

        // Labels
        topTimer = new JLabel(String.valueOf(time) + " Seconds");
        scoreTimer.setActionCommand(INCREMENT);

        // Adding Items to Grid
        topPanel.add(difficultyBox);
        topPanel.add(centerPanel);
        topPanel.add(topTimer);
        mainPanel.add(topPanel, BorderLayout.NORTH);
        mainPanel.add(centerMidPanel, BorderLayout.CENTER);

        this.getContentPane().add(mainPanel, BorderLayout.NORTH);
        this.pack();
    }

    @Override
    public void actionPerformed(ActionEvent event)
    {
        if(event.getActionCommand().equals(INCREMENT))
        {
            time++;
        }
        else if(event.getActionCommand().equals(RESET))
        {
            time = 0;

            if (difficultyBox.getSelectedIndex() == 0)
            {
                minePanel.setMinefield((new Minefield(9, 9, 10)));
            }
            else if (difficultyBox.getSelectedIndex() == 2)
            {
                minePanel.setMinefield((new Minefield(30, 16, 99)));
            }
            else if (difficultyBox.getSelectedIndex() == 1)
            {
                minePanel.setMinefield((new Minefield(16, 16, 40)));
            }

            pack();
        }

        topTimer.setText((time) + " Seconds   ");
    }

    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                new MinesweeperFrame().setVisible(true);
            }
        });
    }
}

@@ -2184,35 +2184,54 @@
                 
-if(
+Minefield minefield = 
 minePanel.getMin
@@ -2242,139 +2242,119 @@
 ld()
-.getGameState() == GameState.RUNNING)%0A                %7B%0A                    topResetBtn.setIcon(new ImageIcon(Images.FACE_NORMAL));
+;%0A%0A                if (minefield.isFinished())%0A                %7B%0A                    // Stop timer and set icon
 %0A   
@@ -2387,15 +2387,15 @@
 r.st
-art
+op
 ();%0A
+%0A
     
@@ -2410,129 +2410,135 @@
     
-%7D%0A
     
-            else%0A                %7B%0A                    if(minePanel.getMinefield().getGameState() == GameState.
+if (minefield.getGameState() == GameState.WON)%0A                        topResetBtn.setIcon(new ImageIcon(Images.FACE_
 WON)
+);
 %0A   
@@ -2546,33 +2546,36 @@
                 
-%7B
+else
 %0A               
@@ -2625,35 +2625,32 @@
 Images.FACE_
-WON));%0A    
+LOST));%0A
             
@@ -2675,106 +2675,108 @@
     
-    else if (minePanel.getMinefield().getGameState() == GameState.LOST)%0A                    %7B%0A    
+else%0A                %7B%0A                    // Set normal face and start timer if we've just started%0A
     
@@ -2833,32 +2833,35 @@
 Images.FACE_
-LOST
+NORMAL
 ));%0A
+%0A
             
@@ -2860,34 +2860,86 @@
                 
-%7D%0A
+if (minefield.getGameState() == GameState.RUNNING)%0A   
                 
@@ -2934,32 +2934,33 @@
                 
+ 
 scoreTimer.stop(
@@ -2952,26 +2952,27 @@
 coreTimer.st
-op
+art
 ();%0A        
@@ -2973,32 +2973,33 @@
               %7D%0A
+%0A
                 

Fix the game state event so the right face is shown on restart