import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 *
 * Ein Fenster, um das Sudoku-Spiel darzustellen
 * Hier sollte nichts verändert werden.
 * @version Dezember 2020
 * @author Rainer Helfrich
 */

public class SudokuFrame extends JFrame {

    Point backtrackingPosition;
    int nextBacktrackIndex;
    JButton btnBacktrack;
    SudokuGitter dasSpiel;
    JLabel lblSackgasse;

    public SudokuFrame(SudokuGitter sp, SudokuFrame parent) { 

        super();
        backtrackingPosition = null;
        dasSpiel = sp;
        nextBacktrackIndex = -1;
        setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
        int frameWidth = 800; 
        int frameHeight = 900;
        setSize(frameWidth, frameHeight);

        if (parent != null)
        {
            parent.setEnabled(false);
            setLocation(parent.getX() + 20, parent.getY() + 20);
        }
        else
        {
            Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
            int x = (d.width - getSize().width) / 2;
            int y = (d.height - getSize().height) / 2;
            setLocation(x, y);
        }
        setTitle("Sudokus lösen");
        setResizable(false);
        Container cp = getContentPane();
        cp.setLayout(null);

        SudokuPanel sudokuPanel1 = new SudokuPanel(sp);
        sudokuPanel1.setBounds(8, 8, 720, 720);
        cp.add(sudokuPanel1);

        final JLabel lblGewonnen = new JLabel("Spiel gelöst");
        lblGewonnen.setBounds(220, 770, 400, 16);
        lblGewonnen.hide();
        cp.add(lblGewonnen);

        lblSackgasse = new JLabel("Spiel so nicht lösbar -> Backtracking nötig");
        lblSackgasse.setBounds(220, 770, 400, 16);
        lblSackgasse.setForeground(Color.RED);
        lblSackgasse.hide();
        cp.add(lblSackgasse);

        final JButton btnKandidatenListe = new JButton("Kandidatenmengen erstellen");
        final JButton btnEintrag = new JButton("Eintragen");
        final JButton btnAutomatisch = new JButton("Automatisch");
        btnAutomatisch.setBounds(8, 770, 200, 24);
        btnEintrag.setEnabled(false);
        btnBacktrack = new JButton("Backtracking-Schritt");
        btnBacktrack.setEnabled(false);
        btnKandidatenListe.setBounds(8, 740, 200, 24);

        AtomicBoolean bEintragungMoeglich = new AtomicBoolean(false);
        ActionListener alKandidaten = new ActionListener() { 
                public void actionPerformed(ActionEvent evt) { 
                    bEintragungMoeglich.set(sp.kandidatenMengenErstellen());
                    if (bEintragungMoeglich.get()) 
                    {
                        btnEintrag.setEnabled(true);
                    }
                    else // Fehler -> Zurückgehen
                    {
                        btnBacktrack.setEnabled(false);
                        btnAutomatisch.setEnabled(false);
                        lblSackgasse.show();
                    }
                    btnKandidatenListe.setEnabled(false);
                    sudokuPanel1.repaint();
                }
            };
        ActionListener alEintrag = new ActionListener() {
                public void actionPerformed(ActionEvent evt) {
                    bEintragungMoeglich.set(sp.eintragen());
                    if (bEintragungMoeglich.get()) // es war eine Eintragung möglich
                    {
                        btnKandidatenListe.setEnabled(true);
                    }
                    else // Man muss raten -> Backtracking
                    {
                        btnBacktrack.setEnabled(true);
                        btnAutomatisch.setEnabled(false);
                        backtrackingPosition = sp.getPositionVonKleinsterKandidatenmenge();
                        if (backtrackingPosition == null)
                        {
                            if (sp.istGeloest())
                            {
                                lblGewonnen.show();
                                btnBacktrack.setEnabled(false);
                                btnEintrag.setEnabled(false);
                            }
                            return;
                        }
                        Kandidatenmenge km = (Kandidatenmenge)sp.getEintrag(backtrackingPosition.x, backtrackingPosition.y);
                        nextBacktrackIndex = 0;
                        btnBacktrack.setText("Backtracking-Schritt 1 von " + km.anzahl());
                    }
                    btnEintrag.setEnabled(false);
                    sudokuPanel1.repaint();
                }
            };

        btnKandidatenListe.addActionListener(alKandidaten); 
        cp.add(btnKandidatenListe);
        cp.add(btnAutomatisch);

        btnEintrag.setBounds(220, 740, 200, 24);
        btnEintrag.addActionListener(alEintrag); 
        cp.add(btnEintrag);

        btnAutomatisch.addActionListener(new ActionListener() { 
                public void actionPerformed(ActionEvent evt) { 
                    if (btnEintrag.isEnabled())
                    {
                        alEintrag.actionPerformed(null);
                    }
                    while(true)
                    {
                        alKandidaten.actionPerformed(null);
                        if (!bEintragungMoeglich.get())
                        {
                            break;
                        }
                        alEintrag.actionPerformed(null);
                        if (!bEintragungMoeglich.get())
                        {
                            break;
                        }
                    }
                }
            });

        btnBacktrack.setBounds(220+212, 740, 200, 24);
        btnBacktrack.addActionListener(new ActionListener() { 
                public void actionPerformed(ActionEvent evt) { 
                    int versuch = ((Kandidatenmenge)sp.getEintrag(backtrackingPosition.x, backtrackingPosition.y)).alsArray()[nextBacktrackIndex];
                    SudokuGitter spNeu = sp.klonErzeugen(backtrackingPosition.x, backtrackingPosition.y, versuch);
                }
            }); 
        cp.add(btnBacktrack);

        addWindowListener(new WindowAdapter(){
                public void windowClosing(WindowEvent e){
                    if (parent != null)
                    {
                        parent.setEnabled(true);
                        parent.nextBacktrackStep();
                    }
                }
            });
        setVisible(true);
    } 

    private void nextBacktrackStep()
    {
        if (this.backtrackingPosition != null)
        {
            Kandidatenmenge km = (Kandidatenmenge)dasSpiel.getEintrag(backtrackingPosition.x, backtrackingPosition.y);
            nextBacktrackIndex++;
            if (nextBacktrackIndex >= km.anzahl())
            {
                btnBacktrack.setEnabled(false);
                btnBacktrack.setText("Backtracking-Schritt");
                lblSackgasse.show();
            }
            else
            {
                btnBacktrack.setText("Backtracking-Schritt "+(nextBacktrackIndex+1)+" von " + km.anzahl());
            }
        }

    }
} 
