/* A simple demonstration of the Student structure with arrays */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>


#define MAX_ID_LENGTH   10
#define MAX_NAME_LENGTH 50


typedef struct student
{
    char id[MAX_ID_LENGTH + 1];
    char name[MAX_NAME_LENGTH + 1];
    int  grade;
    struct student *next;
} Student;


/*
 * Function : free_list
 *    deallocate the list
 * Params:
 *    head - points to the first element in the list
 */
void free_list(Student *head)
{
    Student *temp = NULL;

    while (head != NULL)
    {
        temp = head;
        head = head->next;
        free(temp);
    }
}


/*
 * Function : create_student
 *    create a new Student
 * Params:
 *    id    - student's id
 *    name  - student's name
 *    grade - student's grade
 * Returns:
 *    on success return a new Student with the fields initialized.
 *    returns NULL on failure
 */
Student* create_student(const char* id, const char* name, int grade)
{
    Student *std = NULL;

    /* allocate memory */
    std = (Student*)malloc(sizeof(Student));
    if (std != NULL) 
    {
        /* initialize fields */
        strncpy(std->id, id, MAX_ID_LENGTH);
        strncpy(std->name, name, MAX_NAME_LENGTH);
        std->grade = grade;
        std->next = NULL;
    }
    return std;
}


/*
 * Function : print_student
 *    prints the information of a single student
 * Params:
 *    std - points to the student
 */
void print_student(const Student *std)
{
    if (std != NULL)
    {
        printf("ID: %s; Name: %s; Grade: %d\n", std->id, std->name, std->grade);
    }
}


/*
 * Function : print_list
 *    prints the contents of the list
 * Params:
 *    head - points to the first element in the list
 */
void print_list(const Student *head)
{
    while (head != NULL)
    {
        print_student(head);
        head = head->next;
    }
}


/*
 * Function : add_student
 *    adds a Student to the linked list
 * Params:
 *    head - points to the first element in the list
 *    to_add - the student we wish to add (must be dynamically allocated)
 * Returns:
 *    pointer to the head of the changed list
 */
Student *add_student(Student *head, Student *to_add)
{
    Student *curr_std, *prev_std = NULL;

    /* The list is empty, simply return to_add as the new list */
    if (head == NULL) 
        return to_add;

    /* handle insertion as the first element */
    if (to_add->grade > head->grade)
    {
        to_add->next = head;
        return to_add;
    }

    /* locate where to insert the new student */
    curr_std = head;
    while (curr_std != NULL  &&  to_add->grade < curr_std->grade)
    {
        prev_std = curr_std;
        curr_std = curr_std->next;
    }

    /* insert the new element before curr_std (after prev_std) */
    prev_std->next = to_add;
    to_add->next = curr_std;

    return head;
}


Student* find_student(Student* head, const char* id)
{
    /* YOUR CODE GOES HERE */
}


int main(void)
{
    Student *head = NULL, *std = NULL;
    char id[MAX_ID_LENGTH + 1];

    head = add_student(head, create_student("1", "Marisa Coulter", 94));
    head = add_student(head, create_student("2", "Serafina Pekkala", 100));
    head = add_student(head, create_student("3", "Lyra Belacqua", 97));
    head = add_student(head, create_student("4", "Lee Scoresby", 65));
    head = add_student(head, create_student("5", "Iorek Byrnison", 76));

    printf("Please enter of the student you are looking for: ");
    scanf("%s", &id);

    std = find_student(head, id); 
    if (std != NULL) {
        print_student(std);
        
    } else {
        printf("No student with ID %s exists", id);
    }
    printf("\n");

    free_list(head);

    return 0;
}

