//-------------------------------------
//
// SuperCode (c) 1996 by T.Kühn 
//
// Programmiersprache:	ANSI-C
// Projektstart:			12.7.94
//
// Modul:				File.c
//
//-------------------------------------

#include <pragma/dos_lib.h>
#include <dos/dos.h>
#include <dos/stdio.h>

#include <struct.h>


char text_buffer[FAULT_MAX+2];

//-------------------------------------
ULONG file_error(struct tkfile *file,char *name,ULONG txt,ULONG ask)
{
	ULONG res;
	ULONG error=0;

	error=IoErr();
	if (file) file->error=error;

	text_buffer[Fault(error,NULL,text_buffer,FAULT_MAX)]=0;

	res=display_error((ULONG)txt,ask,name,error,text_buffer);

	return res;
}
//-------------------------------------


//-------------------------------------
struct tkfile *file_open(STRPTR name,LONG accessmode,LONG ask)
{
	struct tkfile *file=(struct tkfile*)Memory_Alloc(sizeof(struct tkfile));
	ULONG res=ASK_YES;

	file->name=name;
	file->file=0;
	file->ok=TRUE;
	file->error=0;

	if (accessmode==0) accessmode=MODE_OLDFILE;

	if (accessmode==MODE_NEWFILE && ask&ASKFILE_OVERWRITE)
	{
		BPTR lock = Lock(name,SHARED_LOCK);

		if (lock)
		{
			res=file_error(file,file->name,ERR_OVERWRITE,ASK_YES|ASK_NO);
		}

		UnLock(lock);
	}

	if (res==ASK_YES)
	{
		while(TRUE)
		{
			file->file = Open(name,accessmode);
			if (file->file) break;

			if (ask & ASKFILE_CANTOPEN) break;

			res=file_error(file,file->name,ERR_FILEOPEN,ASK_AGAIN|ASK_ABORT);
			if (res==ASK_ABORT) break;
		}
	}
	if (!file->file) file->ok=FALSE;

	return file;
}
//-------------------------------------
void file_free(struct tkfile **fileptr)
{
	struct tkfile *file=(*fileptr);
	ULONG res=0;

	if (file)
	{
		if (file->file)
		{
			if (DOSFALSE==Close(file->file))
			{
				res=file_error(file,file->name,ERR_FILECLOSE,ASK_AGAIN|ASK_ABORT);
			}
			file->file=0;
		}
		file->ok=FALSE;
		file->error=0;
	
		Memory_Free((UBYTE**)fileptr);
	}
}
//-------------------------------------
void file_write(struct tkfile *file,APTR buffer,LONG size)
{
	if (file->file && file->ok)
	{
		if (size!=Write(file->file,buffer,size))
		{
			file_error(file,file->name,ERR_FILEWRITE,ASK_AGAIN|ASK_ABORT);
		}
	}
}
//-------------------------------------
void file_writelong(struct tkfile *file,ULONG buf)
{
	if (file->file && file->ok)
	{
		if (4!=Write(file->file,&buf,4))
		{
			file_error(file,file->name,ERR_FILEWRITE,ASK_AGAIN|ASK_ABORT);
		}
	}
}
//-------------------------------------
void file_read(struct tkfile *file,APTR buffer,LONG size)
{
	if (file->ok && buffer)
	{
		if (ENDSTREAMCH==Read(file->file,buffer,size))
		{
			file_error(file,file->name,ERR_FILEREAD,ASK_AGAIN|ASK_ABORT);
		}
	}
}
//-------------------------------------
ULONG file_readlong(struct tkfile *file)
{
	ULONG res=0;

	if (file->ok)
	{
		if (ENDSTREAMCH==Read(file->file,&res,4))
		{
			file_error(file,file->name,ERR_FILEREAD,ASK_AGAIN|ASK_ABORT);
		}
	}
	return res;
}
//-------------------------------------


//-------------------------------------
void file_saveblock(struct tkfile *file,ULONG ind,ULONG ver,ULONG size,APTR block)
{
	file_writelong(file,ind);
	file_writelong(file,ver);
	file_writelong(file,size);
	file_write(file,block,size);
}
//-------------------------------------
void file_loadblock(struct tkfile *file,ULONG ver,ULONG size,APTR block)
{
	ULONG lver=0;
	ULONG lsize=0;

	lver=file_readlong(file);
	lsize=file_readlong(file);

	if (ver==lver && size==lsize)
	{
		file_read(file,block,lsize);
	}
	else
	{
		file_seek(file,lsize,OFFSET_CURRENT);
	}
}
//-------------------------------------


//-------------------------------------
LONG file_seek(struct tkfile *file,LONG newpos,LONG offset)
{
	LONG res=0;

	if (file->ok)
	{
		res = Seek(file->file,newpos,offset);
	}
	return res;
}
//-------------------------------------


//-------------------------------------
void file_delete(UBYTE *name)
{
	LONG res;

	while(TRUE)
	{
		SetProtection(name,0);
		res=DeleteFile(name);
		if (res!=DOSFALSE) break;
		if (ASK_AGAIN!=file_error(0,name,ERR_FILEDELETE,ASK_AGAIN|ASK_ABORT)) break;
	}
}
//-------------------------------------
