// Die Gui-Klasse für Sudoku
// In dieser Klasse ist die GUI-Logik, aber nicht die Lösungslogik
// Klaus Kusche, 2010

#ifndef SUDOKU_H
#define SUDOKU_H

#include <wx/frame.h>
#include <wx/event.h>
#include <wx/grid.h>
#include <wx/button.h>
#include <wx/checkbox.h>
#include <wx/thread.h>

// Anzahl der Zeilen / Spalten
#define NUM_COL 9
// Anzahl der Spielfelder
// Die Spielfelder sind zeilenweise von 0 bis (NUM_POS - 1) durchnummeriert
#define NUM_POS (NUM_COL * NUM_COL)

class Sudoku final : public wxFrame, public wxThreadHelper
{
public:
  Sudoku();

  // Die Methoden des GUI, die der Lösungscode aufruft:
  //
  // lies die vorbelegte Zahl im Feld pos
  // 0 wenn das Feld nicht vorbelegt ist
  int GetValue(int pos);
  // setze die Zahl, die im Feld pos angezeigt wird
  // Returnwert: 0 ... weitermachen, 1 ... aufhören
  int SetValue(int pos, int val);
  // setze das Feld pos auf leer
  // Returnwert: 0 ... weitermachen, 1 ... aufhören
  int ResetValue(int pos);
  // n-te Lösung gefunden! ==> Zeige Lösung an
  // Returnwert: 0 ... weitermachen, 1 ... aufhören
  int Solution(int n);

protected:
  // Main-Funktion des Solver-Threads
  virtual wxThread::ExitCode Entry();
  
private:
  // Event-Handler für Button Clicks  
  void OnGo(wxCommandEvent &event);
  void OnCont(wxCommandEvent &event);
  void OnStop(wxCommandEvent &event);
  void OnBack(wxCommandEvent &event);
  void OnClear(wxCommandEvent &event);
  void OnAbout(wxCommandEvent &event);
  void OnQuit(wxCommandEvent &event);

  // Event-Handler für Thread Messages
  void OnUpdate(wxThreadEvent &event);
  void OnSolution(wxThreadEvent &event);
  void OnThreadEnd(wxThreadEvent &event);

  // Event-Handler für Zeitlupe-Checkbox
  void OnSloMo(wxCommandEvent &event);

  // Event-Handler für Close des Hauptfensters
  void OnClose(wxCloseEvent &event);

  // curVals anzeigen
  void RefreshGrid();

  // das Grid der Zahlen
  wxGrid *grid;

  // Die Buttons
  wxButton *goButton, *contButton, *stopButton,
    *backButton, *clearButton, *aboutButton, *quitButton;
  // Checkbox: Zeitlupe oder volle Geschwindigkeit?
  wxCheckBox *slowMotionBox;

  // Eine Kopie der Werte beim letzten Start
  int startVals[NUM_POS];
  // Die aktuellen Werte
  int curVals[NUM_POS];

  // Existiert der Worker-Thread?
  bool running;
  // Wurde der Thread mit dem Stop-Button abgebrochen?
  bool killed;
  // Wird gerade in Zeitlupe angezeigt?
  bool sloMo;
};

#endif
