/*
 *	File:					Recall.c
 *	Description:	Runs through a project of events set by it's preferences
 *								and displays them.
 *	Version:			2.1
 *	Author:				Ketil Hunn
 *	Mail:					ketil@brosme.dhmolde.no
 *								hunn@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.
 *
 */

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

#define  CATCOMP_NUMBERS
#include "Recall_locale.h"

#define REQUESTER_TYPE	0
#define	MYALERT_TYPE		1
#define	EXECUTE_TYPE		2

#define	ALWAYS					0
#define	DAILY						1
#define	NEVER						2

#define CALC_YEARS			0
#define CALC_DAYS				1

#define GROUP_STAMP			-1
#define ACK_STAMP				-2

#include <clib/alib_stdio_protos.h>
//#include <stdio.h>
#include <libraries/reqtools.h>
#include <intuition/intuition.h>
#include <exec/alerts.h>
#include <dos/datetime.h>

#include <exec/types.h>
#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>

#include <proto/dos.h>
#include <proto/exec.h>
#include <proto/reqtools.h>

struct Library				*IntuitionBase;
struct ReqToolsBase 	*ReqToolsBase=NULL;
struct List						*list=NULL;
extern struct Library *SysBase;
struct Library *LocaleBase;
struct LocaleInfo li;

/* PROTOTYPES */
STRPTR __asm GetString(register __a0 struct LocaleInfo *li,
                       register __d0 LONG stringNum);

int AdjustYear(int year);
int CountYears(struct EventNode *node);
int CountDays(struct EventNode *node);
int CheckPrefixDate(struct EventNode *node);
int CheckDate(struct EventNode *node);
int CheckPrefixTime(struct EventNode *node);
int CheckDateTime(struct EventNode *node);
char *CalcField(struct EventNode *node, char text[]);
char *CalcField(struct EventNode *node, char text[]);
long MakeDate(struct EventNode *node);
long MakeTime(struct EventNode *node);
char *CatSingleEventTexts(struct EventNode *eventnode, char *text);
char *CatGroupEventsTexts(struct List *list, short type, char *text);
long ShowRequest(char *text, char *button, char *params);

long datenow;
long timenow;

#include "Version.h"
#include "MyEZRequest().h"
#include "MyAlert().h"
#include "Config20b.h"
#include "CalcField.h"
#include "CheckDateTime.h"
#include "execute().h"

char const *version = VERSTR;
char title[20];
ULONG normaltag[]={	RTEZ_ReqTitle, (ULONG)(title),
										TAG_END};
ULONG centretag[]={	RTEZ_ReqTitle,(ULONG)(title),
										RT_ReqPos, REQPOS_CENTERSCR,
										TAG_END};

int main(int argc, char *argv[])
{
	char *text, button[40]="  OK  ";
	long retvalue_event, retvalue_alert, retvalue_exec;
	struct Node *node;
	struct EventNode *eventnode;
	char filename[FNSIZE];

	datenow=MakeDate(NULL);
	timenow=MakeTime(NULL);

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

	{
		struct DateTime dt;
		char date[16];

		DateStamp(&dt.dat_Stamp);
		dt.dat_Format	 = 4;
		dt.dat_Flags   = NULL;
		dt.dat_StrDay  = NULL;
		dt.dat_StrDate = date;
		dt.dat_StrTime = NULL;
		DateToStr(&dt);

		strcpy(title, PROGNAME " " VERSION "  ");
		strcat(title, date);
	}

	if(argc>1)
	{
		strcpy(filename, argv[1]);
		shellopen=TRUE;
	}
	else
		strcpy(filename, PREFSFILE);

	if(IntuitionBase=OpenLibrary("intuition.library",37))
	{
		if(list=AllocMem(sizeof(struct List),MEMF_CLEAR))
		{
			NewList(list);
			if(ReadIFF(list, filename))
			{
				// do not open reqtools.library if not needed
				if(config.usereqtools)
					ReqToolsBase=	(struct ReqToolsBase *)OpenLibrary
												(REQTOOLSNAME, REQTOOLSVERSION);

				// Run through the list and mark all events that will be displayed
				for(every_node)
				{
					eventnode=(struct EventNode *)node;
					if(eventnode->show!=NEVER & eventnode->datestamp!=datenow)
						if(eventnode->datestamp==ACK_STAMP)
							eventnode->display=TRUE;
						else if(CheckDateTime(eventnode)==TRUE)
							eventnode->display=TRUE;
				}

				// add a Put Off!-button to the requester
				if(config.putoff)
					strcat(button, GetString(&li, MSG_PUTOFF));

				// add a cancel-button to the requester
				if(config.ack_events)
					strcat(button, GetString(&li, MSG_CANCEL));

				if(text=malloc(2500))
				{
					for(every_node)
					{
						strcpy(text, "");
						eventnode=(struct EventNode *)node;
						if(eventnode->display==TRUE)
						{
							if(config.groupevents)
								CatGroupEventsTexts(list, eventnode->type, text);
							else
								CatSingleEventTexts(eventnode, text);
						
							if(strlen(text))
							{
								if(config.flashscreen)
									DisplayBeep(NULL);

								switch(eventnode->type)
								{
									case REQUESTER_TYPE:
											retvalue_event=ShowRequest(text, button ,"");
										break;

									case MYALERT_TYPE:
										if(config.ack_alerts)
											strcat(text, GetString(&li, MSG_ALERTCONFIRM));
										retvalue_alert=MyAlert(RECOVERY_ALERT, text);
										break;

									case EXECUTE_TYPE:
										retvalue_exec=0;
										if(config.ask_before_execute)
										{
											if((retvalue_exec=ShowRequest(
																						GetString(&li, MSG_EXECUTEEVENT),
																						button,
																						text))==1)
												execute(text);
										}
										else
											execute(text);
										break;
								}
							}
							eventnode->display=TRUE;
 						}
						if(eventnode->datestamp==GROUP_STAMP | eventnode->display==TRUE)
						{
							eventnode->display=FALSE;
							eventnode->datestamp=0;
							switch(eventnode->type)
							{
								case REQUESTER_TYPE:
									if(retvalue_event==0 |
										(retvalue_event==1 & eventnode->show==DAILY))
										eventnode->datestamp=datenow;
									else if(retvalue_event==2)
										eventnode->datestamp=ACK_STAMP;
									break;
								case MYALERT_TYPE:
									if(retvalue_alert==0)
										eventnode->datestamp=datenow;
									break;
								case EXECUTE_TYPE:
									if(retvalue_exec==0 |
										(retvalue_exec==1 & eventnode->show==DAILY))
										eventnode->datestamp=datenow;
									else if(retvalue_exec==2)
										eventnode->datestamp=ACK_STAMP;
									break;
							}
						}
					}
					free(text);
					WriteIFF(list, filename);
				}
			}
			FreeEventList(list);
			FreeMem(list,sizeof(struct List));
		}
		if(ReqToolsBase)
			CloseLibrary((struct Library *)ReqToolsBase);
		CloseLibrary(IntuitionBase);
	}
	if(LocaleBase)
	{
		CloseCatalog(li.li_Catalog);
		CloseLibrary(LocaleBase);
	}
	exit(0);
}

char *CatSingleEventTexts(struct EventNode *eventnode, char *text)
{
	struct List *list=eventnode->textlist;
	struct Node *node;

	eventnode->display=FALSE;
	if(config.groupevents)
		eventnode->datestamp=GROUP_STAMP;
	for(every_node)
	{
		strcat(text, node->ln_Name);
		if(node!=list->lh_TailPred)
			strcat(text, "\n");
	}
	return CalcField(eventnode, text);
}

char *CatGroupEventsTexts(struct List *list, short type, char *text)
{
	struct Node *node;
	struct EventNode *eventnode;
	char   *tmp;
	BOOL   newline=FALSE;

	if(tmp=malloc(2500))
	{
		for(every_node)
		{
			eventnode=(struct EventNode *)node;
			if(eventnode->type==type & eventnode->display==TRUE)
			{
				if(!newline)
					newline=TRUE;
				else
					strcat(text, "\n");
				strcpy(tmp, "");
				strcat(text, CatSingleEventTexts(eventnode, tmp));
			}
		}
		free(tmp);
	}
	return text;
}

long ShowRequest(char *text, char *button, char *params)
{
	long val;

	if(config.usereqtools==TRUE & ReqToolsBase!=NULL)
	{
		if(config.centrerequesters)
			val=rtEZRequest(text, button, NULL,
																(struct TagItem *)centretag, params);
		else
			val=rtEZRequest(text, button, NULL,
																(struct TagItem *)normaltag, params);
	}
	else
		val=MyEZRequest(title, text, button, params);

	return val;
}
