// Arup Guha
// 5/29/2020
// Code for Summer 2020 COP 3502 Section 17 Quiz

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

#include "leak_detector_c.h"

// Dummy struct to show viability of question #2.
typedef struct sodacan {
    int oz;
} sodacan;

// Struct for Part B.
typedef struct charnode {
    char c;
    struct charnode* next;
} charnode;

int stringvalue(charnode* front);
charnode* makeLinkedList(char* word);
int countChar(charnode* front, char mych);
void freeList(charnode* ptr);
void printString(charnode* ptr);

int main(void) {

    // So we can get the leak detector report.
    atexit(report_mem_leak);

    // Part A Question #1
    int n;
    scanf("%d", &n);
    float* array = calloc(n, sizeof(float));

    // Test to see array set to 0.
    for (int i=0; i<n; i++)
        printf("%.1f ", array[i]);
    printf("\n");

    // Free this memory.
    free(array);

    // Part A Question #2 Given mallocs.
    int* ptrN;
    ptrN = malloc(sizeof(int));
    scanf("%d", ptrN);
    sodacan** cans = malloc((*ptrN)*sizeof(sodacan*));

    for (int i=0; i<(*ptrN); i++)
        cans[i] = malloc(sizeof(sodacan));

    // Part A Question #2 Solution - can be verified using leak detector.

    // First free each 1D array of cans.
    for (int i=0; i<(*ptrN); i++)
        free(cans[i]);

    // Now, free the cans array.
    free(cans);

    // Finally free the single int this pointer was pointing to.
    free(ptrN);

    /*** Part B tests starts here. ***/
    charnode* teststr = makeLinkedList("hello");
    printf("Value of string is %d\n", stringvalue(teststr));
    printf("String has %d l's.\n", countChar(teststr, 'l'));
    freeList(teststr);
    return 0;
}

// Solution to Part B Question #1
int stringvalue(charnode* front) {

    // Store answer here.
    int res = 0;

    // Iterate through list.
    while (front != NULL) {

        // Just add the value of this character.
        res += (front->c);

        // Hop to next node.
        front = front->next;
    }

    // This is our result.
    return res;
}

// Support code to test Part B questions
charnode* makeLinkedList(char* word) {

    int i = 0;

    // This is our list initially.
    charnode* front = NULL;
    charnode* back = NULL;

    // Go till null char.
    while (word[i] != '\0') {

        // Make the new node.
        charnode* tmp = malloc(sizeof(charnode));
        tmp->c = word[i];
        tmp->next = NULL;

        // All we have to do for first item.
        if (i == 0) {
            front = tmp;
            back = tmp;
        }

        // Patch old back to new back and update back.
        else {
            back->next = tmp;
            back = tmp;
        }

        // Go to next character in the word.
        i++;
    }

    // This is our pointer.
    return front;
}

// Solution to Part B Question #2
int countChar(charnode* front, char mych) {

    // Store answer here.
    int res = 0;

    // Go through whole list.
    while (front != NULL) {

        // Add 1 if this is the character we are looking for.
        if (front->c == mych)
            res++;

        // Go to next character.
        front = front->next;
    }

    // Value to return.
    return res;
}

// Frees all the memory for the linked list pointed to by ptr.
void freeList(charnode* ptr) {
    if (ptr != NULL) {
        freeList(ptr->next);
        free(ptr);
    }
}

void printString(charnode* ptr) {
    while (ptr != NULL) {
        printf("%c", ptr->c);
        ptr = ptr->next;
    }
    printf("\n");
}
