#ifndef _CEGOFILEHANDLER_H_INCLUDED_
#define _CEGOFILEHANDLER_H_INCLUDED_
///////////////////////////////////////////////////////////////////////////////
//                                                         
// CegoFileHandler.h
// -----------------
// Cego file handler class definition
//                                                         
// Design and Implementation by Bjoern Lemke
//
// (C)opyright 2000-2025 Bjoern Lemke
//
// INTERFACE MODULE
//
// Class: CegoFileHandler
// 
// Description: The filehandler class provides access to all datafiles. Datafiles consists
//              of a defined number of pages managed by the this class.
//              At the header of a datafile, a bitmap is stored for used page information
//
// Status: CLEAN
//
///////////////////////////////////////////////////////////////////////////////

#ifndef _REENTRANT
#define _REENTRANT    /* basic 3-lines for threads */
#endif

// LFC INCLUDES
#include <lfcbase/Chain.h>
#include <lfcbase/File.h>
#include <lfcbase/Logger.h>

// CEGO INCLUDES
#include "CegoLockHandler.h"
#include "CegoDefs.h"
#include "CegoModule.h"

class CegoFileHandler : public CegoModule {
    
public:
   
    enum FileType { DATAFILE, SYSTEMFILE, TEMP };

    CegoFileHandler(const Chain& logFile, const Chain& progName);
    ~CegoFileHandler();

    void setReadOnly(bool isReadOnly);
    
    void setBackup(unsigned fileId, bool m);

    bool needPageBackup(PageIdType pageId);
    bool isPageMarked(PageIdType pageId, unsigned fileId);

    void initDataFile(unsigned tabSetId, const Chain& path, unsigned fileId, unsigned numPages, PageIdType pageOffset, FileType ft);

    void regDataFile(unsigned tabSetId, const Chain& path, unsigned fileId, CegoLockHandler* pLockHandle);

    void resetDataFile(unsigned fileId);
	
    void writePage(PageIdType pageId, unsigned fixStat, char* pageData, CegoLockHandler* pLockHandle);
    void readPage(PageIdType pageId, unsigned& tabSetId, unsigned& fixStat, char* pageData, CegoLockHandler* pLockHandle);
    
    void claimPage(PageIdType pageId, CegoLockHandler* pLockHandle);
    void allocatePage(unsigned tabSetId, FileType ft, PageIdType& pageId, CegoLockHandler* pLockHandle, unsigned* &fbm, unsigned& fbmSize, bool doAppend = false);
    void releasePage(PageIdType pageId, CegoLockHandler* pLockHandle, unsigned* &fbm, unsigned& fbmSize);

    void releaseFiles(unsigned tabSetId);

    unsigned getNumPages(unsigned fileId);
    unsigned getNumUsedPages(unsigned fileId, CegoLockHandler* pLockHandle);

    PageIdType getPageOffset(unsigned fileId);

    PageIdType getMaxPageOffset();
    
    bool isClaimed(PageIdType pageId, CegoLockHandler *pLockHandle);
    
    void writeFBM(unsigned fileId, unsigned *fbm, CegoLockHandler *pLockHandle);

    unsigned getFileIdForPageId(PageIdType pageId);

    void commitPageEntry(PageIdType pageId);
    unsigned cleanPages(CegoLockHandler *pLockHandle);
    
protected:
    
    unsigned _pageSize;

private:

    unsigned getFBMSize(unsigned fileId);
    void readFBM(unsigned fileId, unsigned *fbm, CegoLockHandler *pLockHandle);
    void markPage(PageIdType pageId);
    File* getHandle(unsigned fileId);
    void printBitMap(unsigned bm);
    unsigned mapDiff(unsigned bm1, unsigned bm2);
	    
    bool _isReg[FILMNG_MAXDATAFILE];
    unsigned _tabSetId[FILMNG_MAXDATAFILE];
    unsigned _fileType[FILMNG_MAXDATAFILE];
    unsigned _numPages[FILMNG_MAXDATAFILE];
    PageIdType _pageOffset[FILMNG_MAXDATAFILE];
    File* _fhList[FILMNG_MAXDATAFILE];
    Chain _path[FILMNG_MAXDATAFILE];
    unsigned* _buMask[FILMNG_MAXDATAFILE];
    unsigned* _commitMask[FILMNG_MAXDATAFILE];
    bool _fbmMask[FILMNG_MAXDATAFILE];
    PageIdType _appendPos[FILMNG_MAXDATAFILE];
    unsigned _appendFid;
    bool _isReadOnly;
    
    unsigned long _modId;
};
#endif
