#ifndef FATFILESYSTEM_H_
#define FATFILESYSTEM_H_


typedef enum{
    FAT_SD_CARD
}FAT_DEVICE;

typedef enum{
    FILE_SEEK_BEGIN,
    FILE_SEEK_CURRENT,
    FILE_SEEK_END
}FAT_SEEK_POS;

#pragma pack(1)
//#pragma pack(push, 1)

typedef struct{
    char Name[8];
    char Extension[3];
    char Attribute;
    char reserved[2]; 
    unsigned short CreateTime;
    unsigned short CreateDate;
    unsigned short LastAccessDate;
    unsigned short FirstLogicalClusterHi; // not used in FAT12/FAT16
    unsigned short LastWriteTime;
    unsigned short LastWriteDate;
    unsigned short FirstLogicalCluster;
    unsigned int FileSize;
}FAT_DIRECTORY;

//#pragma pack(pop)
#pragma pack()

typedef struct{
    bool IsOpened;
    unsigned int SeekPos;
    unsigned int Cluster;
    unsigned int ClusterSeq; // zero base
    FAT_DIRECTORY Directory;
}FAT_FILE_HANDLE;

typedef struct{
    unsigned int DirectoryIndex;
}FAT_BROWSE_HANDLE;

typedef struct{
    char szName[256];
    char szExt[8];
    unsigned int nFileSize;
}FILE_INFO;



// Device Mount/Unmount
bool Fat_Mount(FAT_DEVICE FatDevice);
void Fat_Unmount(void);

// FAT Browse
unsigned int Fat_FileCount(void);
void Fat_ComposeFilename(FAT_DIRECTORY *pDir, char *szFilename);
bool Fat_FileBrowseBegin(FAT_BROWSE_HANDLE *pFatBrowseHandle);
bool Fat_FileBrowseNext(FAT_BROWSE_HANDLE *pFatBrowseHandle, FAT_DIRECTORY *pDirectory);



// File Access
bool Fat_FileOpen(FAT_FILE_HANDLE *pFileHandle, const char *pFilename);
unsigned int Fat_FileSize(FAT_FILE_HANDLE *pFileHandle);
bool Fat_FileRead(FAT_FILE_HANDLE *pFileHandle, void *pBuffer, const int nBufferSize);
bool Fat_FileSeek(FAT_FILE_HANDLE *pFileHandle, const FAT_SEEK_POS SeekPos, const int nOffset);
void Fat_FileClose(FAT_FILE_HANDLE *pFileHandle);
bool Fat_FileIsOpened(FAT_FILE_HANDLE *pFileHandle);

//
void Fat_Dump(FAT_DIRECTORY *pDirectory);



#endif /*FATFILESYSTEM_H_*/
