#include <stdio.h>

#include <iostream>

// #include <string>  // es: string blabla; cin >> blabla;

#include "sudoku2lib.h"

using namespace std;

int TestID = 1;

int livelloAnnidamento = 1; // spostare quanto più possibile nel main

type_esitoTest esito[TESTS_TO_RUN] /* = {UNKNOWN} */;

int main()

{

  int ReturnValue = UNKNOWN;

  type_tavola tab;

  type_tavola tabSol;

  #if (!DEBUGGING)

  int i = 1;

  int j = 1;

  #endif

  cout << "    Algoritmo di risoluzione del SUDOKU        \n" << endl;

  cout << "Ingegneria fisica - Politecnico di Milano      " << endl;

  cout << "     Informatica A - Prof. Sam Guinea\n        " << endl;

  cout << "      (2) Dott. Mag. Ing. Antonio Indirli      " << endl;

  cout << "               Embedded SW Dev.                " << endl;

  cout << "                 Alten ITALIA                   \n\n\n" << endl;

  for (TestID = 1; TestID <= TESTS_TO_RUN; TestID++)

  {

   #if (DEBUGGING)

   InitTest(&tab[0][0], SVUOTA_SI, TestID);

   #else // No Debugging

   /**********************************************/

   /*       Inserimento dei valori - BEGIN       */

   /**********************************************/

   cout << "Inserire valori noti (0 se non si conosce).\n\n" << endl;

   for (i = 1; i <= 9; i++) {

     cout << " RIGA " << i << endl;

     for (j = 1; j <= 9; j++) {

       do {

         cout << "(" << i << ":" << j << ")= ";

         cin >> tab[i][j].num;                               // Non sono sicuro se serve passargli l'indirizzo, credo di sì in realtà!!

         if ((tab[i][j].num >= 1) && (tab[i][j].num <= 9))   // Da 1 a 9, il valore è certo

           tab[i][j].status = FOUND;

         else

           tab[i][j].status = EMPTY;

       } while ((tab[i][j].num < 0) || (tab[i][j].num > 9)); // Sotto 0 e sopra 9, ciclo da rifare

       if ((j % 3) == 0)

         cout << endl;

     }

     cout << endl;

   }

   /********************************************/

   /*       Inserimento dei valori - END       */

   /********************************************/

   #endif

   #if (DEBUGGING)

   cout << "Test numero "<< TestID << ". ";

   #endif

   cout << "I valori inseriti sono:\n" << endl;

   mostra_numeri_status(tab);

   #if (!DEBUGGING)

   cout << "\nPremi un tasto per continuare.\n" << endl;

   fflush(stdin);

   getchar();

   /**********************************************************/

   /*       Controllo della validità  dei dati immessi       */

   /**********************************************************/

   if (soluzione_valida(tab) == ERRORE)

   {

     cout << "I dati inseriti contengono errori; il programma verrà terminato." << endl;

     fflush(stdin);

     getchar();

     return ERRORE;

   }

   #endif

   /************************************/

   /*       Cuore dell'algoritmo       */

   /************************************/

   cout << "\nInizio della risoluzione..." << endl;

   esito[TestID - 1].result = risolvi(tab);

   cout << "Risoluzione terminata.\n\n\n\n" << endl;

   // Carico la vera soluzione del test TestID nella tavola tab_soluzione

   InitTest(&tabSol[0][0], SVUOTA_NO, TestID);

   esito[TestID - 1].match = confronta_tabelle(&tab[0][0], &tabSol[0][0]);

  } // End of for (TestID = 1; TestID <= TESTS_TO_RUN; TestID++)

  /***************************/

  /*       Conclusioni       */

  /***************************/

  for (TestID = 1; TestID <= TESTS_TO_RUN; TestID++) // Se il debugging è disattivato, si tratta di un solo test

  {

   #if (DEBUGGING)

   if (esito[TestID - 1].result == FOUND)

     {

     cout << "Test " << TestID << ": ";

     if (esito[TestID - 1].match)

       cout << STRING_OK << endl;

     else

       cout << STRING_NOT_OK << endl;

     StampaTentativi(esito[TestID - 1]);

     cout << endl;

   }

   else

   {

     cout << "La soluzione per il test " << TestID << " non è stata trovata." << endl;

     StampaTentativi(esito[TestID - 1]);

   }

   #else // No Debugging

   if (esito[TestID - 1].result == FOUND)

   {

     cout << "La soluzione è stata trovata!" << endl;

     cout << "Premi un tasto per visualizzare la soluzione." << endl;

     getchar();

     fflush(stdin);

     mostra_numeri_status(tab);

     StampaTentativi(esito[TestID - 1]);

     getchar();

   }

   else

   {

     cout << "Soluzione non trovata, mi dispiace!!!" << endl; // Il programma non dovrebbe mai visualizzare questa dicitura

     StampaTentativi(esito[TestID - 1]);

     getchar();

   }

   #endif

  } // End of for (TestID = 1; TestID <= TESTS_TO_RUN; TestID++)

  ReturnValue = calcola_esito_TOT(esito);

  if (ReturnValue == FOUND)

  {

   cout << "\n/********************************/"     << endl;

   cout <<   "/********************************/"     << endl;

   cout <<   "/*       !!! ALLES OK !!!       */"     << endl;

   cout <<   "/********************************/"     << endl;

   cout <<   "/********************************/\n\n" << endl;

  }

  else

  {

   cout << "\n/******************************/"     << endl;

   cout <<   "/******************************/"     << endl;

   cout <<   "/*       !!! FEHLER !!!       */"     << endl;

   cout <<   "/******************************/"     << endl;

   cout <<   "/******************************/\n\n" << endl;

  }

  return ReturnValue;

}