
package zapoctak;

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;


class Mina extends JButton
{
    public boolean jetam;
    public boolean flag = false;
    public boolean odkryto = false;
    
    public Mina()
    {
        super();
    }
}

class Coord
{
    public int x = 0;
    public int y = 0;
    public Coord(int i, int j)
    {
        x = i;
        y = j;
    }
}

class Miny extends JFrame implements MouseListener, ActionListener
{
    static JPanel top;
    static JButton bvytvor;
    static JTextField tfpole;
    static JTextField tfmin;
    static Mina[][] pole;
    static JPanel ppole;
    
    static JMenuBar menubar;
    static JMenu menu;
    static JMenuItem konec;
    static JMenuItem reset;
    
    static int npole;
    static int nmin;
    static int flags = 0;
    
    static int odkryto = 0;
    
    public Miny()
    {
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setupGui();
    }
    
    void setupGui()
    {
        top = new JPanel();
        add(top);
        top.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
        top.setLayout(new BorderLayout());
        
        menubar = new JMenuBar();
        menu = new JMenu("Hra");
        konec = new JMenuItem("Vzdavam to");
        reset = new JMenuItem("Znovu");
        menu.add(konec);
        menu.add(reset);
        menubar.add(menu);
        setJMenuBar(menubar);
        
        reset.addActionListener(this);
        konec.addActionListener(this);
        
        JPanel controls = new JPanel();
        controls.setLayout(new FlowLayout());
        controls.add(new JLabel("Pole: "));
        tfpole = new JTextField("5");
        tfpole.setPreferredSize(new Dimension(100, tfpole.getPreferredSize().height));
        controls.add(tfpole);
        controls.add(new JLabel("Min: "));
        tfmin = new JTextField("5");
        tfmin.setPreferredSize(new Dimension(100, tfmin.getPreferredSize().height));
        controls.add(tfmin);
        bvytvor = new JButton("Vytvor");
        bvytvor.addActionListener(new Tvoric());
        controls.add(bvytvor);
        top.add(controls, BorderLayout.NORTH);

        pack();
    }
    
    public static void main(String[] args) {
            JFrame f = new Miny();
            f.setVisible(true);
    }

    private void flag(Coord z)
    {
        if (pole[z.x][z.y].odkryto)
            return;
        if (pole[z.x][z.y].flag)
        {
            pole[z.x][z.y].setText("");
            flags--;
        }
        else
        {   
            if (flags >= nmin)
                return;
            pole[z.x][z.y].setText("X");
            flags++;
        }
        pole[z.x][z.y].flag = !pole[z.x][z.y].flag;
    }

    private void konec()
    {
        if (ppole != null)
            top.remove(ppole);
        zased(false);
        flags = 0;
        odkryto = 0;
        pack();
    }

    private void vyhra()
    {
        JOptionPane.showMessageDialog(this, "Vyhral jsi!");
        konec();
    }

    class Tvoric implements ActionListener
    {        
        boolean validate()
        {
            try
            {
                //tfpole.setText("5");
                String s = tfpole.getText();
                String f = tfmin.getText();
                npole = Integer.parseInt(tfpole.getText().trim());
                nmin = Integer.parseInt(tfmin.getText().trim());
            }
            catch (NumberFormatException numberFormatException)
            {
                JOptionPane.showMessageDialog(top, "V nastaveni nejsou cisla!");
                return false;
            }
            if (npole < 2 || npole > 10)
            {
                JOptionPane.showMessageDialog(top, "Pole musi byt >1 a <11!");
                return false;
            }
            if (nmin > npole*npole-1)
            {
                JOptionPane.showMessageDialog(top, "Prilis mnoho min!");
                return false;
            }
            return true;
        }
        
        public void actionPerformed(ActionEvent e)
        {
            if (!validate())
                return;
            zased(true);

            ppole = new JPanel();
            ppole.setPreferredSize(new Dimension(300, 300));
            top.add(ppole, BorderLayout.CENTER);
            
            ppole.setLayout(new GridLayout(npole, npole));
            pole = new Mina[npole][npole];
            
            for (int x = 0; x < npole; ++x)
            //for (JButton[] bf : pole)
            {
                //for (JButton b : bf)
                for (int y = 0; y < npole; ++y)
                {
                    Mina b = new Mina();
                    //b.addActionListener(Miny.this);
                    b.addMouseListener(Miny.this);
                    pole[x][y] = b;
                    ppole.add(b);
                }
            }
            
            polozMiny();
            pack();
        }
        
        void polozMiny()
        { 
            int polozeno = 0;
            while (polozeno < nmin)
            {
                 Random rng = new Random();
                 int x = rng.nextInt(npole);
                 int y = rng.nextInt(npole);
                 if (pole[x][y].jetam)
                     continue;
                 pole[x][y].jetam = true;
                 ++polozeno;
            }
        }
    }
    
    void zased(boolean jo)
    {
        tfpole.setEnabled(!jo);
        tfmin.setEnabled(!jo);
        bvytvor.setEnabled(!jo);
    }
    
    void bum()
    {
        JOptionPane.showMessageDialog(this, "Vybouchnul jsi!");
        konec();
    }
    
    void odkryj(Coord z)
    {
        int x = z.x;
        int y = z.y;
        if (pole[z.x][z.y].flag)
           return;
        if (pole[x][y].jetam)
        {
            bum();
            return;
        }
        pole[x][y].setEnabled(false);
        pole[x][y].odkryto = true;
        
        Integer vokoli = 0;
        for (int i = -1; i < 2; ++i)
            for (int j = -1; j < 2; ++j)
            {
                if (x + i >= 0 && x + i < npole && y + j >= 0 && y + j < npole)
                {
                    if (pole[x+i][y+j].jetam)
                        ++vokoli;
                }
            }
        
        if (vokoli == 0)
        {
            for (int i = -1; i < 2; ++i)
                for (int j = -1; j < 2; ++j)
                {
                    if (x + i >= 0 && x + i < npole && y + j >= 0 && y + j < npole &&
                            !(i == 0 && j == 0) && !pole[x+i][y+j].odkryto)
                        odkryj(new Coord(x+i,y+j));
                }
        }
        odkryto++;
        
        pole[x][y].setText(vokoli.toString());
    }
    
    // zjisti souradnice policka ktere vyvolalo event
    Coord getSource(EventObject z)
    {
        for (int x = 0; x < npole; ++x)
            for (int y = 0; y < npole; ++y)
            {
                if (pole[x][y] == z.getSource())
                {
                    return new Coord(x, y);
                }
            }
        assert(false);
        return new Coord(0,0);
    }
    
    public void mouseClicked(MouseEvent e)
    {
        System.out.println(e.getClickCount());
        Coord z = getSource(e);
        if (e.getButton() == MouseEvent.BUTTON3 || (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() >= 2))
            flag(z);
        else
        {
            odkryj(z);
            if (npole * npole == odkryto + nmin)
                vyhra();
        }
        int y = 0;
    }

    public void mousePressed(MouseEvent e)
    {
    }

    public void mouseReleased(MouseEvent e)
    {
    }

    public void mouseEntered(MouseEvent e)
    {
    }

    public void mouseExited(MouseEvent e)
    {
    }

    public void actionPerformed(ActionEvent e)
    {
        if (e.getSource() == konec)
        {
            System.exit(0);
        }
        else if (e.getSource() == reset)
        {
            konec();
        }
    }
}