// Arup Guha
// 11/21/2011
// Written in COP 3223 to illustrate basic linked list function.
// Essentially, a stack has been implemented that allows us to
// place an item on the top and remove the item on the top.

#include <stdio.h>

struct node {
    char task[20];
    struct node* next;
};

void print(struct node* list);
struct node* add_task(struct node* list, char thistask[]);
struct node* finish_task(struct node* list);

int main() {

    struct node* list = NULL;

    // Adding our three most important Thanksgiving Day tasks.
    list = add_task(list, "sleep");
    list = add_task(list, "eating");
    list = add_task(list, "football");
    print(list);

    // Let's finish one and print again.
    list = finish_task(list);
    print(list);
    return 0;
}

// Prints each item in the list pointed to by list.
void print(struct node* list) {

    // Number the list.
    int num = 1;

    // Print each item and advance to the next node.
    while (list != NULL) {
        printf("%d. %s\n", num, list->task);
        list = list->next;
        num++;
    }

}

// Adds the task thistask to the front of the list poitned to by list and
// returns the new front of the list.
struct node* add_task(struct node* list, char thistask[]) {

    // Create and fill the new node.
    struct node* temp = (struct node*)(malloc(sizeof(struct node)));
    strcpy(temp->task, thistask);

    // Link it to the list and return the new front.
    temp->next = list;
    return temp;
}

// Deletes the task at the front of the list pointed to by list and returns
// a pointer to the new front of the list.
struct node* finish_task(struct node* list) {

    // Special case of an empty list.
    if (list == NULL) {
        printf("Sorry, there is no task to finish.\n");
        return NULL;
    }

    // Get a pointer to the new front.
    struct node* newfront = list->next;

    // Free the front node.
    printf("Finishing task %s.\n", list->task);
    free(list);

    // Return the new front of the list.
    return newfront;
}
