/*
 *	File:					RecallPrefs.c
 *	Description:	Sets the preferences for the ultimate reminder-utility
 *	Version:			2.2
 *	Author:				Ketil Hunn
 *	Mail:					hunn@dhmolde.no
 *								ketil@brosme.dhmolde.no
 *
 *	Copyright © 1993-1994 Ketil Hunn.  Please read the document for further
 *	information and copyrights.
 *
 *	In order to list the source-files included in this package properly,
 *	the TAB size should be set at 2.
 *
 */

#define	every_node	node=list->lh_Head;node->ln_Succ;node=node->ln_Succ

#include <MUI.h>
#include <libraries/locale.h>
#include <clib/locale_protos.h>
#include <pragmas/locale_pragmas.h>
#include <dos/dostags.h>
#include <proto/dos.h>

#define  CATCOMP_NUMBERS
#include "RecallPrefs_locale.h"

extern struct Library *SysBase;
struct Library	*LocaleBase, *IFFParseBase;
struct Device		*TimerBase;
struct LocaleInfo li;

struct EventNode *eventnode, *oldnode;
BOOL addtextflag=FALSE;

#include "Prototypes.h"
#include "Version.h"
#include "Escapes.h"
#include "Id.h"
#include "Exists().h"
#include "IFFconfig.h"
#include "GUI_Preferences.h"
#include "MakeDate().h"
#include "MUI_lists.h"
#include "GetWinPtr().h"
#include "GetFile().h"
#include "Execute().h"

#define LOAD_ASCII							0
#define LOAD_V1X								1
#define LOAD_V20								2

#define SAVE_ASCII							0
#define	SAVE_V20								1

void __main(char *stop_racism__we_are_all_created_equal)
{
	ULONG	id, signals, number;
	BOOL	running	=TRUE, saved=TRUE;
	char	*string, filename[FMSIZE]=PREFSFILE;

	if(IFFParseBase=OpenLibrary("iffparse.library", LIBVER))
	{
		li.li_Catalog=NULL;
		if(LocaleBase=OpenLibrary("locale.library", 38))
		{
			li.li_LocaleBase = LocaleBase;
			li.li_Catalog    = OpenCatalogA(NULL,"Recall/RecallPrefs.catalog",NULL);
		}

		app=SetupGUI();
		ReadIFF(eventlist, PREFSFILE);
		if(DoMethod(window,MUIM_Window_GetMenuCheck, ID_AUTOOPEN_CALENDAR))
			set(editwin, MUIA_Window_Open, TRUE);
		if(config.autodelete)
			PurgeEvents(eventlist);
	
		while(running)
		{
			id=DoMethod(app,MUIM_Application_Input,&signals);
			switch(id)
			{
				case ID_SAVE_QUIT:
					WriteIFF(eventlist, PREFSFILE);
					saved=TRUE;
				case MUIV_Application_ReturnID_Quit:
				case ID_CANCEL:
					if(CheckConfirm(saved))
						running = FALSE;
					break;
	
				case ID_TEST:
					if(ExistsProg(PROGDIR PROGNAME))
					{
						WriteIFF(eventlist, TESTFILE);
//						Execute(PROGDIR PROGNAME " " TESTFILE ,NULL,NULL);
						execute(PROGDIR PROGNAME " " TESTFILE);
					}
					break;
	
				case ID_ABOUT:
					{
						char count[80];
						sprintf(count, GetString(&li, MSG_PROJECTINFO), Count(eventlist));
						MUI_Request(app, window, 0, NULL, "*OK",
												aCENTRE aLIGHT
												PROGNAME " " VERSION " " COPYRIGHT ".\n"
												"%s\n\n" aNORMAL aDARK
												"%s\n\n"
												"%s\n"
												"%s\n\n"
												"%s\n\n"
												"%s Public Domain\n\n"
												"%s " CURRENT_DATE,
												GetString(&li, MSG_BIGTALK),
												count,
												GetString(&li, MSG_LANGUAGE),
												GetString(&li, MSG_TRANSLATOR),
												GetString(&li, MSG_ABOUTHELP),
												GetString(&li, MSG_PUBLICDOMAIN),
												GetString(&li, MSG_COMPILED));
					}
					break;
	
				case ID_ICONIFY:
					set(app,MUIA_Application_Iconified, TRUE);
					break;
	
				case ID_ACTIVATE_EVENTSTRING:
					addtextflag=FALSE;
					set(eventlist,   MUIA_List_Active, MUIV_List_Active_Off);
					eventnode=NULL;
					ShowGadgets();
					set(eventstring, MUIA_Disabled, FALSE);
					set(window,      MUIA_Window_ActiveObject, eventstring);
					olddays=-1;
					break;
	
				case ID_ADDEVENT:
					get(eventstring,MUIA_String_Contents, &string);
					if(eventnode==NULL)
					{
						eventnode=AddEvent(eventlist, string);
						ZeroDateTime(eventnode);
						UpdateData(eventnode, FALSE);
						set(eventlist,	MUIA_List_Active, MUIV_List_Active_Bottom);
					}
					else
					{
						strcpy(eventnode->name, string);
						DoMethod(eventlist, MUIM_List_Redraw, MUIV_List_Redraw_All);
					}
					ShowGadgets();
					saved=FALSE;
					break;
	
				case ID_ACTIVATE_TEXTSTRING:
					set(textlist,		MUIA_List_Active, MUIV_List_Active_Off);
					set(textstring, MUIA_String_Contents, "");
					set(textstring, MUIA_Disabled, FALSE);
					set(window,			MUIA_Window_ActiveObject, textstring);
					if(eventnode->type==EXECUTE)
						set(getfile, MUIA_Disabled, FALSE);
					addtextflag=TRUE;
					break;
	
				case ID_ADDTEXT:
					get(textstring,MUIA_String_Contents, &string);
					if(Active(textlist)==-1)
					{
						DoMethod(textlist, MUIM_List_Insert, &string, 1, MUIV_List_Insert_Bottom);
						AddText(eventnode->textlist, string, MUIV_List_Insert_Bottom);
						set(textlist,	MUIA_List_Active, MUIV_List_Active_Bottom);
					}
					else
					{
						number=Active(textlist);
						set(textlist, MUIA_List_Quiet, TRUE);
						DoMethod(textlist, MUIM_List_Remove, number);
						DoMethod(textlist, MUIM_List_Insert, &string, 1, number);
						set(textlist,	MUIA_List_Active, number);
						set(textlist, MUIA_List_Quiet, FALSE);
						UpdateTextList(textlist, eventnode->textlist);
					}
					saved=FALSE;
					break;
	
				case ID_PURGEEVENT:
					if(CheckConfirm(saved))
					{
						PurgeEvents(eventlist);
						saved=FALSE;
					}
					break;
	
				case ID_DELETEEVENT:
					DeleteEvent(eventlist,Active(eventlist));
					ShowGadgets();
					saved=FALSE;
					break;
	
				case ID_MONTH:
					get(month, MUIA_Cycle_Active, &number);
					if(eventnode!=NULL)
					{
						short max=ShowDays(eventnode->month=number);
						eventnode->day=(eventnode->day<max ? eventnode->day : max);
						SetWhenString(eventnode);
						ShowBoolGadget(eventnode->day);
						saved=FALSE;
					}
					break;
	
				case ID_YEAR:
					if(eventnode!=NULL)
					{
						get(year, MUIA_String_Integer, &eventnode->year);
						SetWhenString(eventnode);
						saved=FALSE;
					}
					break;
	
				case ID_DAYS:
					if(eventnode!=NULL)
					{
						get(days, MUIA_String_Integer, &eventnode->days);
						SetWhenString(eventnode);
						saved=FALSE;
					}
					break;
	
				case ID_REPEAT:
					if(eventnode!=NULL)
					{
						get(repeat, MUIA_String_Integer, &eventnode->repeat);
						SetWhenString(eventnode);
						saved=FALSE;
					}
					break;
	
				case ID_DELETETEXT:
					DeleteText(eventnode->textlist, Active(textlist));
					DoMethod(textlist, MUIM_List_Remove, MUIV_List_Remove_Active);
					addtextflag=FALSE;
					ShowGadgets();
					saved=FALSE;
					break;
	
				case ID_EVENTUP:
					Up(eventlist);
					saved=FALSE;
					break;
	
				case ID_TEXTUP:
					Up(textlist);
					UpdateTextList(textlist, eventnode->textlist);
					saved=FALSE;
					break;
	
				case ID_EVENTDOWN:
					Down(eventlist);
					saved=FALSE;
					break;
	
				case ID_TEXTDOWN:
					Down(textlist);
					UpdateTextList(textlist, eventnode->textlist);
					saved=FALSE;
					break;
	
				case ID_EVENTTOP:
					Top(eventlist);
					saved=FALSE;
					break;
	
				case ID_EVENTBOTTOM:
					Bottom(eventlist);
					saved=FALSE;
					break;
	
				case ID_SORTEVENT:
					if(DoMethod(window,MUIM_Window_GetMenuCheck,ID_SORTBY_NAME))
						DoMethod(eventlist, MUIM_List_Sort);
					else
						SortByDate(eventlist);
					DoMethod(eventlist, MUIM_List_GetEntry,
															MUIV_List_GetEntry_Active, &eventnode);
					UpdateData(eventnode, TRUE);
					saved=FALSE;
					break;
	
				case ID_SORTTEXT:
					set(textlist, MUIA_List_Quiet, TRUE);
					DoMethod(textlist, MUIM_List_Sort);
					UpdateTextList(textlist, eventnode->textlist);
					set(textlist, MUIA_List_Quiet, FALSE);
					saved=FALSE;
					break;
	
				case ID_COPYEVENT:
					eventnode=CopyEvent(eventlist);
					set(window, MUIA_Window_ActiveObject, eventstring);
					saved=FALSE;
					break;
	
				case ID_COPYTEXT:
					DoMethod(	textlist, MUIM_List_GetEntry,
										MUIV_List_GetEntry_Active, &string);
					DoMethod(textlist, MUIM_List_Insert, &string, 1, Active(textlist)+1);
					AddText(eventnode->textlist, string, Active(textlist));
					set(textlist,	MUIA_List_Active, Active(textlist)+1);
					saved=FALSE;
					break;
	
				case ID_WHENDATE:
					if(eventnode!=NULL)
					{
						get(whendate, MUIA_Cycle_Active, &number);
						eventnode->whendate=number;
						SetWhenString(eventnode);
						saved=FALSE;
					}
					break;
	
				case ID_WHENTIME:
					if(eventnode!=NULL)
					{
						get(whentime, MUIA_Cycle_Active, &number);
						eventnode->whentime=number;
						SetWhenString(eventnode);
						saved=FALSE;
					}
					break;
	
				case ID_TYPE:
					if(eventnode!=NULL)
					{
						get(type, MUIA_Cycle_Active, &number);
						eventnode->type=number;
						if(Active(textlist)!=-1 && eventnode->type==2)
							set(getfile,	MUIA_Disabled, FALSE);
						else
							set(getfile,	MUIA_Disabled, TRUE);
						saved=FALSE;
					}
					break;
	
				case ID_SHOW:
					get(show, MUIA_Cycle_Active, &number);
					eventnode->show=number;
					eventnode->datestamp=0;
					saved=FALSE;
					break;
	
				case ID_CALC:
					if(eventnode!=NULL)
					{
						get(calc, MUIA_Cycle_Active, &number);
						eventnode->calc=number;
						saved=FALSE;
					}
					break;
	
				case ID_EVENTLIST:
					DoMethod(	eventlist, MUIM_List_GetEntry,
										MUIV_List_GetEntry_Active, &eventnode);
					if(eventnode!=NULL & eventnode!=oldnode)
						UpdateData(eventnode, TRUE);
					oldnode=eventnode;
					SetWhenString(eventnode);
					ShowGadgets();
					addtextflag=FALSE;
					break;
	
				case ID_TEXTLIST:
					DoMethod(	textlist, MUIM_List_GetEntry,
										MUIV_List_GetEntry_Active, &string);
					set(textstring, MUIA_String_Contents, string);
					ShowGadgets();
					break;
	
				case ID_EDITCLEAR:
					ZeroDateTime(eventnode);
					eventnode->whendate=eventnode->whentime=0;
					UpdateData(eventnode, FALSE);
					saved=FALSE;
					break;
	
				case ID_EDITNOW: 
					CurrentDateTime(eventnode);
					UpdateData(eventnode, FALSE);
					saved=FALSE;
					break;
	
				case ID_EDIT:
					set(editwin,MUIA_Window_Open, TRUE);
					UpdateData(eventnode, FALSE);
					break;
	
				case ID_EDITCLOSE:
					set(editwin, MUIA_Window_Open, FALSE);
					break;
	
				case ID_HOUR:
					if(eventnode!=NULL)
					{
						get(hour, MUIA_Prop_First, &number);
						eventnode->hour=23-number;
						SetWhenString(eventnode);
						saved=FALSE;
					}
					break;
	
				case ID_MINUTES:
					if(eventnode!=NULL)
					{
						get(minutes, MUIA_Prop_First, &number);
						eventnode->minutes=59-number;
						SetWhenString(eventnode);
						saved=FALSE;
					}
					break;
	
				case ID_DAY1:		case ID_DAY2:		case ID_DAY3:		case ID_DAY4:
				case ID_DAY5:		case ID_DAY6:		case ID_DAY7:		case ID_DAY8:
				case ID_DAY9:		case ID_DAY10:	case ID_DAY11:	case ID_DAY12:
				case ID_DAY13:	case ID_DAY14:	case ID_DAY15:	case ID_DAY16:
				case ID_DAY17:	case ID_DAY18:	case ID_DAY19:	case ID_DAY20:
				case ID_DAY21:	case ID_DAY22:	case ID_DAY23:	case ID_DAY24:
				case ID_DAY25:	case ID_DAY26:	case ID_DAY27:	case ID_DAY28:
				case ID_DAY29:	case ID_DAY30:	case ID_DAY31:	case ID_DAY0:
					if(eventnode!=NULL)
					{
	//printf("day\n");
						ShowBoolGadget(eventnode->day=id-100);
						SetWhenString(eventnode);
						saved=FALSE;
					}
					break;
	
				case ID_GETFILE:
					{
						char string[FNSIZE], *p=string;
						get(textstring, MUIA_String_Contents, &p);
						if(GetFile(	GetWinPtr(window),
												GetString(&li, MSG_SELECTCOMMAND),
												p,""))
							set(textstring, MUIA_String_Contents, p);
						set(window, MUIA_Window_ActiveObject, textstring);
					}
					break;
	
				/* parsing the menus */
				case ID_NEW:
					if(CheckConfirm(saved))
					{
						set(window, MUIA_Window_Sleep, TRUE);
						FreeEventList();
						ShowGadgets();
						set(window, MUIA_Window_Sleep, FALSE);
						saved=TRUE;
					}
					break;
	
				case ID_OPEN:
					if(CheckConfirm(saved))
						if(GetFile(	GetWinPtr(window),
												GetString(&li, MSG_OPENREQ),
												filename,
												""))
						{
							set(eventlist, MUIA_List_Quiet, TRUE);
							FreeEventList();
							ReadIFF(eventlist, filename);
							set(eventlist, MUIA_List_Quiet, FALSE);
							saved=TRUE;
						}
					break;
	
				case ID_MERGE:
					if(GetFile(	GetWinPtr(window),
											GetString(&li, MSG_MERGEREQ),
											filename,
											""))
					{
						ReadIFF(eventlist, filename);
						saved=FALSE;
					}
					break;
	
				case ID_SAVE:
					if(WriteIFF(eventlist, PREFSFILE))
						saved=TRUE;
					break;
	
				case ID_SAVE_AS:
					if(GetFile(	GetWinPtr(window),
											GetString(&li, MSG_SAVEASREQ),
											filename,
											""))
					{
						WriteIFF(eventlist, filename);
						saved=TRUE;
					}
					break;
	
				case ID_CONVERTER:
					set(window, MUIA_Window_Sleep, TRUE);
					if(Exists(CONVDIR CONVERTERNAME))
						execute("RUN >NIL: " CONVDIR CONVERTERNAME);
					else
						MUI_Request(app, window, 0, NULL,
												"*OK", GetString(&li, MSG_COULDNOTFIND),CONVDIR CONVERTERNAME);
					set(window, MUIA_Window_Sleep, FALSE);
					break;
	
				case ID_IMPORT_ASCII:
					if(ExistsProg(CONVDIR CONVERTERNAME))
						if(GetFile(	GetWinPtr(window),
												GetString(&li, MSG_IMPORTREQ),
												filename,
												""))
						{
							ConverterArgs(LOAD_ASCII, filename, SAVE_V20, TESTFILE);
							FreeEventList();
							ReadIFF(eventlist, TESTFILE);
						}
					break;
	
				case ID_IMPORT_V14:
					if(ExistsProg(CONVDIR CONVERTERNAME))
						if(GetFile(	GetWinPtr(window),
												GetString(&li, MSG_IMPORTREQ),
												filename,
												""))
						{
							ConverterArgs(LOAD_V1X, filename, SAVE_V20, TESTFILE);
							FreeEventList();
							ReadIFF(eventlist, TESTFILE);
						}
					break;
	
				case ID_EXPORT_ASCII:
					if(ExistsProg(CONVDIR CONVERTERNAME))
						if(GetFile(	GetWinPtr(window),
												GetString(&li, MSG_EXPORTREQ),
												filename,
												""))
						{
							WriteIFF(eventlist, TESTFILE);
							ConverterArgs(LOAD_V20, TESTFILE, SAVE_ASCII, filename);
						}
					break;
	
				case ID_LAST_SAVED:
					if(CheckConfirm(saved))
					{
						FreeEventList();
						ReadIFF(eventlist, PREFSFILE);
						saved=TRUE;
					}
					break;
	
				case ID_REQTOOLS:
				if(DoMethod(window, MUIM_Window_GetMenuCheck, ID_REQTOOLS))
					DoMethod(app, MUIM_Application_SetMenuState, ID_CENTRE_REQUESTERS, TRUE);
				else
					DoMethod(app, MUIM_Application_SetMenuState, ID_CENTRE_REQUESTERS, FALSE);
			}
			if(running && signals)
				Wait(signals);
		}
		set(window,MUIA_Window_Open,FALSE);
		if(aslreq)
			MUI_FreeAslRequest(aslreq);
		FreeEventList();
		DeleteFile(TESTFILE);
		fail(app,NULL);

		if(LocaleBase)
		{
			CloseCatalog(li.li_Catalog);
			CloseLibrary(LocaleBase);
		}
		CloseLibrary(IFFParseBase);
	}
}

BOOL CheckConfirm(BOOL saved)
{
	char butts[80]="*OK|";
	
	strcat(butts, GetString(&li, MSG_CANCEL));
	if(DoMethod(window,MUIM_Window_GetMenuCheck,ID_CONFIRM) & !saved)
		return (BOOL)MUI_Request(	app, window, 0, NULL, butts,
															GetString(&li, MSG_CONFIRM));
	else
		return TRUE;
}

void PurgeEvents(Object *list)
{
	struct Library			*UtilityBase;
	struct timerequest	timereq, *tr=&timereq;
	struct EventNode		*eventnode;
	ULONG								datenow, eventdate, pos=0;
	BOOL								remove;

	if(UtilityBase=OpenLibrary("utility.library", LIBVER))
	{
		if(!(OpenDevice("timer.device", UNIT_VBLANK, (struct IORequest *)tr, 0)))
		{
			TimerBase=tr->tr_node.io_Device;
			set(window, MUIA_Window_Sleep, TRUE);
			set(list, MUIA_List_Quiet, TRUE);

			datenow=NewMakeDate(NULL);
			while(TRUE)
			{
				remove=FALSE;
				DoMethod(list, MUIM_List_GetEntry, pos, &eventnode);
				if(eventnode==NULL)
					break;
				eventdate=NewMakeDate(eventnode);

				switch(eventnode->whendate)
				{
					case EXACT:
						if(datenow>eventdate & (eventnode->year>0 & eventnode->month>0))
							remove=TRUE;
						break;

					case BEFORE:
						if(datenow>=eventdate & (eventnode->year>0 & eventnode->month>0))
							remove=TRUE;
						break;

					case AFTER:
						if(eventnode->days>0 & datenow>eventdate+86400*eventnode->days)
							remove=TRUE;
						break;
				}
				if(remove)
					DeleteEvent(list, pos);
				else
					pos++;
			}
			set(list, MUIA_List_Quiet, FALSE);
			set(window, MUIA_Window_Sleep, FALSE);
			CloseDevice((struct IORequest *)tr);
		}
		CloseLibrary(UtilityBase);
	}
}

void ConverterArgs(	short intype,  char source[FNSIZE],
										short outtype, char dest[FNSIZE])
{
	char args[FNSIZE];
	sprintf(args, "%s %ld \"%s\" %ld \"%s\"", CONVDIR CONVERTERNAME, (long)intype, source, (long)outtype, dest);
	execute(args);
}

BOOL ExistsProg(char *prog)
{
	if(Exists(prog))
		return TRUE;
	else
	{
		MUI_Request(app, window, 0, NULL, "*OK",
								GetString(&li, MSG_COULDNOTFIND), prog);
		return FALSE;
	}
}