/* Mon Jul 19 02:38:27 1993 GM Erstellung, __aligned mit gcc versucht, will nicht, umgeschrieben */

#include <exec/types.h>
#include <libraries/asl.h>
#include <intuition/classusr.h>
#include <intuition/intuition.h>
#include <dos/dosextens.h>
#include <inline/stubs.h>
#ifdef __OPTIMIZE__
#include <inline/exec.h>
#include <inline/dos.h>
#include <inline/asl.h>
#include <inline/intuition.h>
#else
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include <clib/asl_protos.h>
#include <clib/intuition_protos.h>
#include <clib/tagdefines.h>
#endif

#include "add.h"

static UBYTE		 FullFileName[512],
			 		 LastFileName[64];


struct FileRequester* InitSaveSomething(void)
{
		/* Allocate the save file requester structure. */
	struct FileRequester *SaveFileRequest;

	if(!(SaveFileRequest = (struct FileRequester *)AllocAslRequestTags(ASL_FileRequest,
		ASLFR_DoSaveMode,	TRUE,
		ASLFR_PositiveText,	(ULONG)"Save",
	TAG_DONE)))
		return(FALSE);
	else
		return(SaveFileRequest);
}

void DeleteSaveSomething(struct FileRequester *SaveFileRequest)
{
	if(SaveFileRequest)
		FreeAslRequest((APTR)SaveFileRequest);
}

BOOL
SaveSomething(struct Window *window,UBYTE *HailText, struct FileRequester *SaveFileRequest, SaveFunction UserSave)
{
		/* ptr to our process */

	struct Process *process;

		/* did we save really? */

	BOOL return_val = FALSE;

		/* due to a bug in gcc, we make it globally */

	struct FileInfoBlock *FileInfo;

		/* Temporary storage. */

	UBYTE DummyBuffer[512],*Dummy;


	if(FileInfo = AllocDosObject(DOS_FIB,0))
	{

			/* get the current Process */

		process = (struct Process *) FindTask(0);


			/* If no file name has been selected yet, initialize
			 * the directory name buffer with the name of the
			 * current directory.
			 */

Start:	if(!FullFileName[0])
		{
			if(!NameFromLock(process -> pr_CurrentDir,FullFileName,512))
				LastFileName[0] = FullFileName[0] = 0;
			else
				LastFileName[0] = 0;
		}

			/* Save the file name. */

		strcpy(DummyBuffer,FullFileName);

			/* Look for the path name part. */

		Dummy = PathPart(DummyBuffer);

			/* Cut off the file name. */

		*Dummy = 0;

			/* Open the file requester. */

		if(AslRequestTags(SaveFileRequest,
			ASLFR_Window,		(ULONG)window,
			ASLFR_InitialDrawer,(ULONG)DummyBuffer,
			ASLFR_InitialFile,	(ULONG)LastFileName,
			ASLFR_TitleText,	(ULONG)HailText,
		TAG_DONE))
		{
				/* Did we get a file name to deal with? */

			if(SaveFileRequest -> fr_File[0])
			{
					/* Save the directory name. */

				StrnCpy(FullFileName,SaveFileRequest -> fr_Drawer,512);

					/* Add the file name part. */

				if(AddPart(FullFileName,SaveFileRequest -> fr_File,512))
				{
					BPTR	File	= NULL,
							FileLock;
					LONG	Error	= 0,
							Written	= 1,
							i;

						/* Save the file name separately. */

					StrnCpy(LastFileName,SaveFileRequest -> rf_File,64);

						/* Try to get lock on the file name in
						 * question and try to examine it.
						 */

					if(FileLock = Lock(FullFileName,ACCESS_READ))
					{
						/* struct FileInfoBlock FileInfo __attribute__ ((aligned (8))); */

							/* Examine the file in question. */

						if(Examine(FileLock,FileInfo))
						{
								/* Does the name refer to a directory instead of a file? */

							if(FileInfo -> fib_DirEntryType > 0)
							{
								ShowRequest(window,HailText,"Destination \"%s\" is directory, not a file.","Continue",LastFileName);

								UnLock(FileLock);

								goto Start;
							}
							else
							{
									/* Can we delete (overwrite) it? */

								if(FileInfo -> fib_Protection & FIBF_DELETE)
								{
									ShowRequest(window,HailText,"File \"%s\" is protected from deletion and\ncannot be overridden.","Continue",LastFileName);

									UnLock(FileLock);

									goto Start;
								}
								else
								{
										/* Can we write any data to it? */

									if(FileInfo -> fib_Protection & FIBF_WRITE)
									{
										ShowRequest(window,HailText,"File \"%s\" is not write-enabled and\ncannot be overridden.","Continue",LastFileName);

										UnLock(FileLock);

										goto Start;
									}
								}
							}

								/* Is there already data in the file which
								 * we may overwrite?
								 */

							if(FileInfo -> fib_Size > 0)
							{
									/* Ask the user what to do with the file. */

								switch(ShowRequest(window,HailText,"Destination file \"%s\" already exists,\ndo you still want to save?","Override file|Append file|Abort",LastFileName))
								{
										/* Overwrite the file. */

									case 1:	break;

										/* Append data to the file;
										 * release the filelock first.
										 */

									case 2:	UnLock(FileLock);

										FileLock = NULL;

											/* Open the file for mixed read and write access. */

										if(!(File = Open(FullFileName,MODE_READWRITE)))
											goto OpenError;
										else
										{
												/* Seek to the end of the file.*/

											if(Seek(File,0,OFFSET_END) == -1)
											{
													/* Query error condition. */

												Error = IoErr();

													/* Close the file. */

												Close(File);

													/* Clear the ID to avoid confusion. */

												File = NULL;
											}
										}

										break;

										/* Abort the process. */

									case 0:	UnLock(FileLock);

										return;
								}
							}
						}
						else
							Error = IoErr();

							/* Unlock the filelock again. */

						if(FileLock)
							UnLock(FileLock);
					}
					else
					{
						Error = IoErr();

							/* If unable to find the object, don't
							 * treat it as an error.
							 */

						if(Error == ERROR_OBJECT_NOT_FOUND)
							Error = 0;
					}

						/* Display an error message. */

					if(Error)
					{
							/* Get the AmigaDOS error message. */

						if(Fault(Error,"",DummyBuffer,512))
						{
							ShowRequest(window,HailText,"An error occured while accessing file \"%s\":%s","Continue",LastFileName,DummyBuffer);

							goto Start;
						}
						else
						{
							DisplayBeep(window -> WScreen);

							return;
						}
					}

						/* If not already open, create a new file. */

					if(!File)
					{
						if(!(File = Open(FullFileName,MODE_NEWFILE)))
						{
								/* Query error condition. */

OpenError:						Error = IoErr();

								/* Get the AmigaDOS error message. */

							if(Fault(Error,"",DummyBuffer,512))
							{
								ShowRequest(window,HailText,"An error occured while opening file \"%s\":%s","Continue",LastFileName,DummyBuffer);

								goto Start;
							}
							else
							{
								DisplayBeep(window -> WScreen);

								return;
							}
						}
					}

						/* Call the routine the user provided */


					UserSave(File);

						/* The save was successful */

					return_val=TRUE;


						/* Close the file we opened. */

					Close(File);

						/* Take a look at the file we dealt with. */

					if(FileLock = Lock(FullFileName,ACCESS_READ))
					{
						/* struct FileInfoBlock FileInfo __attribute__ ((aligned (4))); */

							/* Examine the file... */

						if(Examine(FileLock,FileInfo))
						{
								/* Did it remain empty? */

							if(!FileInfo -> fib_Size)
							{
								/* the save wasn't successful */

								return_val = FALSE;

									/* Ask the user what to do with it. */

								if(ShowRequest(window,HailText,"Do you wish the incomplete file \"%s\"\nto be removed?","Yes|No",LastFileName))
								{
										/* Free the filelock referring to it. */

									UnLock(FileLock);

									FileLock = NULL;

										/* Delete the file. */

									DeleteFile(FullFileName);
								}
							}
						}

							/* Free the filelock if still available. */

						if(FileLock)
							UnLock(FileLock);
					}
				}
			}
		}
		FreeDosObject(DOS_FIB, FileInfo);
	}
	return (return_val);
}
