//================================================================
// Directory library header file
//
// AUTHOR:  Gabor Nagy
// DATE:    2026-Jun-17 01:42:57
//
// Copyright (C) 1996-2026 by Gabor Nagy. All rights reserved.
//================================================================
#ifndef _EDir_h
#define _EDir_h

#include <stdarg.h>		// For varargs
#include <sys/types.h>
#include <sys/stat.h>

#include <EParam.h>
#include <EResource.h>

#if defined (__cplusplus) && (!(defined (__CPLUSLIBS)))
extern "C" {
#endif

#ifdef WIN32
#include <dos.h>
#include <dir.h>
#endif

#ifdef UNIX
#include <sys/dir.h>
#endif

#include <time.h>
#include <stdlib.h>

#include <EStrings.h>


#ifdef UNIX
#ifdef sgi
#include <sys/statvfs.h>
#endif
#endif

#define EdirENTRY_ALLOC_STEP	64

#define	MAX_LINELEN	512

enum { EdirSortNAME_INC = 0, EdirSortNAME_DEC, EdirSortTIME_INC, EdirSortTIME_DEC, EdirSortSIZE_INC, EdirSortSIZE_DEC };
enum { EdirENTRY_NORMAL=0, EdirENTRY_CURRENT_DIR, EdirENTRY_PARENT_DIR };

// Flags to determine what to display in the directory list
//
#define EdirATTR_FLAGS    0x01
#define EdirUSER          0x02
#define EdirGROUP         0x04
#define EdirNUM_OF_LINKS  0x08
#define EdirSIZE          0x10
#define EdirDIR_SIZE      0x20
#define EdirTIME          0x40


#define EdirINCLUDE_CURRENT_DIR         0x0001
#define EdirINCLUDE_PARENT_DIR          0x0002
#define EdirFILE_FILTER_CASE_SENSITIVE  0x0004
#define EdirDIR_FILTER_CASE_SENSITIVE   0x0008


#ifdef UNIX
#define EDirentryUNIXFields\
	unsigned long long  RealSize;                  /* In case it's a symbolic link */\
	char*               RealName;
#else
#define EDirentryUNIXFields
#endif

#define EDirEntryCore\
	uint32_t            IsDir : 1, IsNFS : 1;\
	nlink_t             NumOfLinks;\
	uid_t               UID;\
	gid_t               GID;\
	unsigned long long  Size;\
	mode_t              Mode;\
	time_t              ATime, CTime, MTime;\
	char*               Name;\
	const EIOModule*    Format;\
	EDirentryUNIXFields\

typedef struct
{
	EDirEntryCore;
} EDirEntry;

EList_t(EDirEntry);
EListA_t(EDirEntry);

extern EStrFilterTokens	EDir_UNIXFilterTokens;	// Filter token strings for UNIX "*" "[" "]"

extern int     EDir_Max_EntryNum;

extern int     EDir_PathType(const char* PPath, const EBool PResolveSymLink);

extern int     EDir_GetDir(const char* PEntryName, const uint16_t PFlags, const void* PDirFilter, const void* PFileFilter, const EStrFilterTokens* PFilterTokens,  const EIndex PStructSize,
                EDirEntry** PEntriesPtr, EIndex* PNumOfEntriesPtr, EIndex* PNumOfEntriesAllocatedPtr,  EIndex* PNumOfDirsPtr,  long long* PTotalSizeRet);

extern int     EDir_RecurseDir(const char* PDirectory, const EBool PDoNFS, const EBool PDoSymLinks, EIndex* PNumOfDirsRet, int (*LCallback)(EDirEntry* PEntry, const char* PPath,
                const EIndex PNumOfDirsSoFar, const EIndex PNumOfFilesSoFar, EPointer PClientData), EPointer PClientData);

extern int     EDir_GetSizeOfDir(const char* PDirectory, const EBool PDoNFS, const EBool PDoSymLinks, long long* PTotalSizeRet, EIndex* PNumOfFilesRet, EIndex* PNumOfDirsRet);

extern EIOModule*  EDirEntry_GetFormat(const char* PFileName, FILE* PFile);

extern void    EDirEntry_FreeContents(EDirEntry* PEntry);

extern void    EDirEntry_FreeArray(EDirEntry* PEntries, const EIndex PN, const EIndex PStructSize);

#if defined (__cplusplus) && (!(defined (__CPLUSLIBS)))
}	// Close scope of 'extern "C"' declaration
#endif

#endif // _EDir_h
