/*=========================================================================
 *
 * FILEUTIL.H - 29 November 1998, Dave Humphrey
 *
 *=======================================================================*/
#ifndef __FILEUTIL_H
#define __FILEUTIL_H

	/* Required includes */
#include <sys/stat.h>
#include <dos.h>
#include <direct.h>
#include <time.h>

	/* Compiler and platform specific includes */
#ifdef __DJGPP__
  #include <unistd.h>
#elif defined(_WIN32)
  #include <io.h>
#endif


/*===========================================================================
 *
 * Begin Defines
 *
 *=========================================================================*/

	/* Program Identification */
  #define FILEUTIL_NAME    "FILEUTIL.CPP"
  #define FILEUTIL_VERSION "0.8"
  #define FILEUTIL_AUTHOR  "Dave Humphrey"
  #define FILEUTIL_DATE    "18 January 1999"

	/* Size of buffer used to copy files */
  #define COPYFILE_BUFFERSIZE 30000

	/* Special ASCII Codes */
  #define CR 10
  #define LF 13

	/* Return values for read_eol, read_word */
  #define READ_OK 0
  #define READ_EOF 1
  #define READ_EOL 2
  #define READ_MSL 3

	/* Character used for various path operations */
  #define PATH_CHARACTER '\\'

	/* Return value for the filesize routines */
  #define INVALID_FILESIZE (-1l)

	/* Number of tab levels allowed in a log file */
  #define LOGFILE_MAX_TABS 20

/*===========================================================================
 *		End of Defines
 *=========================================================================*/


/*===========================================================================
 *
 * Begin Type and Structure Definitions
 *
 *=========================================================================*/
	
	/* Logfile hook callback function type */
  typedef void (*PLOGFILE_HOOKPROC) (const char* pString, va_list Args);
  typedef void (LOGFILE_HOOKPROC)   (const char* pString, va_list Args);

/*===========================================================================
 *		End of Type and Structure Definitions
 *=========================================================================*/


/*===========================================================================
 *
 * Class CLogFile Definition
 *
 * This class is used for handling log file operations used to output
 * various debugging information while program is running.
 *
 *=========================================================================*/
class CLogFile { 

  /*---------- Begin Protected Class Members --------------------*/
protected:
  FILE*		    LogFileHandle;	/* The pointer to the log file steam */
  PLOGFILE_HOOKPROC pHookProc;		/* The optional hook function */
  int		    NumTabs;		/* Number of tabs to pad output with */


  /*---------- Begin Public Class Methods -----------------------*/
public:

	/* Class Constructor and Destructor */
  CLogFile  (void) { NumTabs = 0; LogFileHandle = NULL; pHookProc = NULL; }
  ~CLogFile (void) { Close(); }

	/* Closes the log file if currently open */
  boolean Close (void);

	/* Access the file handle */
  FILE* GetFileHandle (void) { return (LogFileHandle); }

  void DecrementTabs (void) { NumTabs--;  if (NumTabs < 0) NumTabs = 0; }
  void IncrementTabs (void) { NumTabs++;  if (NumTabs > LOGFILE_MAX_TABS) NumTabs = LOGFILE_MAX_TABS; }

	/* Returns the open status of the log file */
  boolean IsOpen (void) { return ((LogFileHandle == NULL) ? FALSE : TRUE); }

	/* Attempt to open a log file for output */
  boolean Open (const char *pFilename, const boolean Append = FALSE);
  boolean OpenTemp (const char *pFilename, const boolean Append = FALSE);

	/* Output a log entry */
  boolean Printf (const char *pString, ...);

	/* Output a log entry to logfile and another stream */
  boolean Printf (FILE* pFile, const char *pString, ...);

	/* Change the hook procedure */
  void SetHookProc (PLOGFILE_HOOKPROC pProc = NULL) { pHookProc = pProc; }

 };
/*===========================================================================
 *		End of Class CLogFile Definition
 *=========================================================================*/


/*===========================================================================
 *
 * Begin Function and Procedure Prototypes
 *
 *=========================================================================*/

	/* DOS specific commands */
#ifdef __MSDOS__

	/* Checks to see if there is any disk in drive */
  boolean CheckDisk (const int NewDrive);

#endif

	/* Checks to see if a filename is a directory or not and change
	 * directory if it is. Returns TRUE on success */
  boolean ChangeDirectory (const char* pPath);

	/* Compares the file extension with the given string */
  boolean CompareExtension (const char* pFilename, const char* pString);

	/* Custom copy file command */
  boolean CopyFile (const char* pInputFile, const char* pOuputFile);
	
	/* Creates a new filename with a different extension */
  char* CreateNewExtension (const char* pOldFile, char* pNewFile, const char* pNewExt, const size_t MaxSize);

	/* Copies a path into a new string and ensures it's properly terminated */
  char* CreatePath (char* pNewPath, const char* pString, const size_t MaxStringLength);

  	/* Saves just the filename from the given string */
  char* ExtractFilename (char* pFilename, char* pPath, const size_t MaxStringLength);

  	/* Returns the path from the specified string */
  char* ExtractPath (char* pPath, const char* pString, const size_t MaxStringLength);

	/* Returns TRUE if file can be opened for reading */
  boolean FileExists (const char* pFilename);

	/* Finds first character in filename of full path */
  char* FindFilename (char* pPath);

	/* Returns filesize in bytes of given filename */
  long GetFilesize(const char* pFilename);
  long GetFilesize(FILE* FileHandle);

	/* Returns true if the specified file has an extension */
  boolean HasExtension (const char* pFilename);

	/* Returns TRUE if the specified string contains path information */
  boolean HasPath (const char* pString);

	/* Same as above but doesn't change directory */
  boolean IsDirectory (const char* pPath);

	/* Returns TRUE if the given file can be written to */
  boolean IsFileWriteable (const char* pFilename);

	/* Checks if a string has any '*' or '?' characters in it */
  boolean IsWildcard(const char* pString);

	/* Makes a directory with multiple levels */
  boolean MakeExtDirectory (const char* pSring);

	/* Returns pointer to opened file on success (with fopen) */
  FILE* openfile (const char* pFilename, const char* pMode, const boolean ExitOnError = FALSE);

	/* Read in a line into a string from the given file */
  int read_eol(FILE* FileHandle, char* pString = NULL, const size_t MaxStringLength = 0);

	/* Reads an integer from a file (binary) */
  int     read_int     (FILE* FileHandle);
  long    read_long    (FILE* FileHandle);
  short   read_short   (FILE* FileHandle);
  long    read_motlong (FILE* FileHandle);
  boolean read_int     (FILE* FileHandle, int&   Value);
  boolean read_long    (FILE* FileHandle, long&  Value);
  boolean read_short   (FILE* FileHandle, short& Value);
  boolean read_motlong (FILE* FileHandle, long&  Value);

	/* Reads entire file into memory, allocating and returning pointer
	 * to data.  Calls file_bug() and exits on error */
  char* read_file (const char* pFilename);
  char* read_textfile (const char* pFilename);

	/* Read an open file f until a Space, CR or EOF is encountered.
	 * Returns FALSE if a EOF was read */
  int read_word (FILE* FileHandle, char* pString = NULL, const size_t MaxStringLength = 0);

	/* Removes the extension from the specified filename */
  char* RemoveExt (char* pFilename);

  	/* Makes sure the string ends in a '\\' character */
  char* TerminatePath (char* pString);
	
	/* Output integer to the specified file */
  boolean write_int     (FILE* FileHandle, const int OutputValue);
  boolean write_long    (FILE* FileHandle, const long OutputValue);
  boolean write_short   (FILE* FileHandle, const short OutputValue);
  boolean write_motlong (FILE* FileHandle, const long OutputValue);

	/* Writes a text file */
  boolean write_textfile (const char* pFilename, const char* pString);

/*===========================================================================
 *		End of Function and Procedure Prototypes
 *=========================================================================*/


/*===========================================================================
 *
 * Begin External Variable Definitions
 *
 *=========================================================================*/

  extern CLogFile SystemLog;
  extern boolean  QuietLogOutput;

/*===========================================================================
 *		End of External Variable Definitions
 *=========================================================================*/


#endif
/*=========================================================================
 *		End of File FILEUTIL.H
 *=======================================================================*/