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

#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 <stdio.h>
#include <clib/alib_stdio_protos.h>
#include <exec/types.h>
#include <libraries/reqtools.h>
#include <intuition/intuition.h>
#include <exec/alerts.h>
#include <dos/datetime.h>
#include <exec/memory.h>

#include <clib/exec_protos.h>
#include <proto/exec.h>
#include <clib/intuition_protos.h>
#include <proto/dos.h>
#include <proto/reqtools.h>

/* PROTOTYPES */
STRPTR __asm GetString(register __a0 struct LocaleInfo *li,
                       register __d0 LONG stringNum);
char *CatSingleEventTexts(struct EventNode *eventnode, char *text);
char *CatGroupEventsTexts(struct List *list, short type, char *text);
long ShowRequest(char *text, char *button, char *params);


struct Library				*IntuitionBase,	*IFFParseBase,	*LocaleBase,
											*UtilityBase;
struct Device					*TimerBase;
struct ReqToolsBase 	*ReqToolsBase=NULL;
struct List						*list=NULL;
struct LocaleInfo			li;
ULONG									datenow, timenow;
char									title[25];

#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;

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

	if(IntuitionBase=OpenLibrary("intuition.library", LIBVER))
	{
		if(IFFParseBase=OpenLibrary("iffparse.library", LIBVER))
		{
			if(UtilityBase=OpenLibrary("utility.library", LIBVER))
			{
				if(!(OpenDevice("timer.device", UNIT_VBLANK, (struct IORequest *)tr, 0)))
				{
					TimerBase=tr->tr_node.io_Device;
					if(list=AllocMem(sizeof(struct List),MEMF_CLEAR))
					{
						NewList(list);

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

						datenow=NewMakeDate(NULL);
						timenow=NewMakeTime(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(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 Postpone-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=AllocMem(TEXTBUFFERSIZE, MEMF_CLEAR))
							{
								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);
													}
													else
													{
														retvalue_alert=1;
														MyAlert(RECOVERY_ALERT, text);
													}
													break;
	
												case EXECUTE_TYPE:
													if(config.ask_before_execute)
													{
														if(1==(retvalue_exec=ShowRequest(
																									GetString(&li, MSG_EXECUTEEVENT),
																									button,
																									text)))
															execute(text);
													}
													else
													{
														retvalue_exec=1;
														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 & config.ack_events) |
													(retvalue_event==1 & eventnode->show==DAILY))
												{
													eventnode->datestamp=datenow;
													save|=1;
												}
												else if(retvalue_event==2)
												{
													eventnode->datestamp=ACK_STAMP;
													save|=1;
												}
												break;
											case MYALERT_TYPE:
												if(retvalue_alert==0)
												{
													eventnode->datestamp=datenow;
													save|=1;
												}
												break;
											case EXECUTE_TYPE:
												if(retvalue_exec==0 |
													(retvalue_exec==1 & eventnode->show==DAILY))
												{
													eventnode->datestamp=datenow;
													save|=1;
												}
												else if(retvalue_exec==2)
												{
													eventnode->datestamp=ACK_STAMP;
													save|=1;
												}
												break;
										}
									}
								}
								FreeMem(text, TEXTBUFFERSIZE);
								if(save)
									WriteIFF(list, filename);
							}
							if(ReqToolsBase)
								CloseLibrary((struct Library *)ReqToolsBase);
						}
						FreeEventList(list);
						FreeMem(list, sizeof(struct List));

						if(LocaleBase)
						{
							CloseCatalog(li.li_Catalog);
							CloseLibrary(LocaleBase);
						}
					}
					CloseDevice((struct IORequest *)tr);
				}
				CloseLibrary(UtilityBase);
			}
			CloseLibrary(IFFParseBase);
		}
		CloseLibrary(IntuitionBase);
	}
	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=AllocMem(TEXTBUFFERSIZE, MEMF_CLEAR))
	{
		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));
			}
		}
		FreeMem(tmp, TEXTBUFFERSIZE);
	}
	return text;
}

long ShowRequest(char *text, char *button, char *params)
{
	long val;
	ULONG normaltag[]={	RTEZ_ReqTitle, (ULONG)(title),
											TAG_END};
	ULONG centretag[]={	RTEZ_ReqTitle,(ULONG)(title),
											RT_ReqPos, REQPOS_CENTERSCR,
											TAG_END};

	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;
}
