/* assign10-1
*  This program reads a list of names from a file.  Each name has an ID number for keeping
*  track of students.  Each entry includes the first and last name and their gender.  The
*  program is going to remove some of the name and display other ones for the user.
*  P stands for previous node. C stands for current node.
*/

#include <stdio.h>
#define MAX 50

typedef struct NodeTag {
	int ID;
	char firstname[MAX];
	char lastname[MAX];
	char studentgender[MAX];
	struct NodeTag *next;
} Structure;

Structure *add_node (Structure *);
int find_id (Structure *, int, Structure **, Structure **);
void delete_node (Structure **, Structure *, Structure *);
void display_name (Structure *);
void delete_list(Structure **);
	
int main (int argc, char *argv[])
{

	FILE *infile1, *infile2, *infile3;
	char studentlist[MAX], removelist[MAX], displaylist[MAX];
	int record, found;
	char first[MAX], last[MAX], gender[MAX];
	Structure *temp, *Head = NULL, *P, *C;
	int first_time = 1;

	/* check if files were entered in the command line */
	if (argc < 4) {
		printf("usage: fopen <infile>\n");
		printf("You didn't enter all of the file names.\n");
		printf("Enter the file name with the list of students: ");
		scanf("%s", studentlist);
		printf("Enter the file name with the ID #'s of who should be removed: ");
		scanf("%s", removelist);
		printf("Enter the file name with the ID #'s for people being displayed: ");
		scanf("%s", displaylist);
	} else {
		strcpy(studentlist, argv[1]);
		strcpy(removelist, argv[2]);
		strcpy(displaylist, argv[3]);
	} /* end of if..else */

	/* open studentlist file */
	if ((infile1 = fopen(studentlist, "r")) == NULL ) {
		printf("Error opening file %s\n", studentlist);
		exit(1);
	}	

	/* create the linked list while there are names to be added */
	temp = (Structure *)malloc(sizeof(Structure));
	temp->next = NULL;
	Head = temp;
	while (fscanf(infile1, "%d %s %s %s", &record, first, last, gender) != EOF) {
		if (first_time == 1)
			first_time = 0;
		else {
			C = add_node(Head);
			temp = C;
		}
		temp->ID = record;
		strcpy(temp->firstname, first);
		strcpy(temp->lastname, last);
		strcpy(temp->studentgender, gender);
	} /* end 0f while */

	/* open removelist file */
        if ((infile2 = fopen(removelist, "r")) == NULL ) {
                printf("Error opening file %s\n", removelist);
                exit(1);
        }

	/* read id number, find id number, remove node w/ id number */
	while (fscanf(infile2, "%d", &record) != EOF) {
		found = find_id(Head, record, &P, &C);
		if (found == 1)
			delete_node(&Head, P, C);
		else 
			printf("%d wasn't found for removal.\n", record);
	}
	printf("Removal process was succesful. \n");

	/* open displaylist file */
        if ((infile3 = fopen(displaylist, "r")) == NULL ) {
                printf("Error opening file %s\n", displaylist);
                exit(1);
        }

	/* display names of people who ID is found in file */
	while (fscanf(infile3, "%d", &record) != EOF) {
		found = find_id(Head, record, &P, &C);
		if (found == 1)
			display_name(C);
		else 
			printf("%d wasn't found for display.\n", record);
	}

	/* free all exsisting nodes */
	delete_list(&Head);
	printf("The list has been cleared succesfully \n");

	/* close file w/ list of students */
        fclose(infile1);

	/* close file w/ list of remove id's */
	fclose(infile2);

	/* close file w/ list of ID of students displayed */
        fclose(infile3);

	exit(1);

} /* end of main */

/* adds a new node to the linked list */
Structure *add_node(Structure *first)
{
	Structure *temp, *L;

	temp = (Structure *)malloc(sizeof(Structure));
	if (first->next == NULL) {
        	temp->next = NULL;
        	first->next = temp;
		L = temp;
        } else {       
		L = first;
        	while (L->next != NULL)
                	L = L->next;
		temp->next = NULL;
		L->next = temp;
		L = temp;
        } /* end of if..else */

	return(L);

} /* end add_node */

/* finds a data in a linked list */
int find_id (Structure *first, int id_number, Structure **previous, Structure **current)
{
	int a = 1, b = 0, counter = 1; /* counter means the first node */
		
	(*previous) = first;
	(*current) = first;
	while ((*current)->ID != id_number && (*current)->next != NULL) {
		if (counter == 1) {
			(*current) = (*current)->next;
			counter = 0;
		} else {
			(*previous) = (*previous)->next;
			(*current) = (*current)->next;
		}
	}

	if ((*current)->ID == id_number) {
                return(a);
        } else
		return(b);
}

/* removes certain nodes from a linked list */
void delete_node(Structure **first, Structure *previous, Structure *current)
{
	if ((*first == NULL) || (previous == NULL) || (current == NULL)) {
		printf("Error, can't remove a empty list \n");
		exit(1);
	}
	if (*first == current) {
		*first = current->next;
		free(current);
	} else {
		previous->next = current->next;
		free(current);
	}

	return;
}

/* displays certain names from the linked list */
void display_name(Structure *display)
{
	printf("%d %s %s\n", display->ID, display->firstname, display->lastname);

	return;
}

/* delete any nodes left in the list */
void delete_list(Structure **first)
{
	Structure *next_node;

	if ((*first)->next == NULL)
		return;
	else {
		while ((*first)->next != NULL) {
			next_node = (*first)->next;
			free(*first);
			(*first) = next_node;
		}
	}
	free(*first);

	return;
}

