/*
 * Author		: George Leonidas Coulouris
 * Description	: rolodex
 * Last modified	: 6 July 94
 */

#include "rolodex.h"

int main(int argc, char **argv)
{
char
	choice = '?';

int
	flag = 1,
	modified = 0;

entry
	*current;

printf("rolodex 1.3 (7 July 94)\n");
printf("Copyright (C) 1994 George Leonidas Coulouris\n\n");

if (argc > 2)
	{
	fprintf(stderr,"usage: rolodex [searchstring]\n\n");
	return 0;
	}

current = start = malloc(sizeof(entry));

current->prev = NULL;

if ((fp = fopen(FILENAME, "r")) == NULL)
	{
	current->data = get_card();
	current->next = NULL;
	modified = 1;
	}
else
	{
	card
		temp;

	if ( read_card(&temp) )
		current->data = temp;

	while ( read_card(&temp) )
		{
		current->next = malloc(sizeof(entry));
		current->next->prev = current;
		current->next->data = temp;
		current = current->next;
		}

	current->next = NULL;
	fclose(fp);

	if (argc == 2)
		{
		current = search(argv[1]);

		printf("\n");

		if ( current == NULL )
			printf("String not found.\n");
		else
			print_card(&(current->data));

		printf("\n");
		goto outtahere;
		}
	}

while (flag)
	{
	switch (choice)
	{
	case '?':					/* display the menu */
	printf("\nv) View an entry\n");
	printf("s) Search by last name\n");
	printf("h) Hardcopy of list\n");
	printf("p) Browse previous entry\n");
	printf("c) View current entry\n");
	printf("n) Browse next entry\n");
	printf("a) Add an entry\n");
	printf("e) Edit an entry\n");
	printf("E) Edit current entry\n");
	printf("d) Delete an entry\n");
	printf("D> Delete current entry\n");
	printf("q) Quit\n");
	printf("Q) Quit without saving\n");

	break;

	case 'v':					/* view */
		dump_list();
		current = jump();

	case 'c':					/* view current */
		print_card(&(current->data));
		break;

	case 's':					/* search by last name */
		{
		char
			searchstring[32];

		printf("\nSearch string : ");
		fflush(stdin);
		gets(searchstring);

		current = search(searchstring);

		printf("\n");

		if ( current == NULL )
			printf("String not found.\n");
		else
			print_card(&(current->data));

		break;
		}

	case 'h':					/* hardcopy of list */
		hardcopy_list();
		break;

	case 'p':					/* browse previous */
		if (current->prev != NULL)
			current = current->prev;
		print_card(&(current->data));
		break;

	case 'n':					/* browse next */
		if (current->next != NULL)
			current = current->next;
		print_card(&(current->data));
		break;

	case 'a':					/* add */
		add_card();
		modified = 1;
		break;


	case 'e':					/* edit */
		dump_list();
		current = jump();

	case 'E':					/* edit current */
		if ( edit_card( &(current->data) ) )
			modified = 1;
		break;


	case 'd':					/* delete */
		dump_list();
		current = jump();
		
	case 'D':					/* delete current */
		if (current->prev == NULL)
			{
			start = current->next;
			current->next->prev = NULL;
			free(current);
			current = start;
			}
		else
			if (current->next == NULL)
				{
				current = current->prev;
				free(current->next);
				current->next = NULL;
				}
			else
				{
				current->prev->next = current->next;
				current->next->prev = current->prev;
				free(current);
				current = start;
				}
		modified = 1;
		break;

	case 'q':					/* quit, save changes */
		flag = 0;
		break;

	case 'Q':					/* quit without saving */
		modified = 0;
		flag = 0;
		break;

	default:
		printf("Invalid command.\n");
	}

	if (flag)
		{
		printf("\n> ");
		fflush(stdin);
		choice = getchar();
		}
	}

if (modified)
	save_list();


outtahere:

fclose(fp);
free_list();

return 0;
}

void add_card()
{
int
	i;

card
	temp = get_card();

entry
	*current = start;

i = strcmp(temp.lastname, current->data.lastname);

if (i < 0)
	i = -1;

if (i > 0)
	i = 1;

while (i != 2)
	{
	switch (i)
		{
		case -1:
		if (current->prev == NULL)
			{
			current->prev = malloc(sizeof(entry));
			current->prev->next = current;
			current->prev->prev = NULL;
			current->prev->data = temp;
			start = current->prev;
			}
		else
			{
			current->prev->next = malloc(sizeof(entry));
			current->prev->next->data = temp;
			current->prev->next->next = current;
			current->prev->next->prev = current->prev;
			current->prev = current->prev->next;
			}
		i = 2;
		break;

	case 0:
	case 1:
	if (current->next != NULL)
		current = current->next;
	else
		{
		current->next = malloc(sizeof(entry));
		current->next->data = temp;
		current->next->next = NULL;
		current->next->prev = current;
		i = 2;
		}
	}

	if (i != 2)
		{
		i = strcmp(temp.lastname, current->data.lastname);

		if (i < 0)
			i = -1;

		if (i > 0)
			i = 1;
		}
	}
}

void dump_list()
{
int
	i = 0;

entry
	*current = start;

printf("\n");

while (current != NULL)
	{
	printf("%d) %s, %s\n", ++i, current->data.lastname, current->data.firstname);
	current = current->next;
	}

printf("\n");
}

void free_list()
{
entry
	*current = start;

while (current->next != NULL)
	{
	current = current->next;
	free(start);
	start = current;
	}

free(start);
}

void print_card(card *a)
{
printf("Last name      : ");
puts(a->lastname);

printf("First name     : ");
puts(a->firstname);

printf("Home phone     : ");
puts(a->phone1);

printf("College phone  : ");
puts(a->phone2);

printf("E-mail address : ");
puts(a->e_address);

printf("Address        : ");
puts(a->address);

printf("City           : ");
puts(a->city);

printf("State          : ");
puts(a->state);

printf("Zip            : ");
puts(a->zip);

/*printf("\n");*/
}

void save_list()
{
entry
	*current = start;

fp = fopen(FILENAME, "w");

while (current != NULL)
	{
	fputs(current->data.lastname, fp);
	fputc('\n', fp);

	fputs(current->data.firstname, fp);
	fputc('\n', fp);

	fputs(current->data.phone1, fp);
	fputc('\n', fp);

	fputs(current->data.phone2, fp);
	fputc('\n', fp);

	fputs(current->data.e_address, fp);
	fputc('\n', fp);

	fputs(current->data.address, fp);
	fputc('\n', fp);

	fputs(current->data.city, fp);
	fputc('\n', fp);

	fputs(current->data.state, fp);
	fputc('\n', fp);

	fputs(current->data.zip, fp);
	fputc('\n', fp);

	current = current->next;
    }

    fclose(fp);
}

int
read_card(card *jumpoff)
{

if (fgets(jumpoff->lastname, 32, fp) == NULL)
	return 0;
else
	*(strchr(jumpoff->lastname, '\n')) = '\0';

if (fgets(jumpoff->firstname, 32, fp) == NULL)
	return 0;
else
	*(strchr(jumpoff->firstname, '\n')) = '\0';

if (fgets(jumpoff->phone1, 16, fp) == NULL)
	return 0;
else
	*(strchr(jumpoff->phone1, '\n')) = '\0';

if (fgets(jumpoff->phone2, 16, fp) == NULL)
	return 0;
else
	*(strchr(jumpoff->phone2, '\n')) = '\0';

if (fgets(jumpoff->e_address, 64, fp) == NULL)
	return 0;
else
	*(strchr(jumpoff->e_address, '\n')) = '\0';

if (fgets(jumpoff->address, 64, fp) == NULL)
	return 0;
else
	*(strchr(jumpoff->address, '\n')) = '\0';

if (fgets(jumpoff->city, 32, fp) == NULL)
	return 0;
else
	*(strchr(jumpoff->city, '\n')) = '\0';

if (fgets(jumpoff->state, 16, fp) == NULL)
	return 0;
else
	*(strchr(jumpoff->state, '\n')) = '\0';

if (fgets(jumpoff->zip, 16, fp) == NULL)
	return 0;
else
	*(strchr(jumpoff->zip, '\n')) = '\0';

return 1;
}

card get_card()
{
card
	a;

fflush(stdin);

printf("Last name      : ");
gets(a.lastname);

printf("First name     : ");
gets(a.firstname);

printf("Home phone     : ");
gets(a.phone1);

printf("College phone  : ");
gets(a.phone2);

printf("E-mail address : ");
gets(a.e_address);

printf("Address        : ");
gets(a.address);

printf("City           : ");
gets(a.city);

printf("State          : ");
gets(a.state);

printf("Zip code       : ");
gets(a.zip);

return a;
}

entry *jump()
{
int
	i = 1,
	n;

entry
	*current = start;

printf("Entry # : ");
scanf("%d", &n);

printf("\n");

if (n < 1)
	n = 1;

while ((i++ < n) && (current->next != NULL))
	current = current->next;

return current;
}

int edit_card(card *jumpoff)
{
char
	temp = 'y';

int
	choice;

while (temp == 'y')
	{
	printf("\n1) Last name      : %s\n", jumpoff->lastname);
	printf("2) First name     : %s\n", jumpoff->firstname);
	printf("3) Home phone     : %s\n", jumpoff->phone1);
	printf("4) College phone  : %s\n", jumpoff->phone2);
	printf("5) E-mail address : %s\n", jumpoff->e_address);
	printf("6) Address        : %s\n", jumpoff->address);
	printf("7) City           : %s\n", jumpoff->city);
	printf("8) State          : %s\n", jumpoff->state);
	printf("9) Zip            : %s\n", jumpoff->zip);
	printf("0) abort edit\n");
	printf("\nEdit which field ? ");

	scanf("%d", &choice);

	if (choice > 0)
		{
		printf("Enter replacement : ");
		fflush(stdin);

	switch (choice)
	{
	case 1:
		gets(jumpoff->lastname);
		break;

	case 2:
		gets(jumpoff->firstname);
		break;

	case 3:
		gets(jumpoff->phone1);
		break;

	case 4:
		gets(jumpoff->phone2);
		break;

	case 5:
		gets(jumpoff->e_address);
		break;

	case 6:
		gets(jumpoff->address);
		break;

	case 7:
		gets(jumpoff->city);
		break;

	case 8:
		gets(jumpoff->state);
		break;

	case 9:
		gets(jumpoff->zip);
		break;

	default:
		printf("Incorrect field specifier.\n");
	} /* switch */

	} /* if */
	printf("Edit another field? ");
	fflush(stdin);
	temp = getchar();
	} /* while */

return 1;
}

void
hardcopy_list(void)
{
int
	i = 0;

entry
	*current = start;

printf("\nReady printer and type 'y' to print.");

fflush(stdin);

if (getchar() == 'y')
	{
	printer = fopen(PRINTDEV,"w");

	while (current != NULL)
		{
		fprintf(printer, "%3d) %-15s %-15s %s\n", ++i,
		current->data.lastname,
		current->data.firstname,
		current->data.e_address);
		current = current->next;
		}
	fclose(printer);
	}

printf("\n");
}

entry *search(char *string)
{
entry

	*current = start;

while (current->next != NULL)
	if (strcmp( string,current->data.lastname))
		current = current->next;
	else
		return current;

return NULL;
}
