/*
 *	File:					RecallPrefs.c
 *	Description:	Sets the preferences for the ultimate reminder-utility
 *	Version:			2.1
 *	Author:				Ketil Hunn
 *	Mail:					hunn@dhmolde.no
 *								ketil@brosme.dhmolde.no
 *
 *	Copyright © 1993 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>

#define  CATCOMP_NUMBERS
#include "RecallPrefs_locale.h"

extern struct Library *SysBase;
struct Library *LocaleBase;
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"

#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[FNSIZE]=PREFSFILE;

	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();
	if(aslreq=MUI_AllocAslRequestTags(ASL_FileRequest,TAG_DONE))
	{
		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);
					}
					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:
					oldnode=eventnode;
					DoMethod(	eventlist, MUIM_List_GetEntry,
										MUIV_List_GetEntry_Active, &eventnode);
					if(eventnode!=NULL & eventnode!=oldnode)
						UpdateData(eventnode, TRUE);
					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),
												aslreq,
												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),
												aslreq,
												GetString(&li, MSG_OPENREQ),
												filename,
												""))
						{
							set(eventlist, MUIA_List_Quiet, TRUE);
							FreeEventList();
							ReadIFF(eventlist, filename);
							set(eventlist, MUIA_List_Quiet, FALSE);
							saved=TRUE;
							eventnode=oldnode;
						}
					break;

				case ID_MERGE:
					if(GetFile(	GetWinPtr(window),
											aslreq,
											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),
											aslreq,
											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,NULL,NULL);
					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),
												aslreq,
												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),
												aslreq,
												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),
												aslreq,
												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);
		MUI_FreeAslRequest(aslreq);
		FreeEventList();
		DeleteFile(TESTFILE);
		fail(app,NULL);
	}
	if(LocaleBase)
	{
		CloseCatalog(li.li_Catalog);
		CloseLibrary(LocaleBase);
	}
}

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 EventNode	*eventnode;
	long datenow, eventdate;
	BOOL	remove;
	ULONG pos=0;

	set(window, MUIA_Window_Sleep, TRUE);
	set(list, MUIA_List_Quiet, TRUE);

	datenow=MakeDate(NULL);
	while(TRUE)
	{
		remove=FALSE;
		DoMethod(list, MUIM_List_GetEntry, pos, &eventnode);
		if(eventnode==NULL)
			break;
		eventdate=MakeDate(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);
}

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, NULL, NULL);
}

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