/* Jetzt in C: Das Konvertierungsprogramm für ACDPlay-Konfigurationsdateien */

#include <clib/dos_protos.h>
#include <clib/exec_protos.h>
#include <dos/dos.h>
#include <exec/exec.h>

#include "string.h"

#define ACD1 0x41434431
#define ACD2 0x41434432
#define ACD3 0x41434433

#define SIZE_CONFIG 	192
#define ANZ_WINDOWS 	10
#define SIZE_WINDOW 	18
#define STD_FLAG_MAIN 	127

char * OpenFile(char *);
BOOL SaveFile(char *, char *, LONG);

int main(int argc, char *argv[])
{
	ULONG returnval = RETURN_FAIL;

	struct RDArgs *rda;

	/* Dateiname rausfinden */
	if (rda = AllocDosObject(DOS_RDARGS, NULL))
	{
		LONG vec[1];
		char fullname[257];

		rda->RDA_ExtHelp =	"[4mACDPlay 1.5 config file converter[24m\n"
							"[1mFILE:   [22mold ACDPlay configuration file\n\n"
							"Enter parameters";

		if (ReadArgs("F=FILE/A", vec, rda))
		{
			char *oldbuf, *newbuf;

			FreeArgs(rda);
			strncpy(fullname, (char *)vec[0], 256);

			/* Datei laden */
			if (oldbuf = OpenFile(fullname))
			{
				if (newbuf = AllocVec(SIZE_CONFIG, MEMF_ANY))
				{
					WORD *oldoffset = (WORD *)oldbuf;
					WORD *newoffset = (WORD *)newbuf;
					LONG id = *(LONG *)oldbuf;
					
					/* Variablen zum Speichern der Werte */
					WORD position_min[ANZ_WINDOWS * 4];
					WORD position_max[ANZ_WINDOWS * 4];
					WORD bools[ANZ_WINDOWS];
					LONG flag_main;
					
					int i, j, usedwindows;
					BOOL write = FALSE;

					/* Datei bearbeiten */
					switch (id)
					{
						case ACD1:
							/* Hierbei handelt es sich um das ganz alte
							   Konfig-File. Die Daten sind vollkommen anders
							   strukturiert.
							   Da es zwischen den Konfig-Files von V1.0 und V1.1
							   auch noch Unterschiede gibt, werden nur die
							   am Anfang der Datei befindlichen Fensterpositionen
							   gerettet. */
														
							oldoffset += 16;
							
							/* Die Sachen erstmal in ein Array schreiben */
							for (i = 0; i < 8; i++)
							{
								bools[i] = *(oldoffset++);
							}
							
							for (i = 0; i < 8 * 4; i++)
							{
								position_min[i] = *(oldoffset++);
							}
							for (i = 0; i < 8 * 4; i++)
							{
								position_max[i] = *(oldoffset++);
							}
							
							flag_main = STD_FLAG_MAIN;
							
							write = TRUE;
							usedwindows = 8;
							
							break;
						
						case ACD2:
							/* Hier ist wohl ein Fenster dazugekommen */
							
							oldoffset += 4;
							
							for (i = 0; i < 9; i++)
							{
								for (j = 0; j < 4; j++)
									position_min[4 * i + j] = *(oldoffset++);
								for (j = 0; j < 4; j++)
									position_max[4 * i + j] = *(oldoffset++);

								bools[i] = *(oldoffset++);
							}
							
							flag_main = *(LONG *)oldoffset;
							
							write = TRUE;
							usedwindows = 9;
							
							break;
					}
					
					if (write)
					{
						/********************************/
						/* Eintragen von Standardwerten */
						/********************************/
						
						/* Standardwerte für fehlende Fenster   */
						/* Die Anzahl der verbleibenden Fenster */
						/* wird aus 'usedwindows' ermittelt     */
						
						for (i = 8; i < ANZ_WINDOWS; i++)
						{
							bools[i] = FALSE;
						}
						for (i = 8 * 4; i < ANZ_WINDOWS * 4; i++)
						{
							position_min[i] = 100;
							position_max[i] = 100;
						}
						
						/************************************/
						/* Erstellen der neuen Konfig-Datei */
						/************************************/
						
						(*(LONG *)newoffset) = ACD3;		/* ID setzen */
						newoffset += 2;
						
						*(newoffset++) = ANZ_WINDOWS;
						*(newoffset++) = SIZE_WINDOW;
						
						/* Jetzt eintragen */
						for (i = 0; i < ANZ_WINDOWS; i++)
						{
							for (j = 0; j < 4; j++)
								*(newoffset++) = position_min[4 * i + j];
							for (j = 0; j < 4; j++)
								*(newoffset++) = position_max[4 * i + j];
							
							*(newoffset++) = bools[i];
						}
						
						*(LONG *)newoffset = flag_main;
						
						if (SaveFile(fullname, newbuf, SIZE_CONFIG))
						{
							SetProtection(fullname, FIBF_EXECUTE);
							returnval = RETURN_OK;
						}
					}
					
					FreeVec(newbuf);
				}
				FreeVec(oldbuf);
			}
		}
		FreeDosObject(DOS_RDARGS, rda);
	}

	return (returnval);
}

char * OpenFile(char * name)
{
	BPTR filehandle;
	struct FileInfoBlock *fib;
	APTR buffer = NULL;

	/* Datei öffnen */
	if (filehandle = Open(name, MODE_OLDFILE))
	{
		if (fib = (struct FileInfoBlock *)AllocDosObject(DOS_FIB, NULL))
		{
			/* FileInfoblock auslesen, für Dateigröße */
			if (ExamineFH(filehandle, fib) == DOSTRUE)
			{
				if (fib->fib_Size)
				{
					/* Speicher reservieren */
					if (buffer = (char *)AllocVec(fib->fib_Size, MEMF_ANY))
					{
						/* Datei in Speicher schreiben */
						if (Read(filehandle, buffer, fib->fib_Size) != fib->fib_Size)
							buffer = NULL;
					}
				}
			}
			FreeDosObject(DOS_FIB, (APTR)fib);
		}
		/* Datei schließen */
		Close(filehandle);
	}
	return ((char *)buffer);
}

BOOL SaveFile(char *name, char *buffer, LONG bufferlen)
{
	BPTR filehandle;
	BOOL success = FALSE;

	if (filehandle = Open(name, MODE_NEWFILE))
	{
		if (Write(filehandle, (APTR)buffer, bufferlen) == bufferlen)
			success = TRUE;
		Close(filehandle);
	}

	return (success);
}