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

// Wie oft versucht wird, ein Wort zufällig zu platzieren
#define MAX_RAND_TRIES_PER_WORD 10
// Kennzeichen für leere Felder (wird später durch Buchstaben ersetzt)
#define EMPTY_CHAR 0

// Richtungen für das Platzieren der Wörter
typedef enum { HORIZONTAL = 0, VERTICAL = 1 } Direction;

// Gibt einen zufälligen Großbuchstaben A–Z zurück
static char randomLetter(void) {
    return 'A' + (rand() % 26);
}

// Prüft, ob ein Wort an der gegebenen Position und Richtung ins Spielfeld passt
static int canPlace(const char field[][MAX_SEARCH_FIELD_LEN], unsigned int fieldSize,
                    const char *word, unsigned int row, unsigned int col, Direction dir) {

    int length = strlen(word);

    if (dir == HORIZONTAL) {
        if (col + length > fieldSize) return 0;  // würde rechts rausgehen
        for (int i = 0; i < length; i++) {
            char current = field[row][col + i];
            if (current != EMPTY_CHAR && current != word[i])
                return 0;  // Kollision mit anderem Wort
        }
    } else { // VERTICAL
        if (row + length > fieldSize) return 0;  // würde unten rausgehen
        for (int i = 0; i < length; i++) {
            char current = field[row + i][col];
            if (current != EMPTY_CHAR && current != word[i])
                return 0;
        }
    }
    return 1; // Platz ist frei
}

// Schreibt ein Wort tatsächlich ins Spielfeld
static void placeWord(char field[][MAX_SEARCH_FIELD_LEN], const char *word,
                      unsigned int row, unsigned int col, Direction dir) {

    int length = strlen(word);

    if (dir == HORIZONTAL) {
        for (int i = 0; i < length; i++)
            field[row][col + i] = word[i];
    } else {
        for (int i = 0; i < length; i++)
            field[row + i][col] = word[i];
    }
}

// Hauptfunktion: erstellt das Buchstabenfeld mit den versteckten Wörtern
int createWordSalad(char field[MAX_SEARCH_FIELD_LEN][MAX_SEARCH_FIELD_LEN],
                    unsigned int fieldSize, const char words[][MAX_WORD_LEN], unsigned int wordCount)
{
    srand((unsigned)time(NULL)); // Zufallsstartwert setzen

    // 1) Feld "leer" 
    for (unsigned int r = 0; r < fieldSize; r++) {
        for (unsigned int c = 0; c < fieldSize; c++) {
            field[r][c] = EMPTY_CHAR;
        }
    }

    // 2) Wörter zufällig platzieren
    int placedWords = 0;

    for (unsigned int w = 0; w < wordCount; w++) {
        const char *word = words[w];
        if (!word || word[0] == '\0') continue; // leere Zeilen überspringen

        int placed = 0;
        for (int tries = 0; tries < MAX_RAND_TRIES_PER_WORD && !placed; tries++) {
            Direction dir = (rand() % 2 == 0) ? HORIZONTAL : VERTICAL;
            unsigned int row = rand() % fieldSize;
            unsigned int col = rand() % fieldSize;

            if (canPlace(field, fieldSize, word, row, col, dir)) {
                placeWord(field, word, row, col, dir);
                placedWords++;
                placed = 1;
            }
        }
    }

    // 3) Leere Felder mit Zufallsbuchstaben füllen
    for (unsigned int r = 0; r < fieldSize; r++) {
        for (unsigned int c = 0; c < fieldSize; c++) {
            if (field[r][c] == EMPTY_CHAR)
                field[r][c] = randomLetter();
        }
    }

    return placedWords;
}

// Gibt das Spielfeld auf der Konsole aus
void showWordSalad(const char field[MAX_SEARCH_FIELD_LEN][MAX_SEARCH_FIELD_LEN], unsigned int fieldSize)
{
    for (unsigned int r = 0; r < fieldSize; r++) {
        for (unsigned int c = 0; c < fieldSize; c++) {
            printf("%c ", field[r][c]);
        }
        printf("\n");
    }
}