#include "game.h"
#include <time.h>
#include <stdlib.h>
#include <string.h>

#define MAX_RAND_TRIES_PER_WORD 10
#define EMPTY_CHAR 0

 //Position beinhaltet x, y und Richtung
//TODO: Spiellogik implementieren:
/* * Wörter aus der Wortliste zufällig horizontal oder vertikal platzieren
   * restliche Felder mit zufälligen Buchstaben füllen */

// Creates the word salad by placing words randomly and filling empty spaces
int createWordSalad(char salad[MAX_SEARCH_FIELD_LEN][MAX_SEARCH_FIELD_LEN], unsigned int searchFieldLen, const char words[][MAX_WORD_LEN], unsigned int wordCount)
{
   srand(time(NULL));
   Position position[(2 * MAX_SEARCH_FIELD_LEN * (MAX_SEARCH_FIELD_LEN - MIN_WORD_LEN + 1))]; //Positionsarray Größe: Formel max. nötige Größe (für minimal großes wort)
   int gesetzteWörter = 0;
   clearWordSalad(salad, searchFieldLen);
   gesetzteWörter = fuelleSalatMitWörtern(salad, searchFieldLen, words, position, wordCount);
   fillWordsaladRand(salad, searchFieldLen);
   return gesetzteWörter;
}

// Prints the word salad to console
void showWordSalad(const char salad[MAX_SEARCH_FIELD_LEN][MAX_SEARCH_FIELD_LEN], unsigned int searchFieldLen)
{
   for(int i = 0; i < searchFieldLen; i++)
   {
      for(int k = 0; k < searchFieldLen; k++)
      {
         printf("%c", salad[i][k]);
      }
      printf("\n");
   }

}
//Logik für createWordSalad: Ein Wort nach dem anderen bis entweder alle Wörter drinnen, 
//Funktion dafür den gesammten Salat mit . zu befüllen.
void clearWordSalad(char salad[MAX_SEARCH_FIELD_LEN][MAX_SEARCH_FIELD_LEN], unsigned int searchFieldLen)
{
   for(unsigned int zeile = 0; zeile < searchFieldLen; zeile++)
   {
      for(unsigned int spalte = 0; spalte < searchFieldLen; spalte++)
      {
         salad[zeile][spalte] = '.'; // salad wird mit Punkten befüllt.
      }
   }
}
//Funktion für den Schluss: Übrige leere stellen werden random befüllt.
void fillWordsaladRand(char salad[MAX_SEARCH_FIELD_LEN][MAX_SEARCH_FIELD_LEN], unsigned int searchFieldLen)
{
   for(int i = 0; i < searchFieldLen; i++)
   {
      for(int k = 0; k < searchFieldLen; k++)
      {
         if(salad[i][k] == '.')
         {
            salad[i][k] = 'A' + rand() % 26;
         }
      }
   }
}
//hierbei: alle Positionen werden zunächst geprüft ob leer (.) danach wird nach rechts und nach unten geschaut ob:
//a.) genügend Platz wäre, dass nicht aus dem array herausgeschrieben wird und
//b.) alle zu besetzenden Felder leer sind (.).
//Positionamount gibt aus wie viele mögliche Positionen es für dieses Wort gibt. 
//Wird mit 0 initialisiert. Wenns null bleibt, bedeutet dies es gibt keine verfügbaren Positionen.
int findPossiblePositions(char salad[MAX_SEARCH_FIELD_LEN][MAX_SEARCH_FIELD_LEN], unsigned int searchFieldLen, const char words[][MAX_WORD_LEN],  int wordidx, Position positions[])
{
   const char *word = words[wordidx];
   int wordlen = strlen(word);
   int positionamount = 0;
   int rechtsfrei = 1;
   int untenfrei = 1;
   for(int i = 0; i < searchFieldLen; i++)
   {
      for(int k = 0; k < searchFieldLen; k++)
      {
         rechtsfrei = 1;
         untenfrei = 1;
         if(salad[i][k] == '.')
         {
            //nach rechts prüfen
            if(searchFieldLen - k >= wordlen)
            {
               for(int p = k +1; p < k+ wordlen; p++)
               {
                  if(salad[i][p] != '.')
                  {
                     rechtsfrei = 0;
                     break;
                  }
               }

            }
            //nach unten prüfen
            if(searchFieldLen - i >= wordlen)
            {
               for(int q = i+1; q < i+ wordlen; q++)
               {
                  if(salad[q][k] != '.')
                  {
                     untenfrei = 0;
                     break;
                  }
               }
            }
            if(rechtsfrei) //Positions array wird mit gültigen Positionen und Richtung befüllt.
            {
               positions[positionamount].x = k;
               positions[positionamount].y = i;
               positions[positionamount].richtung = RECHTS;
               positionamount++;
            }
            if(untenfrei)
            {
               positions[positionamount].x = k;
               positions[positionamount].y = i;
               positions[positionamount].richtung = UNTEN;
               positionamount++;
            }
         }
      }
   }

   return positionamount;

}

//Nun muss für jedes Wort per zufall ausgesucht werden Wo es beginnt und welche richtung aus 
//den ganzen möglichen fällen und dann das wort ins grid gezeichnet werden.
int fuelleSalatMitWörtern(char salad[MAX_SEARCH_FIELD_LEN][MAX_SEARCH_FIELD_LEN], unsigned int searchFieldLen, const char words[][MAX_WORD_LEN], Position position[], unsigned int wordcount)
{
   int gesetzteWörter = 0;
   int positionsamount;
   int positiongewählt;
   const char *word;
   for(int i = 0; i < wordcount; i++) //jedes Wort.
   {
      positionsamount = findPossiblePositions(salad, searchFieldLen, words, i, position); //für dieses Wort werden die Positionen gefunden
      if(positionsamount > 0)//es gibt Positionen
      {
         gesetzteWörter++;
         positiongewählt = rand() % positionsamount; //die wie vielte Position des Positionsarrays für dieses Wort wir nehmen
         if(position[positiongewählt].richtung == RECHTS)
         {
            word = words[i];
            int p = position[positiongewählt].x;
            int t = 0;
            for(int k = p; k < p + strlen(word); k++)
            {
               salad[position[positiongewählt].y][k] = word[t];
               t++;
            }
         }
         if(position[positiongewählt].richtung == UNTEN)
         {
            word = words[i];
            int up = position[positiongewählt].y;
            int ut = 0;
            for(int uk = up; uk < up +strlen(word); uk++)
            {
               salad[uk][position[positiongewählt].x] = word[ut];
               ut++;
            }
         }
      }
   }
   return gesetzteWörter;

}