/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::
::   Module      :   Flash File System API Header File
::   Copyright   :   (C)2004-2009 Woodward
::   Platform(s) :   MPC5xx
::   Limitations :   None
::
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
/*! \file Resource_FFS.h
    \brief The Flash File System (FFS) allows standard file operations to be performed on an embedded file
           system that is utilising (typically) NAND Flash technology
*/
    
#ifndef __RESOURCE_FFS_H
#define __RESOURCE_FFS_H

/*----- INCLUDES ------------------------------------------------------------------------------------------*/
#include <typedefn.h>
#include <resource.h>

/*----- DEFINES -------------------------------------------------------------------------------------------*/
/*! The filename path length describes a 48 character name, a '.', a 3 character extension and a NULL
    terminator */
#define FILENAME_PATH_LEN (48 + 3 + 2)

#ifdef _MAX_DRIVE
#undef _MAX_DRIVE
#endif
#ifdef MAX_DRIVE
#undef MAX_DRIVE
#endif
#define _MAX_DRIVE  7
/*! The maximum number of chracters including the NULL terminator in a volume name (drive name) */
#define MAX_DRIVE   _MAX_DRIVE

#ifdef _MAX_EXT
#undef _MAX_EXT
#endif
#ifdef MAX_EXT
#undef MAX_EXT
#endif
#define _MAX_EXT    3
/*! The maximum number of characters including the NULL terminator in a file extension name */
#define MAX_EXT     _MAX_EXT

#ifdef _MAX_PATH
#undef _MAX_PATH
#endif
#ifdef MAX_PATH
#undef MAX_PATH
#endif
#define _MAX_PATH       (FILENAME_PATH_LEN - MAX_EXT - MAX_DRIVE)
/*! The maximum number of chracters including a NULL terminator in a path name */
#define MAX_PATH        _MAX_PATH

#ifdef _MAX_FNAME
#undef _MAX_FNAME
#endif
#ifdef MAX_FNAME
#undef MAX_FNAME
#endif
#define _MAX_FNAME     _MAX_PATH
/*! The maximum number of characters including the NULL terminator in a file name */
#define MAX_FNAME      _MAX_FNAME

#ifdef _MAX_DIR
#undef _MAX_DIR
#endif
#ifdef MAX_DIR
#undef MAX_DIR
#endif
#define _MAX_DIR       _MAX_PATH
/*! The maximum number of chracters including the NULL terminator in a path name */
#define MAX_DIR        _MAX_DIR

#define OVERWRITE_IF_FILE_EXIST FALSE
#define FAIL_IF_FILE_EXIST      TRUE
/*----- TYPEDEFS ------------------------------------------------------------------------------------------*/
#pragma pack(1)

/*! Describes the set of possible events that a file system volume could experience */
typedef enum
{
    FFS_VOLUME_MOUNTED    = 0x01,
    FFS_VOLUME_UNMOUNTED  = 0x02
} E_FileSysEvent;

/*! \brief Function pointer type that defines the function that is executed ona file system event

    The parameter \p in_pszVolume describes the volume name of the file system that the event applies to.
    The parameter \p in_eEvent describes the event that the file system volume has just experienced
*/
typedef void (*pfONFILESYSTEMEVENT)(char const* in_pszVolume, E_FileSysEvent in_eEvent, void* pOnNotifyUserData);

/*! \brief Enumeration describes the set of attributes that can be applied to a file search. See
           FindFileFirstFFS(). */
typedef enum
{
    FFS_FIND_FILES = 0x01,      /*!< Include files in the search */
    FFS_FIND_DIRECTORY = 0x02,  /*!< Include directories in the search */
} E_FindFileAttributes;

typedef uint1 FindFileAttributeMask_U;

/*! \brief Describes the structure of a find file object */
typedef struct
{
    uint4 size;                     /*!< The size of the file in bytes. Is undefined if the file is a directory */
    char name[FILENAME_PATH_LEN];   /*!< The complete name of the file */
    bool1 IsDirectory;
} S_FFSFindData;

/*! \brief Enumeration describes the set of file open modes supported by the file system */
typedef enum
{
/*! Opens the file for reading only. The file must exist and not be open for modification if the open is to succeed.
    The file pointer starts at the beginning of the file. */
    FFS_OPEN_READ_ONLY,            
/*! Opens an empty file for reading and writing. If the given file exists, its contents are destroyed. */
    FFS_OPEN_READ_WRITE,
/*! Opens a file for reading and writing in appended mode. The file pointer starts at the end of the file. */
    FFS_OPEN_APPEND,
/*! Opens a file for both reading and writing. The file must exist or this call will fail. The file pointer
    starts at the beginning of the file. */
    FFS_OPEN_EXIST_READ_WRITE,
} E_FFSOpenMode;

/*! \brief Enumeration describes the set of possible origins to use when specifying a file seek */
typedef enum
{
    FFS_SEEK_FROM_CURRENT,  /*!< The origin for the file seek shall be the current file position */
    FFS_SEEK_FROM_END,      /*!< The origin for the file seek shall be the end of the file */
    FFS_SEEK_FROM_START,    /*!< The origin for the file seek shall be the start of the file */

    FFS_NUM_OF_SEEK_MODES,
} E_FFSSeekOrigin;

typedef struct
{
    NativePtrSizedInt_U TheHandle;
} S_DontDeclareAnInstanceOfThisFileHandle;

typedef S_DontDeclareAnInstanceOfThisFileHandle* FFS_FILEHANDLE;

typedef struct
{
    NativePtrSizedInt_U TheHandle;
} S_DontDeclareAnInstanceOfThisSearchHandle;

typedef S_DontDeclareAnInstanceOfThisSearchHandle* FFS_SEARCH_HANDLE;

#pragma pack()
/*----- EXTERNALS -----------------------------------------------------------------------------------------*/

/*----- PROTOTYPES ----------------------------------------------------------------------------------------*/

FFS_FILEHANDLE OpenFileFFS(char const* in_pszFileName, E_FFSOpenMode in_eMode, NativeError_S* out_pErrorDetail);
NativeVar_S WriteFileFFS(void const* in_pDataToWrite, NativeVar_S in_sItemByteSize, NativeVar_S in_sNumItems, FFS_FILEHANDLE, NativeError_S* out_pErrorDetail);
NativeVar_S ReadFileFFS(void* out_pDataBuffer, NativeVar_S in_sItemByteSize, NativeVar_S in_sNumItems, FFS_FILEHANDLE, NativeError_S* out_pErrorDetail);
NativeError_S CloseFileFFS(FFS_FILEHANDLE hFileHandle);
NativeError_S SeekFileFFS(FFS_FILEHANDLE hFile, sint4 sByteOffset, E_FFSSeekOrigin eFileOrigin);
NativeError_S DeleteFileFFS(char const* in_psFileName);
sint4 GetFileLengthFFS(char const* in_pszFileName);
sint4 GetFilePointerFFS(FFS_FILEHANDLE hFile);
NativeError_S SetFileEndOfFileFFS(FFS_FILEHANDLE hFile);
FFS_SEARCH_HANDLE FindFileFirstFFS(char const* in_pszFileSpecification, FindFileAttributeMask_U, S_FFSFindData* out_pFindFileBuffer, NativeError_S* out_pErrorDetail);
NativeError_S FindFileNextFFS(FFS_SEARCH_HANDLE hSearchHandle, S_FFSFindData* out_pFindFileBuffer);
void FindFileClose(FFS_SEARCH_HANDLE hSearchHandle);

NativeError_S CreateDirectoryFFS(char const* in_pszDirectory);
NativeError_S RemoveDirectoryFFS(char const* in_pszDirectory);
NativeError_S SetDirectoryFFS(char const* in_pszDirectory);

NativeError_S RequestFileSystemEventNotifyFFS(pfONFILESYSTEMEVENT pfOnFileSysEvent, uint1 in_uEnabledEventsMask, void* pOnNotifyUserData);

sint4 GetDriveFreeBytesFFS(char const* in_pszDriveName);

NativeError_S CopyFileFFS(char const* in_pszFileToCopy, char const* in_pszCopiedFileName, NativeBool in_bFailIfExist);
NativeError_S RenameFileFFS(char const* in_pszExistingFileName, char const* in_pszNewFileName);
uint4 GetFileLengthWithHandleFFS(FFS_FILEHANDLE, NativeError_S*);

#endif /* __RESOURCE_FFS_H */

/*----- END OF FILE ---------------------------------------------------------------------------------------*/
