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

#define MAX_RAND_TRIES_PER_WORD 10
#define EMPTY_CHAR 0
#define MAX_NUMBER_OF_WORDS 100

//TODO: Spiellogik implementieren:
/* * Wörter aus der Wortliste zufällig horizontal oder vertikal platzieren
   * restliche Felder mit zufälligen Buchstaben füllen */

//words und salad sind char arrays --> laengstes wort sind 100 zeichen 

// 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)
{
   int placedWords = 0;
   srand(time(NULL));

   int usedWords[MAX_NUMBER_OF_WORDS];
   for(int i=0; i< MAX_NUMBER_OF_WORDS; i++){
      usedWords[i] = -1;
   }
   
   placedWords = fillSalad(salad, searchFieldLen, words, wordCount, usedWords);
   showWordSalad(salad);
   printf("\nPlacedWords: %d\n", placedWords);
   return placedWords;

}

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

// Decides wether to print horizontally or vertically
// returns 1, when horizontal
int printHorizontal()
{
   return rand() % 2;
}

// checks wether after all words are filled, empty spaces are left
// returns 1, when empty spaces are left
int emptyPlaces(unsigned int wordCount)
{
   if(wordCount < MAX_NUMBER_OF_WORDS)
   {
      return 1;
   }
   return 0;
}


// fills salad array with max. words from word array either horizontally or vertically
int fillSalad(char salad[MAX_SEARCH_FIELD_LEN][MAX_SEARCH_FIELD_LEN], unsigned int searchFieldLen, const char words[][MAX_WORD_LEN], unsigned int wordCount, int usedWords[MAX_NUMBER_OF_WORDS])
{
  int addedWords = 0;
    // empties salad
    for(unsigned int i = 0; i < MAX_SEARCH_FIELD_LEN; i++) {
        for(unsigned int j = 0; j < MAX_SEARCH_FIELD_LEN; j++) {
            salad[i][j] = '\0';
        }
    }

    // inserts words
    for(unsigned int w = 0; w < wordCount; w++) {
        int tries = 0;
        int placed = 0;

        while(tries < MAX_RAND_TRIES_PER_WORD && !placed) {
            int numWord = whichWord(wordCount, usedWords);
            if(numWord == -5) {
                // found no unused word
                break;
            }

            int horizontal = printHorizontal();

            if(horizontal) {
                int row = rand() % searchFieldLen;
                // checks if words fits 
                unsigned int wordLen = strlen(words[numWord]);
                if(wordLen <= searchFieldLen) {
                    int startCol = rand() % (searchFieldLen - wordLen + 1);
                    int canPlace = 1;
                    for(unsigned int i = 0; i < wordLen; i++) { //checks if word fits
                        if(salad[row][startCol + i] != '\0') {
                            canPlace = 0;
                            break;
                        }
                    }
                    if(canPlace) { //word fits and is inserted
                        for(unsigned int i = 0; i < wordLen; i++) {
                            salad[row][startCol + i] = words[numWord][i];
                        }
                        placed = 1;
                        addedWords++;
                    }
                }
            } else {
                // vertically
                int col = rand() % searchFieldLen;
                unsigned int wordLen = strlen(words[numWord]);
                if(wordLen <= searchFieldLen) {
                    int startRow = rand() % (searchFieldLen - wordLen + 1);
                    int canPlace = 1;
                    for(unsigned int i = 0; i < wordLen; i++) {
                        if(salad[startRow + i][col] != '\0') {
                            canPlace = 0;
                            break;
                        }
                    }
                    if(canPlace) {
                        for(unsigned int i = 0; i < wordLen; i++) {
                            salad[startRow + i][col] = words[numWord][i];
                        }
                        placed = 1;
                        addedWords++;
                    }
                }
            }

            tries++;
        }
    }
    fillRandom(salad);
    return addedWords;
}


int whichWord(unsigned int wordCount, int usedWords[MAX_NUMBER_OF_WORDS])
{
    int tries = 0;

    while(tries < MAX_RAND_TRIES_PER_WORD) {
        int numWord = rand() % wordCount; // 0..wordCount-1

        int alreadyUsed = 0;
        for(int f = 0; f < MAX_NUMBER_OF_WORDS; f++){
            if(usedWords[f] == numWord){
                alreadyUsed = 1;
                break; // word already used
            }
        }

        if(!alreadyUsed){
            // Eintragen in usedWords
            for(int f = 0; f < MAX_NUMBER_OF_WORDS; f++){
                if(usedWords[f] == -1){ // unused
                    usedWords[f] = numWord;
                    break;
                }
            }
            return numWord; // unused row found
        }

        tries++;
    }

    return -5; 
}




//Fills word in salad and deletes row of words of the used word
void fillWordinRow(char salad[MAX_SEARCH_FIELD_LEN][MAX_SEARCH_FIELD_LEN],unsigned int searchFieldLen,const char words[][MAX_WORD_LEN], int numWord,int row)
{
    unsigned int wordLen = strlen(words[numWord]);

    // Returns if word longer than game field
    if (wordLen > searchFieldLen || wordLen == 0)
        return;

    // Determines random starting point in the row to place word
    int startCol = rand() % (searchFieldLen - wordLen + 1);

    // Determines wether word fits
    for (unsigned int i = 0; i < wordLen; i++)
    {
      if (salad[row][startCol + i] != '\0')
      {
        return; 
      }
    }
    for (unsigned int i = 0; i < wordLen; i++)
    {
      salad[row][startCol + i] = words[numWord][i];
    }
}


//Fills word in salad and deletes row of words of the used word, vertical from top to bottom
void fillWordinColumn(char salad[MAX_SEARCH_FIELD_LEN][MAX_SEARCH_FIELD_LEN], unsigned int searchFieldLen, const char words[][MAX_WORD_LEN], int numWord, int column)
{
  unsigned int wordLen = strlen(words[numWord]);

    if (wordLen > searchFieldLen || wordLen == 0)
      return;

    int startRow = rand() % (searchFieldLen - wordLen + 1);

    for (unsigned int i = 0; i < wordLen; i++)
    {
      if (salad[startRow + i][column] != '\0') 
      {
         return; 
      }
    }

    for (unsigned int i = 0; i < wordLen; i++)
    {
      salad[startRow + i][column] = words[numWord][i];
    }
}


// if emptyPlaces, fill these with random letters
void fillRandom(char salad[MAX_SEARCH_FIELD_LEN][MAX_SEARCH_FIELD_LEN]) {
    for (int j = 0; j < MAX_SEARCH_FIELD_LEN; j++) {
        for (int h = 0; h < MAX_SEARCH_FIELD_LEN; h++) {
            if (salad[j][h] == '\0') {
                char letter = 'A' + rand() % 26; // 0–25 → 'A'–'Z'
                salad[j][h] = letter;
            }
        }
    }
}
