/*
 *	File:					Iffconfig.h
 *	Description:	Defines the structure of the configuration and events.
 *								Reads and writes the project as an V2.x IFF-FORM.
 *
 *	(C) 1993 Ketil Hunn
 *
 */

#include <libraries/iffparse.h>
#include <clib/iffparse_protos.h>
#include <dos.h>

#define  ID_PREF	MAKE_ID('P','R','E','F')
#define  ID_CONF	MAKE_ID('C','O','N','F')
#define  ID_EVNT	MAKE_ID('E','V','N','T')
#define  ID_ETXT	MAKE_ID('E','T','X','T')

struct Config20 {
	BOOL	centrerequesters;
	BOOL	groupevents;
	BOOL	flashscreen;
	BOOL	ack_events;
	BOOL	ack_alerts;
	BOOL  ask_before_execute;
	BOOL  putoff;
	BOOL	autodelete;
	BOOL	confirm;
	BOOL	autoopencalendar;
	BOOL	usereqtools;
	int		sortby;
};

struct EventNode20 {
	char				name[30];
	short				whendate;
	short				day;
	short				month;
	int					year;
	short				whentime;
	short				hour;
	short				minutes;
	int					days;
	int					repeat;
	short				type;
	short				show;
	short				calc;
	long				datestamp;
	short				display;
	short				expansion1;
	short				expansion2;
	struct List	*textlist;
};

BOOL ReadIFF(struct List *list, char source[256])
{
	struct IFFHandle		*iff;
	struct ContextNode	*cn;
	struct Config20			config;
	struct EventNode20	tmpnode;
	struct EventNode		*globalnode;
	long								error;
	char 								tmp[FNSIZE];
	BOOL success;

	if(iff=AllocIFF())
	{
		if(iff->iff_Stream=Open(source, MODE_OLDFILE))
		{
			InitIFFasDOS (iff);
			if(!(error=OpenIFF(iff, IFFF_READ)))
			{
				ParseIFF(iff, IFFPARSE_RAWSTEP);
				cn=CurrentChunk(iff);
				if(cn->cn_ID!=ID_FORM && cn->cn_Type!=ID_PREF)
					error=2;
				else
				{
					ParseIFF(iff, IFFPARSE_RAWSTEP);
					cn=CurrentChunk(iff);
					if(cn->cn_ID!=ID_CONF)
						error=2;
					else 
					{
						ReadChunkBytes(iff,(APTR)&config, cn->cn_Size);
						globalConfig.centrerequesters	=config.centrerequesters;
						globalConfig.groupevents			=config.groupevents;
						globalConfig.flashscreen			=config.flashscreen;
						globalConfig.ack_events				=config.ack_events;
						globalConfig.ack_alerts				=config.ack_alerts;
						globalConfig.putoff						=config.putoff;
						globalConfig.autodelete				=config.autodelete;
						globalConfig.confirm					=config.confirm;
						globalConfig.autoopencalendar	=config.autoopencalendar;
						globalConfig.sortby						=config.sortby;

						while(TRUE)
						{
							error=ParseIFF(iff, IFFPARSE_RAWSTEP);
							if(error==IFFERR_EOC)
								continue;
							else if(error)
								break;

							success=TRUE;
							if(cn=CurrentChunk(iff))
							{
								switch(cn->cn_ID)
								{
									case ID_EVNT:
										if(ReadChunkBytes(iff,(APTR)&tmpnode,cn->cn_Size)==cn->cn_Size) {
											globalnode=AddEvent(list, tmpnode.name);
											globalnode->whendate	=tmpnode.whendate;
											globalnode->day				=tmpnode.day;
											globalnode->month			=tmpnode.month;
											globalnode->year			=tmpnode.year;
											globalnode->whentime	=tmpnode.whentime;
											globalnode->hour			=tmpnode.hour;
											globalnode->minutes		=tmpnode.minutes;
											globalnode->days			=tmpnode.days;
											globalnode->repeat		=tmpnode.repeat;
											globalnode->type			=tmpnode.type;
											globalnode->show			=tmpnode.show;
											globalnode->calc			=tmpnode.calc;
										}
										break;

									case ID_ETXT:
										if(ReadChunkBytes(iff,(APTR)&tmp,cn->cn_Size)==cn->cn_Size)
											AddText(globalnode->textlist, tmp);
										break;
								}
							}
						}
					}
				}
				CloseIFF (iff);
			}
			Close (iff->iff_Stream);
		}
		else
			error=IFFERR_EOF;
		FreeIFF (iff);
	}
	if(error!=IFFERR_EOF)
		if(error==2)
			MUI_Request(app, window, 0, NULL, "*OK", GetString(&li, MSG_IFFERROR2));
		else
			MUI_Request(app, window, 0, NULL, "*OK", GetString(&li, MSG_IFFERROR1));
	return success;
}

void WriteIFFTexts(struct IFFHandle *iff, struct List *list)
{
	struct Node *node;

	for(every_node)
	{
		PushChunk(iff, 0, ID_ETXT, IFFSIZE_UNKNOWN);
		WriteChunkBytes(iff, node->ln_Name, strlen(node->ln_Name)+1);
		PopChunk(iff);
	}
}

BOOL WriteIFF(struct List *list, char *destination)
{
	struct Config20			config;
	struct EventNode20	*eventnode;
	struct EventNode		*globalnode;
	struct Node					*eNode;
	struct IFFHandle		*iff;

	iff=AllocIFF();
	iff->iff_Stream=Open(destination, MODE_NEWFILE);
	InitIFFasDOS(iff);
	OpenIFF(iff,IFFF_WRITE);

	PushChunk(iff, ID_PREF, ID_FORM, IFFSIZE_UNKNOWN);

	PushChunk(iff, 0, ID_CONF, IFFSIZE_UNKNOWN);

	config.centrerequesters	=globalConfig.centrerequesters;
	config.groupevents			=globalConfig.groupevents;
	config.flashscreen			=globalConfig.flashscreen;
	config.ack_events				=globalConfig.ack_events;
	config.ack_alerts				=globalConfig.ack_alerts;
	config.putoff						=globalConfig.putoff;
	config.autodelete				=globalConfig.autodelete;
	config.confirm					=globalConfig.confirm;
	config.autoopencalendar	=globalConfig.autoopencalendar;
	config.sortby						=globalConfig.sortby;
	WriteChunkBytes(iff, &config, sizeof(struct Config20));
	PopChunk(iff);

	eventnode=AllocMem(sizeof(struct EventNode20), MEMF_CLEAR);
	for(eNode=list->lh_Head; eNode->ln_Succ; eNode=eNode->ln_Succ)
	{
		globalnode=(struct EventNode *)eNode;

		strcpy(eventnode->name, globalnode->eventname);
		eventnode->whendate	=globalnode->whendate;
		eventnode->day			=globalnode->day;
		eventnode->month		=globalnode->month;
		eventnode->year			=globalnode->year;
		eventnode->whentime	=globalnode->whentime;
		eventnode->hour			=globalnode->hour;
		eventnode->minutes	=globalnode->minutes;
		eventnode->days			=globalnode->days;
		eventnode->repeat		=globalnode->repeat;
		eventnode->type			=globalnode->type;
		eventnode->show			=globalnode->show;
		eventnode->calc			=globalnode->calc;

		PushChunk(iff, 0, ID_EVNT, IFFSIZE_UNKNOWN);
		WriteChunkBytes(iff, eventnode, sizeof(struct EventNode20));
		PopChunk(iff);

		WriteIFFTexts(iff, globalnode->textlist);
	}
	PopChunk(iff);

	CloseIFF(iff);
	Close(iff->iff_Stream);
	FreeIFF(iff);
	FreeMem(eventnode, sizeof(struct EventNode20));
	return TRUE;

}
