
/****************************************************************************
 *
 *	address_book.c
 *
 *	MAIN CODE MODULE
 *	
 *	TO COMPILE USING DICE:
 *		"execute make_app" - Where make_app is our application maker, see
 *												 earlier issues of AS.
 *
 *	Address book application for Amiga Shopper.
 *	By Toby Simpson.
 *	(C) Copyright AmigaShopper 1993.
 */

#include "address_includes.h"

/* Definition for the intuition library base */
struct IntuitionBase *IntuitionBase = NULL;

extern struct Window *addr_window;					/* External definition */
extern struct Gadget window_gads[];
extern int field_lengths[];
extern char *field_names[];

/* Our Global Variables */
BOOL	search_flag			= FALSE;			/* Indicates we're searching				*/
BOOL 	new_flag				= FALSE;			/* Indicating we're making new rec. */
BOOL 	record_changed 	= FALSE;			/* Flag to indicate we made changes */
long	current_record 	= -1;					/* Current record, -1 for none			*/
long	total_records 	= 0;					/* Total records in file						*/
char	record_data[RECORD_LENGTH];		/* The actual record itself 				*/

/* Embed a version string in our program */
UBYTE *version = "\0$VER:"VERSION_STRING;

/* Our "main" function */
void main(void)
{
	BOOL 		quit_program = FALSE;
	long 		signal_mask = 0;
	long		new_id = 0;
	struct 	IntuiMessage *imsg;
	struct	Gadget *gad_pressed;
	char		*field_offset;
	int			loop;
	long		match_id;

	/* Open the intuition library */
	if (!(IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 34L)))
		{
		printf("Can't open intuition.library V34.\n");
		cleanexit(10);					/* Exit, error code 10 */
		}

	/* Open our window */
	if (!(open_window()))
		{
		printf("Can't open my window.\n");
		cleanexit(10);					/* Exit, error code 10 */
		}

	/* Initialise file information */
	total_records = find_total_records();

	/* Work our our signal mask */
	signal_mask = 1L << (addr_window->UserPort->mp_SigBit);

	/* Window opened, now wait for events */
	while (!quit_program)
		{
		/* Wait for something to happen */
		Wait(signal_mask);

		/* Act on any messages */
		while (imsg = (struct IntuiMessage *)GetMsg(addr_window->UserPort))
			{
			/* Remember the gadget number for identifying presses */
			gad_pressed = (struct Gadget *)imsg->IAddress;

			switch(imsg->Class)
				{
				/* If its the close gadget, set the exit flag */
				case CLOSEWINDOW:
					if (record_changed)
						{
						/* Ask if OK to lose changes.. */
						if (!(YesOrNo("Ok to lose changes?", "Yes", "Cancel")))
							break;
						}

					/* User clicked OK! */
					quit_program = TRUE;
					break;

				case GADGETUP:
					/* Deal with the button ID */
					switch(gad_pressed->GadgetID)
						{
						case BTN_PREV:
							/*
							**	Goto Previous Record
							*/
							if (search_flag)
								{
								/* Search backwards */
								record_changed = FALSE;
								match_id = search_record_data(current_record, SEARCH_BACKWARDS, record_data);

								if (match_id == -1)
									YesOrNo("No match found", NULL, "Abort");
								else
									current_record = match_id;

								show_current_record(record_data, current_record);
								search_flag = FALSE;

								break;
								}

							if (record_changed)
								{
								/* Ask if OK to lose changes.. */
								if (!(YesOrNo("Ok to lose changes?", "Yes", "Cancel")))
									break;
								}
							if (current_record > 0)		current_record--;
							if (current_record != -1)
								show_current_record(record_data, current_record);
							new_flag = FALSE;
							break;

						case BTN_NEXT:
							/*
							**	Goto Next Record
							*/
							if (search_flag)
								{
								/* Search backwards */
								record_changed = FALSE;
								match_id = search_record_data(current_record, SEARCH_FORWARDS, record_data);

								if (match_id == -1)
									YesOrNo("No match found", NULL, "Abort");
								else
									current_record = match_id;

								show_current_record(record_data, current_record);
								search_flag = FALSE;

								break;
								}

							if (record_changed)
								{
								/* Ask if OK to lose changes.. */
								if (!(YesOrNo("Ok to lose changes?", "Yes", "Cancel")))
									break;
								}
							if (current_record < (total_records-1))	current_record++;
							if (current_record != -1)
								show_current_record(record_data, current_record);
							new_flag = FALSE;
							break;

						case BTN_SAVE:
							/*
							**	Save changes
							*/
							if (search_flag)
								{
								YesOrNo("Nothing to save", NULL, "Continue");
								break;
								}
							if (new_flag)
								{
								/* Save new record... */
								if (write_record_data(record_data, -1))
									{
									/* Record created OK */
									total_records++;
									current_record = total_records - 1;
									show_current_record(record_data, current_record);
									new_flag = FALSE;
									record_changed = FALSE;
									}								
								}
							else
								if (current_record >= 0 && record_changed)
									{
									/* Save any changes */
									write_record_data(record_data, current_record);
									record_changed = FALSE;
									}
								else
									YesOrNo("Nothing to save", NULL, "Continue");
							break;

						case BTN_GOTO:
							/*
							**	Goto named record
							*/
							break;

						case BTN_SEARCH:
							/*
							**	Search for data
							*/
							if (record_changed)
								{
								/* Ask if OK to lose changes.. */
								if (!(YesOrNo("Ok to lose changes?", "Yes", "Cancel")))
									break;
								}
							search_flag = TRUE;
							new_flag = FALSE;
							record_changed = FALSE;
							show_current_record(record_data, CREATE_SEARCH);

							/* Activate first string gadget */
							ActivateGadget(&window_gads[0], addr_window, NULL);
							break;

						case BTN_NEW:
							/*
							**	Create a new record
							*/
							if (record_changed)
								{
								/* Ask if OK to lose changes.. */
								if (!(YesOrNo("Ok to lose changes?", "Yes", "Cancel")))
									break;
								}
							new_flag = TRUE;
							search_flag = FALSE;
							record_changed = FALSE;
							show_current_record(record_data, CREATE_NEW);

							/* Activate first string gadget */
							ActivateGadget(&window_gads[0], addr_window, NULL);
							break;

						default:
							/*
							**	If it wasn't one of the above, it must have been the
							**	string gadgets, so make the change if any.
							*/
							if (current_record != -1 || new_flag || search_flag)
								{
								record_changed = TRUE;

								/* Copy changed field across... */
								field_offset = record_data;		
					
								for (loop = 0; loop < gad_pressed->GadgetID; loop++)
									field_offset = field_offset + field_lengths[loop];

								strcpy(field_offset, ((struct StringInfo *)(window_gads[gad_pressed->GadgetID].SpecialInfo))->Buffer);

								/* Activate next gadget */
								new_id = gad_pressed->GadgetID + 1;
								if (new_id == TOTAL_FIELDS)		new_id = 0;
								ActivateGadget(&window_gads[new_id], addr_window,	NULL);
								}
							else
								YesOrNo("No record, data ignored", NULL, "Cancel");
							break;
						}

					break;
				}

			/* Now we've dealt with the message, reply to it */
			ReplyMsg((struct Message *)imsg);
			}		
		}

	/* Now exit gracefully with no error code */
	cleanexit(0);
}

/*******************
 *
 * 	void cleanexit(error_code)
 *
 *	This routine simply tidies up anything which is open before exiting
 *	the program.
 */

void cleanexit(int return_value)
{
	if (IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
	close_window();				/* Close our window if it was opened */

	/* Exit the program */
	exit(return_value);
}
