// Arup Guha
// 4/25/2024
// Solution to Spring 2024 COP 3502H Final Exam Question 3

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct player {
    char name[10];
    int jersey;
};

// Function prototypes.
char* makeName(int n);
struct player*** makeTeamsSpace(int* teamsizes, int numteams);
void print(const struct player* ptr);

int main(void) {

    // Just a spaced out array of sizes.
    int* arr = calloc(5, sizeof(int));
    for (int i=0; i<5; i++)
        arr[i] = (7+4*i)%13;

    // Make the space here.
    struct player*** teams = makeTeamsSpace(arr, 5);

    int id = 1;

    // Fill up the teams.
    for (int i=0; i<5; i++) {
        for (int j=0; j<arr[i]; j++) {
            char* tmp = makeName(id);
            strcpy(teams[i][j]->name, tmp);
            teams[i][j]->jersey = 100*i+id;
            id++;
        }
    }

    // Print each player.
    for (int i=0; i<5; i++) {
        printf("Team %d\n", i);
        for (int j=0; j<arr[i]; j++)
            print(teams[i][j]);
        printf("------------------------\n");
    }

    // Every malloc gets an equal and opposite free!
    for (int i=0; i<5; i++) {
        for (int j=0; j<arr[i]; j++)
            free(teams[i][j]);
        free(teams[i]);
    }
    free(teams);

    return 0;
}

// Prints the struct pointed to by ptr.
void print(const struct player* ptr) {
    printf("%s %d\n", ptr->name, ptr->jersey);
}

// I make a custom name out of the integer n. n < 100000 is required.
char* makeName(int n) {
    char* res = malloc(10*sizeof(char));
    res[0] = 'p'; res[1] = 'l'; res[2]='y'; res[3] = 'r';
    int i = 4;
    while (n>0) {
        res[i++] = (char)('0'+n%10);
        n = n/10;
    }
    res[i] = '\0';
    return res;
}

// Here is the answer to the question.
struct player*** makeTeamsSpace(int* teamsizes, int numteams) {

    // Top level malloc for numteams struct player**'s
    struct player*** res = malloc(numteams*sizeof(struct player**));

    // Go through each team.
    for (int i=0; i<numteams; i++) {

        // Here is the array of pointers for team i.
        res[i] = malloc(teamsizes[i]*sizeof(struct player*));

        // Now, go through each player.
        for (int j=0; j<teamsizes[i]; j++)

            // We just want this pointer pointing to a single struct.
            res[i][j] = malloc(sizeof(struct player));
    }

    // Ta da!
    return res;
}
