/*=============================================================================
 *
 *  Filename:                   BigFile.C
 *  Version:            1.1
 *  Date:               08/97
 *  Author:             1.0 / Vincent Lhuillier
 *                      1.1 / Adrian Silvescu, Laurentiu Barza, Yan Marchal
 *
 *  Description:        Definitions of functions for accessing BigFile
 *
 *===========================================================================*/

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#include <time.h>
#include <direct.h>
#include <io.h>
#include <windows.h>

#define __DeclareGlobalVariableErrMrc_h__
#include "MRC\ErrMrc.h"
#undef  __DeclareGlobalVariableErrMrc_h__
#define __DeclareGlobalVariableMmgMrc_h__
#include "MRC\MmgMrc.h"
#undef  __DeclareGlobalVariableMmgMrc_h__

#include "mrc.h"

#define _DEFINE_CPA_MMG_MEMORY_ALLOCATION_
#define MAX_BUFF 4096

/*=============================================================================
* GLOBALES
=============================================================================*/
        #define MRC_C_ucIsData      0
        #define MRC_C_ucIsPatch 1

        char *MRC_ga_szReadTypeString[ 2 ]=
        {
                "Synchronous",
                "Asynchronous"
        };

        /* globals for external mode */
        MRC_tdstFileEntry MRC_g_stExternalFileEntry;
        char  MRC_g_szExternalFileName[256];

        /* ever used globals */
        char                                    *MRC_g_szDataPath = (char *) NULL;  /* path to root directory of data */
        char                                    *MRC_g_szPatchPath = (char *) NULL; /* path to directory where patch are stocked */
        unsigned char   MRC_g_ucCurrentIsDataPath = MRC_C_ucDataPathIsCurrent;                  
        char                                    MRC_g_szFullName[256];


/*=============================================================================
* FUNCTIONS for printing DEBUG INFO in a file
=============================================================================*/

/*-----------------------------------------------------------------------------
 *  Description : Auxiliary function (gets the name of a file from its complete Path)
 *---------------------------------------------------------------------------*/

char* fn_sz_GetName(char* szName)
{
        char* p_str;
        char* retv;
        char* p1_str;
#ifdef _DEFINE_CPA_MMG_MEMORY_ALLOCATION_
        M_MrcAlloc (E_ucDynamic, retv , char * , 256 );
#else
        retv = (char *) malloc ( 256 );
#endif
        p_str = strrchr( szName, '\\' );
    if ( p_str != NULL )
        {
                p_str = p_str + 1 ; 
        }
        else
        {
                p_str = szName;
        }
        p1_str = strchr(p_str , '.');
        strncpy( retv , p_str , (p1_str - p_str) );
        retv[(p1_str - p_str)] = (char)0;
        return retv;
}


/*-----------------------------------------------------------------------------
 *  Description : Initialise variable for debug info file
 *-----------------------------------------------------------------------------
 *  Input :             none
 *  Output :    none
 *-----------------------------------------------------------------------------
 *  Creation date : 05/06/96            Author : V.L.
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
void MRC_fn_vOpenBigFileDebugFiles( MRC_tdstBigFile *p_stBigFile , char* szFileName )
{
        char* szName;
        char* sz1Name;
        szName = fn_sz_GetName( szFileName );
#ifdef _DEFINE_CPA_MMG_MEMORY_ALLOCATION_
        M_MrcAlloc( E_ucDynamic, sz1Name , char * , 256 );
#else
        sz1Name = (char *) malloc ( 256 );
#endif
        strcpy(sz1Name,szName);
                if ( p_stBigFile->ucMode & MRC_C_ucDebugMode )
                {
                        p_stBigFile->hpDebugBigFile = fopen( MRC_fn_p_szGetFullFileName ( strcat(szName,"debug.inf"), MRC_C_ucIsData), "wt");
                        if (p_stBigFile->hpDebugBigFile == NULL)
                                exit (-1);
                }
        
                if (p_stBigFile->ucMode & MRC_C_ucProfileMode )
                {
                        p_stBigFile->hpProfileBigFile = fopen( MRC_fn_p_szGetFullFileName( strcat(sz1Name,"profile.inf"), MRC_C_ucIsData), "wt");
                        if (p_stBigFile->hpProfileBigFile == NULL)
                                exit (-2);
                }
#ifdef _DEFINE_CPA_MMG_MEMORY_ALLOCATION_
        M_MrcFree( E_ucDynamic , szName );
#else
        free( szName );
#endif
#ifdef _DEFINE_CPA_MMG_MEMORY_ALLOCATION_
        M_MrcFree( E_ucDynamic , sz1Name );
#else
        free( sz1Name );
#endif
        
}

/*-----------------------------------------------------------------------------
 *  Description : Close debug info file
 *-----------------------------------------------------------------------------
 *  Input :             none
 *  Output :    none
 *-----------------------------------------------------------------------------
 *  Creation date : 05/06/96            Author : V.L.
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
void MRC_fn_vCloseBigFileDebugFiles( MRC_tdstBigFile *p_stBigFile )
{
        if (p_stBigFile->ucMode & MRC_C_ucDebugMode )
                fclose( p_stBigFile->hpDebugBigFile );
        
        if (p_stBigFile->ucMode & MRC_C_ucProfileMode )
                fclose( p_stBigFile->hpProfileBigFile );
}

/*-----------------------------------------------------------------------------
 *  Description : print a read access info on the profil file.
 *                                                              BigFile must be in C_ucProfileMode mode when calling this function
 *-----------------------------------------------------------------------------
 *  Input :             pointer on a tdstFileEntry structure
 *  Output :    none
 *-----------------------------------------------------------------------------
 *  Creation date : 05/06/96            Author : V.L.
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
void MRC_fn_vPrintReadAccess( char *szFileName, char bAsyncRead, long lOffset, long lLength , MRC_tdstBigFile *p_stBigFile)
{
        time_t                  lTime;
        struct tm               *p_stTime;
        char                            *p_szReadType;

        p_szReadType = MRC_ga_szReadTypeString[ bAsyncRead?1:0 ];
        time( &lTime );
        p_stTime = localtime( &lTime );

        fprintf(p_stBigFile->hpProfileBigFile,"%2d:%2d:%2d (%d) %s %d %d %s\n",
                                                p_stTime->tm_hour, p_stTime->tm_min, p_stTime->tm_sec,
                                                lTime, szFileName, lOffset, lLength, p_szReadType );
}

/*-----------------------------------------------------------------------------
 *  Description : print FileEntry info in debug info file
 *                                                              BigFile must be in C_ucDebugMode mode when calling this function
 *-----------------------------------------------------------------------------
 *  Input :             pointer on a tdstFileEntry structure
 *  Output :    none
 *-----------------------------------------------------------------------------
 *  Creation date : 05/06/96            Author : V.L.
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
void MRC_fn_vPrintFileEntryInfos( MRC_tdstFileEntry *p_stFile , MRC_tdstBigFile *p_stBigFile)
{
        char acName[13];

        if ((p_stFile == NULL) || (p_stFile->wPlace == MRC_C_wInexistentFile) )
                fprintf( p_stBigFile->hpDebugBigFile, "FileEntry : NULL\n");
        else
        {
                strcpy (acName, p_stFile->szName);
                while (strlen(acName) < 12)
                        strcat( acName, " ");

                fprintf( p_stBigFile->hpDebugBigFile, "FileEntry : %s -> Infos (%3d) ", acName, p_stFile->lInfos);                switch (p_stFile->wPlace)
                {
                        case MRC_C_wInternalFile:
                                        fprintf (p_stBigFile->hpDebugBigFile, "Pos (%8d,%8d)\n", p_stFile->lOffset, p_stFile->lLength );           
                                break;
                        case MRC_C_wExternalFile:
                                        fprintf (p_stBigFile->hpDebugBigFile, "Length (%8d), Externe File : %s\n", p_stFile->lLength, p_stFile->szExternFile);
                                break;
                        default:
                                        fprintf (p_stBigFile->hpDebugBigFile, "Pos (%8d,%8d), Patch (%d)\n", p_stFile->lOffset, p_stFile->lLength, p_stFile->wPlace );             
                }
        }
}

/*-----------------------------------------------------------------------------
 *  Description : print bigfile info in debug info file
 *  BigFile must be in C_ucDebugMode mode when calling this function
 *-----------------------------------------------------------------------------
 *  Input :             pointer on a MRC_tdstBigFile structure
 *  Output :    none
 *-----------------------------------------------------------------------------
 *  Creation date : 05/06/96            Author : V.L.
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
void MRC_fn_vPrintBigFileInfos( MRC_tdstBigFile *p_stBigFile )
{
        char                            acName[13];
        short                           wIndex;
        MRC_tdstDirectoryEntry      *p_stDir = p_stBigFile->pa_stDir;
        MRC_tdstFileEntry                           *p_stFile = p_stBigFile->pa_stFile;
        MRC_tdstDataPatch                           *p_stPatch = p_stBigFile->pa_stPatch;

        if ( p_stBigFile->ucMode & MRC_C_ucExternalMode )
        {
                fprintf( p_stBigFile->hpDebugBigFile, "/***** BigFile Infos ********/\n");
                fprintf( p_stBigFile->hpDebugBigFile, "All files are external\n");
                return;
        }
                
        /* printing bigfile infos */
        fprintf( p_stBigFile->hpDebugBigFile, "/***** BigFile Infos ********/\n");
        fprintf( p_stBigFile->hpDebugBigFile, "\tName            : %s\n", p_stBigFile->szName);
        fprintf( p_stBigFile->hpDebugBigFile, "\tVersion         : %d\n", p_stBigFile->lVersion);
        fprintf( p_stBigFile->hpDebugBigFile, "\tFirst Data      : %d\n", p_stBigFile->lFirstData);
        fprintf( p_stBigFile->hpDebugBigFile, "\tNumber of Dirs  : %d\n", p_stBigFile->wNumberOfDirs);
        fprintf( p_stBigFile->hpDebugBigFile, "\tNumber of Files : %d\n", p_stBigFile->wNumberOfFiles);
        fprintf( p_stBigFile->hpDebugBigFile, "\tNumber of Patchs: %d\n", p_stBigFile->wNumberOfPatchs);
        fprintf( p_stBigFile->hpDebugBigFile, "\n");
        
        /* for each dir print info */
        fprintf( p_stBigFile->hpDebugBigFile, "\t/***** Directory List *******/\n");
        for (wIndex = 0; wIndex < p_stBigFile->wNumberOfDirs; wIndex ++)
        {
                strcpy (acName, p_stDir->szName);
                while (strlen(acName) < 12)
                        strcat( acName, " ");

                fprintf( p_stBigFile->hpDebugBigFile, "\t%3d : %s -> Subdirs (%3d,%3d) Files (%3d,%3d)\n",
                                        wIndex,
                                        acName,
                                        p_stDir->wFirstSubDir,
                                        p_stDir->wNumberOfSubDirs,
                                        p_stDir->wFirstFile,
                                        p_stDir->wNumberOfFiles
                                );
                p_stDir ++;
        }
        fprintf( p_stBigFile->hpDebugBigFile, "\n");

        /* for each file, print info */
        fprintf( p_stBigFile->hpDebugBigFile, "\t/***** File List ************/\n");
        for (wIndex = 0; wIndex < p_stBigFile->wNumberOfFiles; wIndex ++)
        {
                fprintf(p_stBigFile->hpDebugBigFile, "\t");
                MRC_fn_vPrintFileEntryInfos( p_stFile , p_stBigFile );
                p_stFile ++;
        }
        fprintf( p_stBigFile->hpDebugBigFile, "\n");

        /* For each patch print infos    */
        fprintf( p_stBigFile->hpDebugBigFile, "\t/***** Patch List ************/\n");
        for (wIndex = 0; wIndex < p_stBigFile->wNumberOfPatchs; wIndex ++)
        {
                fprintf( p_stBigFile->hpDebugBigFile, "Patch %2d : version(%8d),FirstData(%8d), %s\n",
                                                        wIndex, p_stPatch->lVersion, p_stPatch->lFirstData, p_stPatch->szName );
                p_stPatch ++;
        }
        fprintf( p_stBigFile->hpDebugBigFile, "\n");
}

/*-----------------------------------------------------------------------------
 *  Description : print MRC_tdstFileDescription info in debug info file
 *  BigFile must be in C_ucDebugMode mode when calling this function
 *-----------------------------------------------------------------------------
 *  Input :             pointer on a MRC_tdstFileDescription structure
 *  Output :    none
 *-----------------------------------------------------------------------------
 *  Creation date : 05/06/96            Author : V.L.
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
void MRC_fn_vPrintFileDescriptionInfos( MRC_tdstFileDescription *p_stFile )
{
        if (p_stFile)
        {
                fprintf( p_stFile->p_stBigFile->hpDebugBigFile,"File : (%d %d %d), pos = %d\n",
                                                                        p_stFile->eType, p_stFile->eMode, p_stFile->eState, 
                                                                        p_stFile->lPosition );
                MRC_fn_vPrintFileEntryInfos( p_stFile->p_stFileEntry , p_stFile->p_stBigFile);
        }
        else
                fprintf( p_stFile->p_stBigFile->hpDebugBigFile,"File : NULL\n");
}

/*=============================================================================
*
* FUNCTION TO INIT DATA & PATCH PATH
*
=============================================================================*/

/*-----------------------------------------------------------------------------
 *  Description : go into a path
 *-----------------------------------------------------------------------------
 *  Input :     pth name
 *  Output : an error value
 *-----------------------------------------------------------------------------
 *  Creation date : 05/06/96            Author : V.L.
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
long MRC_fn_lChangeDirectory( char *szPath )
{
        if (
#ifdef WATCOM
                        chdir
#else
                        _chdir
#endif
                        ( szPath ))
        {
                M_MrcError( E_uwMrcWarningInvalidPath );
                return (E_uwMrcWarningInvalidPath);
        }
        return( E_uwMrcWarningNone );
}

/*-----------------------------------------------------------------------------
 *  Description : verify existence of a path
 *-----------------------------------------------------------------------------
 *  Input :     a pointer on path name 
  *  Output : an error value
 *-----------------------------------------------------------------------------
 *  Creation date : 05/06/96            Author : V.L.
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
long fn_l_VerifyPath( char *szPath )
{
        long lError;
        char szCurrentDir[256];
        
#ifdef WATCOM
                getcwd
#else
        _getcwd
#endif
                ( szCurrentDir , 255);
        lError = MRC_fn_lChangeDirectory( szPath );
#ifdef WATCOM 
                chdir
#else
                _chdir
#endif
                ( szCurrentDir );

        return ( lError );
}

/*-----------------------------------------------------------------------------
 *  Description : initialize data path and verify it
 *-----------------------------------------------------------------------------
 *  Input :     a pointer on path name, dataPath mode : 
 *                                              C_ucDataPathIsCurrent or C_ucDataPathIsNotCurrent
 *  Output : an error value
 *-----------------------------------------------------------------------------
 *  Creation date : 05/06/96            Author : V.L.
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
long MRC_fn_lInitDataPath( char *szDataPath, unsigned char ucMode )
{
        long lError;

        if ( (lError = fn_l_VerifyPath( szDataPath ) ) == E_uwMrcWarningNone )
        {
                MRC_g_ucCurrentIsDataPath = ucMode;
#ifdef _DEFINE_CPA_MMG_MEMORY_ALLOCATION_
                M_MrcAlloc(E_ucDynamic, MRC_g_szDataPath , char * , (strlen(szDataPath)+1) );
#else
                MRC_g_szDataPath = (char *) malloc (strlen(szDataPath) + 1);
#endif
                                strcpy( MRC_g_szDataPath, szDataPath );
        }
        return ( lError );
}

/*-----------------------------------------------------------------------------
 *  Description : initialize Patches path and verify it
 *-----------------------------------------------------------------------------
 *  Input :     a pointer on path name
 *  Output : an error value
 *-----------------------------------------------------------------------------
 *  Creation date : 05/06/96            Author : V.L.
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
long MRC_fn_lInitPatchPath( char *szPatchPath )
{
        long lError;

        if ( (lError = fn_l_VerifyPath( szPatchPath ) ) == E_uwMrcWarningNone )
        {
#ifdef _DEFINE_CPA_MMG_MEMORY_ALLOCATION_
                M_MrcAlloc(E_ucDynamic, MRC_g_szPatchPath , char * , (strlen(szPatchPath) + 1));
#else
                MRC_g_szPatchPath = (char *) malloc (strlen(szPatchPath) + 1);
#endif
                strcpy( MRC_g_szPatchPath, szPatchPath );
        }
        return ( lError );
}

/*-----------------------------------------------------------------------------
 *  Description : change data path mode
 *-----------------------------------------------------------------------------
 *  Input :     a data path mode (C_ucDataPathIsCurrent ou C_ucDataPathIsNotCurrent)
 *  Output : none
 *-----------------------------------------------------------------------------
 *  Creation date : 05/06/96            Author : V.L.
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
void MRC_fn_vChangeDataPathMode( unsigned char ucMode )
{
        MRC_g_ucCurrentIsDataPath = ucMode;
}

/*-----------------------------------------------------------------------------
 *  Description : free path
 *-----------------------------------------------------------------------------
 *  Input :     none
 *  Output : none
 *-----------------------------------------------------------------------------
 *  Creation date : 05/06/96            Author : V.L.
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
void MRC_fn_vFreePath( void )
{
        if (MRC_g_szDataPath)
        {
#ifdef _DEFINE_CPA_MMG_MEMORY_ALLOCATION_
                        M_MrcFreeWithoutSetMode(MRC_g_szDataPath);
#else
            free(MRC_g_szDataPath);
#endif                                  
                                        
            MRC_g_szDataPath = 0;
        }
        if (MRC_g_szPatchPath)
        {
#ifdef _DEFINE_CPA_MMG_MEMORY_ALLOCATION_
                        M_MrcFreeWithoutSetMode (MRC_g_szPatchPath);
#else
            free (MRC_g_szPatchPath);
#endif
                                        
            MRC_g_szPatchPath = 0;
        }
}

/*-----------------------------------------------------------------------------
 *  Description : go into data path
 *-----------------------------------------------------------------------------
 *  Input :     none
 *  Output : an error value
 *-----------------------------------------------------------------------------
 *  Creation date : 05/06/96            Author : V.L.
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
long MRC_fn_lGotoDataDir( void )
{
        return (MRC_fn_lChangeDirectory( MRC_g_szDataPath ) );
}

/*-----------------------------------------------------------------------------
 *  Description : go into patch path
 *-----------------------------------------------------------------------------
 *  Input :     none
 *  Output : an error value
 *-----------------------------------------------------------------------------
 *  Creation date : 05/06/96            Author : V.L.
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
long MRC_fn_lGotoPatchDir( void )
{
        return (MRC_fn_lChangeDirectory( MRC_g_szPatchPath ) );
}

/*-----------------------------------------------------------------------------
 *  Description : return full name in a user-supplied buffer
 *-----------------------------------------------------------------------------
 *  Input :     pointer on name, pointer on path
 *  Output : pointer on full name
 *-----------------------------------------------------------------------------
 *  Creation date : 05/06/96            Author : V.L.
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
char *MRC_fn_p_szGetFullFileName( char *szFileName, unsigned char ucType )
{
        char *szPath;

        if (ucType == MRC_C_ucIsData )
        {
                if ( MRC_g_ucCurrentIsDataPath || (MRC_g_szDataPath == NULL))
                        return szFileName;
                else
                        szPath = MRC_g_szDataPath;
        }
        else
        {
                if (MRC_g_szPatchPath == NULL)
                        return szFileName;
                else
                        szPath = MRC_g_szPatchPath;
        }

        strcpy( MRC_g_szFullName, szPath);
        strcat( MRC_g_szFullName, "\\");
        strcat( MRC_g_szFullName, szFileName);

        return (MRC_g_szFullName);
}


/*=============================================================================
*
* FUNCTION TO INIT, OPEN & CLOSE BIGFILE
*
=============================================================================*/

/*-----------------------------------------------------------------------------
 *  Description : Read a BigFile & setup bigfile members
 *-----------------------------------------------------------------------------
 *  Input :     a pointer on a BigFile structure and bigfile name
 *  Output : none
 *-----------------------------------------------------------------------------
 *  Creation date : 05/06/96            Author : V.L.
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
e_uwMrcErrNumber MRC_fn_lReadBigFile( MRC_tdstBigFile *p_stBigFile, char *szFileName, short wPlace )
{
        MRC_tdstDirectoryEntry      *p_stDir;
        MRC_tdstFileEntry           *p_stFile;
        MRC_tdstShortChunk          stChunk;
        MRC_tdstDLst                *p_stDLst;
        MRC_tdstFLst                *p_stFLst;
        FILE                        *hpFile;
        FILE                        *hpExternalFile;
        char                        *szNameList;
        char                        *szName;
        long                        lValue;
        short                       wNbDirs;
        short                       wNbFiles;
        short                       wIndex;

        /*
         * Opening File
         */
        hpFile = p_stBigFile->hpBigFile = fopen( MRC_fn_p_szGetFullFileName(szFileName, MRC_C_ucIsData), "rb");

        if (hpFile == NULL)
        {
                M_MrcError( E_uwMrcWarningBigFileNotFound );
                return ( E_uwMrcWarningBigFileNotFound );
        }
#ifdef _DEFINE_CPA_MMG_MEMORY_ALLOCATION_
        M_MrcAlloc(E_ucDynamic, p_stBigFile->szName , char * , ( strlen(szFileName) + 1));
#else
        p_stBigFile->szName = (char *) malloc ( strlen(szFileName) + 1);
#endif
        strcpy(p_stBigFile->szName, szFileName);
        
        /* Read bigfile info */
        fread( &stChunk, sizeof(MRC_tdstShortChunk), 1, hpFile );
        fread( &stChunk, sizeof(MRC_tdstShortChunk), 1, hpFile );
        memcpy((char *)&p_stBigFile->lVersion, stChunk.acInfo, 4);

        /* Read File system chunk */
        fread( &stChunk, sizeof(MRC_tdstShortChunk), 1, hpFile );

        /* Read Dir List */
        fseek( hpFile, 4, SEEK_CUR );
        fread( &lValue, 4, 1, hpFile );
        
        wNbDirs = p_stBigFile->wNumberOfDirs = (short)(lValue / sizeof(MRC_tdstDLst));
#ifdef _DEFINE_CPA_MMG_MEMORY_ALLOCATION_ 
                M_MrcAlloc(E_ucDynamic, p_stBigFile->pa_stDir , MRC_tdstDirectoryEntry * , (wNbDirs * sizeof(MRC_tdstDirectoryEntry))) ;
#else
                p_stBigFile->pa_stDir = (MRC_tdstDirectoryEntry *) malloc (wNbDirs * sizeof(MRC_tdstDirectoryEntry) );
#endif

#ifdef _DEFINE_CPA_MMG_MEMORY_ALLOCATION_
        M_MrcAlloc(E_ucDynamic, p_stDLst , MRC_tdstDLst * , (lValue));
#else
        p_stDLst = (MRC_tdstDLst *) malloc (lValue);
#endif

        fread( p_stDLst, lValue, 1, hpFile);    

        /* Read File List */
        fseek( hpFile, 4, SEEK_CUR );
        fread( &lValue, 4, 1, hpFile );
        
        wNbFiles = p_stBigFile->wNumberOfFiles = (short)(lValue / sizeof(MRC_tdstFLst));
#ifdef _DEFINE_CPA_MMG_MEMORY_ALLOCATION_
        M_MrcAllocWithoutSetMode(p_stBigFile->pa_stFile , MRC_tdstFileEntry * , (wNbFiles * sizeof(MRC_tdstFileEntry) ));
#else
        p_stBigFile->pa_stFile = (MRC_tdstFileEntry *) malloc (wNbFiles * sizeof(MRC_tdstFileEntry) );
#endif
#ifdef _DEFINE_CPA_MMG_MEMORY_ALLOCATION_
        M_MrcAllocWithoutSetMode(p_stFLst , MRC_tdstFLst * , (lValue));
#else
        p_stFLst = (MRC_tdstFLst *) malloc (lValue);
#endif

        fread( p_stFLst, lValue, 1, hpFile);    

        /* Read Name List */
        fseek( hpFile, 4, SEEK_CUR );
        fread( &lValue, 4, 1, hpFile );
#ifdef _DEFINE_CPA_MMG_MEMORY_ALLOCATION_
        M_MrcAllocWithoutSetMode(szNameList , char * , (lValue));
#else
        szNameList = (char *) malloc (lValue);
#endif
        fread ( szNameList, lValue, 1, hpFile);

        /* Save DLst list in bigFile Dir table */
        p_stDir = p_stBigFile->pa_stDir;
        for (wIndex = 0; wIndex < wNbDirs; wIndex ++)
        {
                szName = (char *) &szNameList[ p_stDLst[wIndex].lNameOffset ];
#ifdef _DEFINE_CPA_MMG_MEMORY_ALLOCATION_
                M_MrcAllocWithoutSetMode(p_stDir->szName , char * , (strlen(szName) + 1));
#else
                p_stDir->szName = (char *) malloc (strlen(szName) + 1);
#endif
                strcpy( p_stDir->szName, szName);
                p_stDir->wNumberOfSubDirs = (short)p_stDLst[wIndex].lNumberOfSubDirs;
                p_stDir->wFirstSubDir = (short)p_stDLst[wIndex].lFirstSubDir;
                p_stDir->wNumberOfFiles = (short)p_stDLst[wIndex].lNumberOfFiles;
                p_stDir->wFirstFile = (short)p_stDLst[wIndex].lFirstFile;
                p_stDir ++;
        }
        
        /* Save FLst list in bigFile File table */
        p_stFile = p_stBigFile->pa_stFile;
        for (wIndex = 0; wIndex < wNbFiles; wIndex ++)
        {       
                szName = (char *) &szNameList[ p_stFLst[wIndex].lNameOffset ];
#ifdef _DEFINE_CPA_MMG_MEMORY_ALLOCATION_
                M_MrcAllocWithoutSetMode(p_stFile->szName , char * , (strlen(szName) + 1));
#else
                p_stFile->szName = (char *) malloc (strlen(szName) + 1);
#endif
                strcpy( p_stFile->szName, szName);
                
                p_stFile->lLength = p_stFLst[ wIndex ].lLength;
                p_stFile->lOffset = p_stFLst[ wIndex ].lOffset;
                p_stFile->lInfos = p_stFLst[ wIndex ].lInfo;
                p_stFile->wPlace = wPlace;

                if (p_stFile->lLength == MRC_C_wExternalFile)
                {
                        szName = (char *) &szNameList[ p_stFile->lOffset ];
#ifdef _DEFINE_CPA_MMG_MEMORY_ALLOCATION_
                        M_MrcAllocWithoutSetMode(p_stFile->szExternFile , char * , ( strlen(szName) + 1));
#else
                        p_stFile->szExternFile = (char *) malloc ( strlen(szName) + 1);
#endif
                        strcpy( p_stFile->szExternFile, szName );

                        if ( (hpExternalFile = fopen( MRC_fn_p_szGetFullFileName(szName, MRC_C_ucIsData), "rb" )) == NULL)
                                p_stFile->wPlace = MRC_C_wInexistentFile    ;
                        else
                        {
                                p_stFile->wPlace = MRC_C_wExternalFile;
                                p_stFile->lOffset = 0;
                                fseek( hpExternalFile, 0, SEEK_END );
                                p_stFile->lLength = ftell( hpExternalFile );
                                fclose (hpExternalFile);
                        }
                }
                else
                        p_stFile->szExternFile = NULL;
                
                p_stFile ++;
        }

        /* Read chunk of File Storage */
        fread( &stChunk, sizeof(MRC_tdstShortChunk), 1, hpFile );
        
        p_stBigFile->lFirstData = ftell( hpFile );

        /* free local pointer */
#ifdef _DEFINE_CPA_MMG_MEMORY_ALLOCATION_
        M_MrcFreeWithoutSetMode( p_stDLst );
#else
        free( p_stDLst );
#endif                  
                        

#ifdef _DEFINE_CPA_MMG_MEMORY_ALLOCATION_
        M_MrcFreeWithoutSetMode( szNameList );
#else
        free ( szNameList );
#endif                  
                        
#ifdef _DEFINE_CPA_MMG_MEMORY_ALLOCATION_
        M_MrcFreeWithoutSetMode( p_stFLst );
#else
        free( p_stFLst );
#endif
                        
        return(E_uwMrcWarningNone);
}

/*-----------------------------------------------------------------------------
 *  Description : Free memory taken by a BigFile structure
 *-----------------------------------------------------------------------------
 *  Input :     a pointer on a BigFile structure
 *  Output :none
 *-----------------------------------------------------------------------------
 *  Creation date : 05/06/96            Author : V.L.
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
void MRC_fn_vFreeBigFile( MRC_tdstBigFile *p_stBigFile )
{
        short                           wIndex;
        MRC_tdstDirectoryEntry      *p_stDir        = p_stBigFile->pa_stDir;
        MRC_tdstFileEntry                           *p_stFile       = p_stBigFile->pa_stFile;       
        MRC_tdstDataPatch                           *p_stPatch = p_stBigFile->pa_stPatch;

        if (p_stBigFile->ucMode & MRC_C_ucDebugMode)
                fprintf( p_stBigFile->hpDebugBigFile, "Closing bigfile %s\n", p_stBigFile->szName);

        /* free patch table */
        if (p_stBigFile->wNumberOfPatchs)
        {
                for (wIndex = 0; wIndex < p_stBigFile->wNumberOfPatchs; wIndex++, p_stPatch ++)
#ifdef _DEFINE_CPA_MMG_MEMORY_ALLOCATION_                        
                    M_MrcFree(E_ucDynamic, p_stPatch->szName);
#else
                    free(p_stPatch->szName);
#endif
                                                        
                p_stBigFile->wNumberOfPatchs = 0;
#ifdef _DEFINE_CPA_MMG_MEMORY_ALLOCATION_
                M_MrcFree(E_ucDynamic, p_stBigFile->pa_stPatch);
#else
                free(p_stBigFile->pa_stPatch);
#endif
                                        

        }
        p_stBigFile->pa_stPatch = NULL;

        /* free bigfile name & close if open */
#ifdef _DEFINE_CPA_MMG_MEMORY_ALLOCATION_
        M_MrcFree(E_ucDynamic, p_stBigFile->szName);
#else
        free( p_stBigFile->szName);
#endif
                        
        
        if (p_stBigFile->hpBigFile)
                fclose( p_stBigFile->hpBigFile);
        p_stBigFile->hpBigFile = NULL;

        /* free directory table */
        if (p_stBigFile->wNumberOfDirs)
        {
                for (wIndex = 0; wIndex < p_stBigFile->wNumberOfDirs; wIndex ++, p_stDir ++)
#ifdef _DEFINE_CPA_MMG_MEMORY_ALLOCATION_
                    M_MrcFreeWithoutSetMode(p_stDir->szName);
#else
                    free (p_stDir->szName);
#endif                                          
                                                        
                p_stBigFile->wNumberOfDirs = 0;
#ifdef _DEFINE_CPA_MMG_MEMORY_ALLOCATION_
                M_MrcFreeWithoutSetMode(p_stBigFile->pa_stDir);
#else      
                free(p_stBigFile->pa_stDir);
#endif
                                        
        }
        p_stBigFile->pa_stDir = NULL;

        /* free file table */
        if (p_stBigFile->wNumberOfFiles)
        {
                for (wIndex = 0; wIndex < p_stBigFile->wNumberOfFiles; wIndex ++, p_stFile++)
#ifdef _DEFINE_CPA_MMG_MEMORY_ALLOCATION_
                    M_MrcFreeWithoutSetMode(p_stFile->szName);
#else                        
                    free (p_stFile->szName);
#endif                                                  
                                                        
                p_stBigFile->wNumberOfFiles = 0;
#ifdef _DEFINE_CPA_MMG_MEMORY_ALLOCATION_
                M_MrcFreeWithoutSetMode(p_stBigFile->pa_stFile);
#else      
                free (p_stBigFile->pa_stFile);
#endif                                  
                                        
        }
        p_stBigFile->pa_stFile = NULL;
}


/*-----------------------------------------------------------------------------
 *  Description : Initialise the globlal BigFile structure
 *-----------------------------------------------------------------------------
 *  Input :     name of the file to open
 *  Output :none
 *-----------------------------------------------------------------------------
 *  Creation date : 05/06/96            Author : V.L.
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
MRC_tdstBigFile* MRC_fn_p_stOpenBigFile( char *szFileName, unsigned char ucMode )
{
        
            short wIndex;
            MRC_tdstBigFile *p_stBigFile;
#ifdef _DEFINE_CPA_MMG_MEMORY_ALLOCATION_
                M_MrcAlloc(E_ucDynamic, p_stBigFile , MRC_tdstBigFile * , (sizeof(MRC_tdstBigFile)));
#else
                p_stBigFile = (MRC_tdstBigFile *) malloc (sizeof(MRC_tdstBigFile));
#endif

        /* Initialise the BigFile*/
        p_stBigFile->szName = NULL;        /* name of big file */
        p_stBigFile->hpBigFile = NULL;     /* Handler of big file */
        p_stBigFile->pa_stDir = NULL;      /* Directory list */
        p_stBigFile->pa_stFile =NULL;      /* File List */
        p_stBigFile->lVersion = 0;
        p_stBigFile->lFirstData = 0;
        p_stBigFile->wNumberOfDirs = 0;    /* number of dir in dir table */
        p_stBigFile->wNumberOfFiles = 0; /* number of files in file table */
        p_stBigFile->wNumberOfPatchs = 0;
        p_stBigFile->pa_stPatch = 0;

                /* Initialise BigFile mode */
        p_stBigFile->ucMode = ucMode;
// 
        MRC_fn_vOpenBigFileDebugFiles(p_stBigFile,szFileName);
//
        /* Initialize file description table */
        for (wIndex = 0; wIndex < MRC_C_NumberMaxOfFileDescription; wIndex ++)
                p_stBigFile->aFileDescription[ wIndex ].eState = MRC_FS_Close;
        
        /* Initialize File Table by opening bigfile and eventually patches */
        if ( p_stBigFile->ucMode & MRC_C_ucExternalMode )
        {
                p_stBigFile->hpBigFile = NULL;
                return ( NULL );
        }
        else
        {
                if ( p_stBigFile->ucMode & MRC_C_ucDebugMode)
                        fprintf( p_stBigFile->hpDebugBigFile, "Opening bigfile %s\n", szFileName);
                
                /* ajouter lectures des patchs */

                if (MRC_fn_lReadBigFile( p_stBigFile, szFileName, MRC_C_wInternalFile ) == E_uwMrcWarningNone)
                                {
                                        return p_stBigFile;
                                }
                                else
                                {
                                        return NULL;
                                }
                /* changer la table des fichiers pour chaque patchs */
        }
}


/*-----------------------------------------------------------------------------
 *  Description : Close global BigFile structure
 *-----------------------------------------------------------------------------
 *  Input :     none
 *  Output :none
 *-----------------------------------------------------------------------------
 *  Creation date : 05/06/96            Author : V.L.
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
void MRC_fn_vCloseBigFile ( MRC_tdstBigFile *p_stBigFile )
{
        short wIndex;

        /* Close file if some are still opened */
        for (wIndex = 0; wIndex < MRC_C_NumberMaxOfFileDescription; wIndex ++)
                if (p_stBigFile->aFileDescription[ wIndex ].eState != MRC_FS_Close)
                        MRC_fn_vCloseFile( &(p_stBigFile->aFileDescription[ wIndex ]) );
        
        /* Close BigFile */
        if (!(p_stBigFile->ucMode & MRC_C_ucExternalMode))
                MRC_fn_vFreeBigFile( p_stBigFile );
//        
                MRC_fn_vCloseBigFileDebugFiles( p_stBigFile );
//
#ifdef _DEFINE_CPA_MMG_MEMORY_ALLOCATION_
        M_MrcFree(E_ucDynamic, p_stBigFile );
#else                        
        free ( p_stBigFile );
#endif  
}

/*=============================================================================
*
* FUNCTION TO FIND FILE DESCRIPTIF IN BIG FILE
*
=============================================================================*/

/*-----------------------------------------------------------------------------
 *  Description : Function that return Directory description of a subdir of a dir
 *-----------------------------------------------------------------------------
 *  Input :     a pointer on a BigFile and 
 *                      a pointer on the current dir 
 *                      name of the subdir
 *  Output : pointer on the sub dir or NULL
 *-----------------------------------------------------------------------------
 *  Creation date : 05/06/96            Author : V.L.
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
MRC_tdstDirectoryEntry *MRC_fn_p_stFindSubDirectoryInDirectory( MRC_tdstBigFile *p_stBigFile, MRC_tdstDirectoryEntry *p_stCurrentDir, char *szSubDirName)
{
        MRC_tdstDirectoryEntry      *p_stSubDir;
        short                                                           wIndex;
        if (( strcmp(szSubDirName,".") == 0)||( strcmp(szSubDirName,"") == 0))
        {
            return p_stCurrentDir;
        }
        if (p_stCurrentDir->wNumberOfSubDirs == 0)
                return ( (MRC_tdstDirectoryEntry *) NULL); 

        p_stSubDir = &p_stBigFile->pa_stDir[ p_stCurrentDir->wFirstSubDir ];

        for ( wIndex = 0; wIndex < p_stCurrentDir->wNumberOfSubDirs; wIndex ++)
        {
                if ( !_stricmp( szSubDirName, p_stSubDir->szName) )
                        return p_stSubDir;

                p_stSubDir ++;
        }

        return ( (MRC_tdstDirectoryEntry *) NULL);
}

/*-----------------------------------------------------------------------------
 *  Description : Function that return File description of a file in a dir
 *-----------------------------------------------------------------------------
 *  Input :     a pointer on a BigFile and 
 *                      a pointer on the current dir 
 *                      name of the File
 *  Output : pointer on the file if found or NULL
 *-----------------------------------------------------------------------------
 *  Creation date : 06/06/96            Author : V.L.
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
MRC_tdstFileEntry *MRC_fn_p_stFindFileInDirectory( MRC_tdstBigFile *p_stBigFile, MRC_tdstDirectoryEntry *p_stCurrentDir, char *szFileName)
{
        MRC_tdstFileEntry   *p_stFile;
        short                   wIndex;

        if (p_stCurrentDir->wNumberOfFiles == 0)
                return ( (MRC_tdstFileEntry *) NULL); 

        p_stFile = &p_stBigFile->pa_stFile[ p_stCurrentDir->wFirstFile ];

        for ( wIndex = 0; wIndex < p_stCurrentDir->wNumberOfFiles; wIndex ++)
        {
                if ( !_stricmp( szFileName, p_stFile->szName) )
                        return p_stFile;

                p_stFile ++;
        }

        return ( (MRC_tdstFileEntry *) NULL);
}

/*-----------------------------------------------------------------------------
 *  Description : Function that return File entry of a file in a BigFile
 *-----------------------------------------------------------------------------
 *  Input :     a pointer on a BigFile
 *                      name of the File
 *  Output : pointer on the FileEntry if found or NULL
 *-----------------------------------------------------------------------------
 *  Creation date : 06/06/96            Author : V.L.
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
MRC_tdstFileEntry *MRC_fn_p_stFindFileInBigFile( MRC_tdstBigFile *p_stBigFile, char *szFileName)
{
        MRC_tdstDirectoryEntry      *p_stSubDir;
        MRC_tdstFileEntry                           *p_stFile;
        char                                                            *p_cDirPos;
        char                                                            *p_cNextDir;
        char                                                            *p_cFilePos;

        /*
         * Find Begin of FileName
         */
        p_cFilePos = &szFileName[ strlen( szFileName ) - 1 ];

        while ( (p_cFilePos != szFileName) && (*p_cFilePos != '\\') )
                p_cFilePos --;
        
        if ( *p_cFilePos == '\\' )
        {
                *p_cFilePos = 0;
                p_cFilePos ++;
                p_cDirPos = szFileName;
        }
        else
                p_cDirPos = NULL;

        /*
         * Go To GoodDirectory
         */
        p_stSubDir = p_stBigFile->pa_stDir;
        p_cNextDir = p_cDirPos;
        if (p_cDirPos != NULL)
                while ( *p_cDirPos != 0 )
                {
                        /* search begin of next dir */
                        while ( *p_cNextDir && (*p_cNextDir != '\\') )
                                p_cNextDir ++;

                        if ( *p_cNextDir )
                                *p_cNextDir ++ = 0;
                        
                        /* Search sub dir */
                        if ( (p_stSubDir = MRC_fn_p_stFindSubDirectoryInDirectory( p_stBigFile, p_stSubDir, p_cDirPos )) == NULL)
                                return ( (MRC_tdstFileEntry *) NULL);

                        p_cDirPos = p_cNextDir;

                }
        /* search file in its sub directory */
        p_stFile = MRC_fn_p_stFindFileInDirectory (p_stBigFile, p_stSubDir, p_cFilePos);

        return ( p_stFile );
}

/*=============================================================================
*
* Managing Files : opening, closing and miscellaneous functions
*
=============================================================================*/

/*-----------------------------------------------------------------------------
 *  Description : Search a file in EXTERNAL_FILE mode
 *-----------------------------------------------------------------------------
 *  Input :     name of the File
 *  Output : pointer on a stFileDescription structure or NULL if file's not found
 *-----------------------------------------------------------------------------
 *  Creation date : 06/06/96            Author : V.L.
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
MRC_tdstFileEntry *MRC_fn_p_stOpenFileInExternalMode( char *szFileName )
{
        FILE *hpFile;

        if ( (hpFile = fopen( MRC_fn_p_szGetFullFileName(szFileName, MRC_C_ucIsData), "rb" ) ) == NULL )
        {
                M_MrcError( E_uwMrcWarningFileNotFound );
                exit (-1) ;
        }

        strcpy(MRC_g_szExternalFileName, szFileName);
        fseek( hpFile, 0, SEEK_END);

        MRC_g_stExternalFileEntry.szExternFile = MRC_g_szExternalFileName;
        MRC_g_stExternalFileEntry.wPlace = MRC_C_wExternalFile; 
        MRC_g_stExternalFileEntry.lLength = ftell( hpFile );
        MRC_g_stExternalFileEntry.lOffset = 0;

        fclose( hpFile );

        return (&MRC_g_stExternalFileEntry);
}

/*-----------------------------------------------------------------------------
 *  Description : search for the file in the bigfile index and return a pointer
 *                                                              on a MRC_tdstFileDescription
 *-----------------------------------------------------------------------------
 *  Input :     name of the File
 *  Output : pointer on a stFileDescription structure or NULL if file's not found
 *-----------------------------------------------------------------------------
 *  Creation date : 06/06/96            Author : V.L.
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
CPA_EXPORT MRC_tdstFileDescription *MRC_fn_p_stOpenFile( char *szFileName, MRC_tdstBigFile *p_stBigFile )
{
        short                                                           wIndex;
        MRC_tdstFileDescription *p_stFileDesc =   p_stBigFile->aFileDescription;
        MRC_tdstFileEntry                           *p_stFile;
        FILE                                                            *hpFile;
        long                                                            lPos;
        
        if (p_stBigFile->ucMode & MRC_C_ucExternalMode)
        {
#ifdef _DEFINE_CPA_MMG_MEMORY_ALLOCATION_
                M_MrcAlloc(E_ucDynamic, p_stFile , MRC_tdstFileEntry * , (sizeof(MRC_tdstFileEntry)));
#else
                p_stFile = (MRC_tdstFileEntry *) malloc (sizeof(MRC_tdstFileEntry));
#endif
                memcpy(p_stFile, MRC_fn_p_stOpenFileInExternalMode( szFileName ), sizeof(MRC_tdstFileEntry) );
        }
        else
                p_stFile = MRC_fn_p_stFindFileInBigFile( p_stBigFile, szFileName );
                        
        if (p_stFile == NULL)
                return NULL;

        switch ( p_stFile->wPlace )
        {
                case MRC_C_wInexistentFile:
                                hpFile = (FILE *) NULL;
                                break;
                case MRC_C_wInternalFile:
                                hpFile = p_stBigFile->hpBigFile;
                                lPos = p_stBigFile->lFirstData + p_stFile->lOffset;
                                break;
                case MRC_C_wExternalFile:
                                hpFile = fopen( MRC_fn_p_szGetFullFileName(p_stFile->szExternFile, MRC_C_ucIsData), "rb");
                                lPos = 0;
                                break;
                default:
                                if ( 
                                                        ( p_stFile->wPlace >= 0) && 
                                                        ( p_stFile->wPlace < p_stBigFile->wNumberOfPatchs) 
                                         )
                                {
                                hpFile = fopen( MRC_fn_p_szGetFullFileName(p_stBigFile->pa_stPatch[ p_stFile->wPlace ].szName, MRC_C_ucIsPatch), "rb");
                                        lPos = p_stBigFile->pa_stPatch[ p_stFile->wPlace ].lFirstData + p_stFile->lOffset;
                                }

                                else
                                        hpFile = (FILE *) NULL;

        }

        if ( hpFile == (FILE *) NULL )
                return NULL;
        wIndex = 0;
        /* find a free description file in description file table */
        while (                 ( wIndex < MRC_C_NumberMaxOfFileDescription )
                                        &&      ( p_stFileDesc->eState != MRC_FS_Close )
                                )
        {
                wIndex ++;
                p_stFileDesc ++;
        }
        
        if ( wIndex == MRC_C_NumberMaxOfFileDescription )
                return NULL;

        p_stFileDesc->p_stFileEntry             = p_stFile;
        p_stFileDesc->hpFile                    = hpFile;
        p_stFileDesc->eType                     = MRC_FT_Binary;
        p_stFileDesc->eMode                     = MRC_FM_Read;
        p_stFileDesc->eState                    = MRC_FS_Ready;
        p_stFileDesc->lFirst                    = lPos;
        p_stFileDesc->lPosition                 = 0;
        p_stFileDesc->p_stBigFile               = p_stBigFile;
                p_stFileDesc->bEndOfFile                = 0;
        return p_stFileDesc;
}

/*-----------------------------------------------------------------------------
 *  Description : Close a FileDescription
 *-----------------------------------------------------------------------------
 *  Input :     pointer on a file description structure
 *  Output : none
 *-----------------------------------------------------------------------------
 *  Creation date : 06/06/96            Author : V.L.
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
void MRC_fn_vCloseFile( MRC_tdstFileDescription *p_stFile )
{
        if ( p_stFile->eState != MRC_FS_Close )
        {
                /* lecture assynchrone : vérifier quel fichier est pret */

                if ( ( p_stFile->hpFile != NULL ) &&  (p_stFile->hpFile != p_stFile->p_stBigFile->hpBigFile ))
                {
                        fclose( p_stFile->hpFile );
                        p_stFile->hpFile = (FILE *) NULL;
                }

                if (p_stFile->p_stBigFile->ucMode & MRC_C_ucExternalMode)
#ifdef _DEFINE_CPA_MMG_MEMORY_ALLOCATION_
                    M_MrcFree(E_ucDynamic, p_stFile->p_stFileEntry );
#else                        
                    free (p_stFile->p_stFileEntry );
#endif                                                  
                                                        

                p_stFile->eState = MRC_FS_Close;
        }
}

/*-----------------------------------------------------------------------------
 *  Description : Function that return Length of a file
 *-----------------------------------------------------------------------------
 *  Input :     a pointer on a BigFile 
 *                      name of the File
 *  Output : length of a file or 0 if file is not found
 *-----------------------------------------------------------------------------
 *  Creation date : 06/06/96            Author : V.L.
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
long MRC_fn_lFileLength ( MRC_tdstFileDescription *p_stFile )
{
        return ( p_stFile->p_stFileEntry->lLength );
}

/*-----------------------------------------------------------------------------
 *  Description : Change current position on the file
 *-----------------------------------------------------------------------------
 *  Input :     a pointer on a description file
 *                                      origine of change (SO_SET, SO_CURRENT, SO_END )
 *                                      offset of change
 *  Output : length of a file or 0 if file is not found
 *-----------------------------------------------------------------------------
 *  Creation date : 06/06/96            Author : V.L.
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
long MRC_fn_lSeek ( MRC_tdstFileDescription *p_stFile, long lOffset, MRC_tdeSeekOrigin eOrigin)
{
        long lNewPos;
        p_stFile->bEndOfFile = 0;
        switch (eOrigin)
        {
                case MRC_SO_SET :
                                lNewPos = lOffset;
                        break;
                case MRC_SO_CURRENT:
                                lNewPos = p_stFile->lPosition + lOffset;
                        break;
                case MRC_SO_END :
//                                lNewPos = p_stFile->p_stFileEntry->lLength - 1 - lOffset;
//              Modified by Viorel
                              lNewPos = p_stFile->p_stFileEntry->lLength + lOffset;
                        break;
                default:
                                lNewPos = p_stFile->lPosition;
        }
        if (lNewPos < 0)
                {
                        lNewPos = 0;
                                                return -1;
                }
//        if (lNewPos > p_stFile->p_stFileEntry->lLength)
//                {
//                        lNewPos = p_stFile->p_stFileEntry->lLength;
//                                                return -1;
//                }
                p_stFile->lPosition = lNewPos;
//        return (p_stFile->lPosition = lNewPos);
                return 0;
}

/*-----------------------------------------------------------------------------
 *  Description : Function that return the position in a file
 *-----------------------------------------------------------------------------
 *  Input :     a pointer on a BigFile name of the File
 *  Output :    position in the file 
 *-----------------------------------------------------------------------------
 *  Creation date : 08/15/97            Author : Ady
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/

long MRC_fn_lTell ( MRC_tdstFileDescription *p_stFile )
{
        return p_stFile->lPosition ;
}

/*-----------------------------------------------------------------------------
 *  Description : Function that return if 0 if end of file anything else otherwise
 *-----------------------------------------------------------------------------
 *  Input :     a pointer on a BigFile name of the File
 *  Output :    0 if end of file anything else otherwise
 *-----------------------------------------------------------------------------
 *  Creation date : 06/06/96            Author : Ady
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/

int MRC_fn_nEof ( MRC_tdstFileDescription *p_stFile )
{
        return p_stFile->bEndOfFile; 
}

/*=============================================================================
*
* Managing Files : synchronous && asynchronous read
*
=============================================================================*/

/*-----------------------------------------------------------------------------
 *  Description : Read synchronously part of file
 *-----------------------------------------------------------------------------
 *  Input :     a pointer on a FileDescription
 *                                      pointer on an user-supplied character buffer
 *                                      length of bytes to read
 *  Output : number of character really read
 *-----------------------------------------------------------------------------
 *  Creation date : 06/06/96            Author : V.L.
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
long MRC_fn_lSyncReadFile( MRC_tdstFileDescription *p_stFile, char *p_cBuffer, long lSize, long lCount)
{
        FILE    *hpFile;
        long  lPos,lRetv;
//              int flag;
                
                if (p_stFile == NULL || p_stFile->eState == MRC_FS_Close)
                return 0;
//              flag = 0;
        if ( p_stFile->p_stFileEntry->lLength < p_stFile->lPosition + lSize*lCount)
                {
//                              flag = 1;
                //lCount = (p_stFile->p_stFileEntry->lLength - p_stFile->lPosition) / lSize;
                lCount = lSize?((p_stFile->p_stFileEntry->lLength - p_stFile->lPosition) / lSize):0;
                                p_stFile->bEndOfFile = 1;
                }
        hpFile = p_stFile->hpFile;
        lPos   = p_stFile->lFirst + p_stFile->lPosition;

        if (hpFile == (FILE *) NULL)
                lSize = 0;
        else
        {
                fseek( hpFile, lPos, SEEK_SET );
                lRetv = fread( p_cBuffer, lSize, lCount ,hpFile);
//                if (flag) 
//                              {
                                        p_stFile->lPosition += (lSize*lCount);
//                                      p_stFile->bEndOfFile = 1;
//                              }
//                              else
//                              {
//                                      p_stFile->lPosition = p_stFile->p_stFileEntry->lLength;
//                              }
                if (hpFile != p_stFile->p_stBigFile->hpBigFile)
                        fclose( hpFile );
        }
        return lRetv;
}

/*-----------------------------------------------------------------------------
 *  Description : Thread for asynchronous read
 *-----------------------------------------------------------------------------
 *  Input :     a pointer on a MRC_tdstFileDescription
 *  Output : 0
 *-----------------------------------------------------------------------------
 *  Creation date : 06/06/96            Author : V.L.
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
long WINAPI MRC_fn_lAsyncThread( MRC_tdstFileDescription *p_stFile )
{
        p_stFile->lAsyncSize = MRC_fn_lSyncReadFile( p_stFile, p_stFile->p_cAsyncBuffer, 1 , p_stFile->lAsyncSize);
        p_stFile->eState     = MRC_FS_Ready;
        return (0);
}

/*-----------------------------------------------------------------------------
*  Description : Asynchronous read : launch a thread that read synchrnously
 *-----------------------------------------------------------------------------
 *  Input :     a pointer on a MRC_tdstFileDescription,
 *                                      a pointer on an user-supplied buffer,
 *                                      number of bytes to read
 *  Output : an error value C_ErrNone, C_ErrAsyncLaunch ou C_ErrFileNotReady
 *-----------------------------------------------------------------------------
 *  Creation date : 06/06/96            Author : V.L.
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
long MRC_fn_lAsyncReadFile(MRC_tdstFileDescription *p_stFile, char *p_cBuffer, long lSize )
{
        long lThreadId;

        if (p_stFile->eState != MRC_FS_Ready )
        {
                p_stFile->lAsyncSize = 0; 
                M_MrcError( E_uwMrcWarningFileNotReady );
                return (E_uwMrcWarningFileNotReady );  
        }

        p_stFile->p_cAsyncBuffer        = p_cBuffer;
        p_stFile->lAsyncSize                    = lSize;
        
        if (CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) MRC_fn_lAsyncThread, p_stFile, 0,(unsigned long *) &lThreadId))
        {
                p_stFile->eState = MRC_FS_NotReady;
                return (E_uwMrcWarningNone);
        }
        M_MrcError( E_uwMrcWarningAsyncLaunch );
        return (E_uwMrcWarningAsyncLaunch );
}

/*-----------------------------------------------------------------------------
 *  Description : return number of bytes read by the last asynchronous read
 *-----------------------------------------------------------------------------
 *  Input :     a pointer on a MRC_tdstFileDescription
 *  Output : number of bytes last asynchronous read really read
 *-----------------------------------------------------------------------------
 *  Creation date : 06/06/96            Author : V.L.
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
long MRC_fn_lAsyncNumberOfBytesRead( MRC_tdstFileDescription *p_stFile )
{
        if (p_stFile->eState == MRC_FS_Ready)
                return (p_stFile->lAsyncSize);
        else
                return (0);
}

/*-----------------------------------------------------------------------------
 *  Description : wait for the end of an asynchronous read 
 *-----------------------------------------------------------------------------
 *  Input :     a pointer on a MRC_tdstFileDescription
 *  Output : none
 *-----------------------------------------------------------------------------
 *  Creation date : 06/06/96            Author : V.L.
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
void MRC_fn_vWaitEndOfAsyncRead( MRC_tdstFileDescription *p_stFile )
{
        while (p_stFile->eState != MRC_FS_Ready);
}

/*-----------------------------------------------------------------------------
 *  Description : Opens a list of big files
 *-----------------------------------------------------------------------------
 *  Input :  a NULL terminated array of the BigFile Names
             & mode 
 *  Output : a NULL terminated array of BigFiles 
 *-----------------------------------------------------------------------------
 *  Creation date : 08/04/97            Author : Ady & Prince
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/

MRC_tdstBigFileList *MRC_fn_p_stOpenBigFileList( char **szFileNames, unsigned char ucMode )
{
        MRC_tdstBigFileList* p_stBigFileList;
        int i,j;
        char *szFileName;
        i = 0;
        szFileName = szFileNames[i];
        while ( szFileName != NULL )
        {
                i++;
                szFileName = szFileNames[i];
        }
        i++;
#ifdef _DEFINE_CPA_MMG_MEMORY_ALLOCATION_
    M_MrcAlloc(E_ucDynamic, p_stBigFileList , MRC_tdstBigFileList* ,  (i*sizeof(MRC_tdstBigFileList)) );
#else
    p_stBigFileList = ( MRC_tdstBigFileList* ) malloc( i*sizeof( MRC_tdstBigFileList ) );
#endif 
        i--;
        p_stBigFileList[i] = NULL;
        for ( j = 0; j < i ; j++ )
        {
                p_stBigFileList[j] = MRC_fn_p_stOpenBigFile( szFileNames[j] , ucMode);
        }
        return p_stBigFileList;
}

/*-----------------------------------------------------------------------------
 *  Description : Close a list of big files
 *-----------------------------------------------------------------------------
 *  Input :   a NULL terminated array of BigFiles 
 *  Output :  none
 *-----------------------------------------------------------------------------
 *  Creation date : 08/04/97            Author : Ady & Prince
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/

void MRC_fn_vCloseBigFileList ( MRC_tdstBigFileList *p_stBigFileList )
{
        int i,j;
        i = 0;
        while ( p_stBigFileList[i] != NULL )
        {
                i++;
        }
        for ( j = 0; j < i ; j++ )
        {
                MRC_fn_vCloseBigFile( p_stBigFileList[j] );
        }
#ifdef _DEFINE_CPA_MMG_MEMORY_ALLOCATION_
    M_MrcFree( E_ucDynamic, p_stBigFileList );
#else
    free( p_stBigFileList );
#endif
        
}

/*-----------------------------------------------------------------------------
 *  Description : Opens a file from a list of big files
 *-----------------------------------------------------------------------------
 *  Input :  
             a NULL terminated array of BigFiles
 *  Output : a NULL terminated array of BigFiles 
 *-----------------------------------------------------------------------------
 *  Creation date : 08/04/97            Author : Ady & Prince
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/

MRC_tdstFileDescription *MRC_fn_p_stOpenFileInList( char *szFileName, MRC_tdstBigFileList *p_stBigFileList )
{
        int i;
        char tempName[256];
                i = 0;
                while ( p_stBigFileList[i] != NULL )
        {
                                strcpy( tempName , szFileName );
                if ( MRC_fn_p_stFindFileInBigFile( p_stBigFileList[i] , tempName ) != NULL )
                {
                                                strcpy( tempName , szFileName );
                        return MRC_fn_p_stOpenFile( tempName , p_stBigFileList[i] ) ;
                }
                i++;
        }
        return NULL;
}

/*-----------------------------------------------------------------------------
 *  Description : Function that returns 1 if the file exists 0 otherwise
 *-----------------------------------------------------------------------------
 *  Input :     a pointer on a BigFile , name of the File
 *  Output :    1 if file exists anything else otherwise
 *-----------------------------------------------------------------------------
 *  Creation date : 08/15/97            Author : Ady
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/

int MRC_fn_nFileExists ( MRC_tdstBigFileListEx *p_stBigFileListEx , char* szFileName )
{
        int flag;
        MRC_tdstFileDescription *p_stFile;
        flag = 0;
        p_stFile = MRC_fn_p_stOpenFileInList( szFileName , p_stBigFileListEx->p_BigFileList );
        if ( p_stFile != NULL )
        {
            flag = 1;
            MRC_fn_vCloseFile( p_stFile );
        }
        return flag;
}


//////////////////////////////////////////////////////////////////////////////////
//                                                                                                                                                              //
//                                              Extended functions for the bigfiles                                             //      
//                                                                                                                                                              //
//////////////////////////////////////////////////////////////////////////////////
//
//
//        Extended means that if a file is not found in a bigfile
//        the extended functions try to open it as an external file
//
//
////////////////////////////////////////////////////////////////////////////////

/*-----------------------------------------------------------------------------
 *  Description : Opens an extended list of  big files
 *-----------------------------------------------------------------------------
 *  Input :  a NULL terminated array of the BigFile Names
             & mode 
 *  Output : a NULL terminated array of BigFiles 
 *-----------------------------------------------------------------------------
 *  Creation date : 08/04/97            Author : Ady 
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/

MRC_tdstBigFileListEx *MRC_fn_p_stOpenBigFileListEx( char **szFileNames, unsigned char ucMode )
{
    MRC_tdstBigFileListEx* p_stBigFileListEx;
#ifdef _DEFINE_CPA_MMG_MEMORY_ALLOCATION_
    M_MrcAlloc(E_ucDynamic, p_stBigFileListEx , MRC_tdstBigFileListEx* ,  sizeof(MRC_tdstBigFileListEx) );
#else
    p_stBigFileListEx = ( MRC_tdstBigFileListEx* ) malloc( sizeof( MRC_tdstBigFileListEx ) );
#endif 
    p_stBigFileListEx->p_BigFileList = MRC_fn_p_stOpenBigFileList( szFileNames, ucMode );
    p_stBigFileListEx->p_stFileDesc = NULL;
    return p_stBigFileListEx;
}

/*-----------------------------------------------------------------------------
 *  Description : Close an extended list of big files
 *-----------------------------------------------------------------------------
 *  Input :   a NULL terminated array of BigFiles 
 *  Output :  none
 *-----------------------------------------------------------------------------
 *  Creation date : 08/04/97            Author : Ady 
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/

void MRC_fn_vCloseBigFileListEx  ( MRC_tdstBigFileListEx *p_stBigFileListEx )
{
    MRC_tdstFileDescription *p_stPrev;
        while ( p_stBigFileListEx->p_stFileDesc != NULL )
        {
                p_stPrev = p_stBigFileListEx->p_stFileDesc;
                p_stBigFileListEx->p_stFileDesc = p_stBigFileListEx->p_stFileDesc->p_stNext;
                MRC_fn_vCloseFileEx( p_stPrev );
#ifdef _DEFINE_CPA_MMG_MEMORY_ALLOCATION_
                M_MrcFree( E_ucDynamic, p_stPrev );
#else
                free( p_stPrev );
#endif
        }
        MRC_fn_vCloseBigFileList(p_stBigFileListEx->p_BigFileList);
#ifdef _DEFINE_CPA_MMG_MEMORY_ALLOCATION_
    M_MrcFree( E_ucDynamic, p_stBigFileListEx );
#else
    free( p_stBigFileListEx );
#endif
        
}

/*-----------------------------------------------------------------------------
 *  Description : Opens a file from an extended list of big files
 *-----------------------------------------------------------------------------
 *  Input :  
             a NULL terminated array of BigFiles
 *  Output : a NULL terminated array of BigFiles 
 *-----------------------------------------------------------------------------
 *  Creation date : 08/04/97            Author : Ady 
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/

MRC_tdstFileDescription *MRC_fn_p_stOpenFileInListEx( MRC_tdstBigFileListEx *p_stBigFileListEx , char *szFileName ,char* fmt )
{
        MRC_tdstFileDescription *p_stFileDes;
//if (!(stricmp(szFileName,".\\DATA\\p01.MBM")))
//{

    //Adys
//    p_stFileDes = NULL;
//}
        p_stFileDes = MRC_fn_p_stOpenFileInList( szFileName, p_stBigFileListEx->p_BigFileList );
        if ( p_stFileDes != NULL )
        {
                return p_stFileDes;
        }
        else
        {
#ifdef _DEFINE_CPA_MMG_MEMORY_ALLOCATION_
                M_MrcAlloc(E_ucDynamic, p_stFileDes , MRC_tdstFileDescription* ,  sizeof(MRC_tdstFileDescription) );
#else
                p_stFileDes = ( MRC_tdstFileDescription* ) malloc( sizeof( MRC_tdstFileDescription ) );
#endif
                if ( fmt == NULL)
                                {
                                        p_stFileDes->hpFile = fopen( szFileName, "rb" ); 
                                }
                                else
                                {
                                        p_stFileDes->hpFile = fopen( szFileName, fmt ); 
                                }
                if ( p_stFileDes->hpFile == NULL )
                {
                        return NULL;
                }
                                p_stFileDes->p_stBFLEx = p_stBigFileListEx;
                                p_stFileDes->p_stBigFile = NULL;
                p_stFileDes->p_stPrev = NULL;
                p_stFileDes->p_stNext = p_stFileDes->p_stBFLEx->p_stFileDesc;
                                if (p_stFileDes->p_stBFLEx->p_stFileDesc != NULL)
                                {
                                        p_stFileDes->p_stBFLEx->p_stFileDesc->p_stPrev = p_stFileDes;
                                }
                p_stFileDes->p_stBFLEx->p_stFileDesc = p_stFileDes;
                                
                return p_stFileDes;
        }
}

//////////////////////////////////////////////////////////////////////////////
/*
 *                  Extended functions for file services
 */
//////////////////////////////////////////////////////////////////////////////


/*-----------------------------------------------------------------------------
 *  Description : Close a FileDescription
 *-----------------------------------------------------------------------------
 *  Input :     pointer on a file description structure
 *  Output : none
 *-----------------------------------------------------------------------------
 *  Creation date : 06/06/96            Author : Ady.
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/

void MRC_fn_vCloseFileEx( MRC_tdstFileDescription *p_stFile )
{
        if ( p_stFile->p_stBigFile != NULL)
        {
                MRC_fn_vCloseFile( p_stFile );
        }
        else
        {
                fclose(p_stFile->hpFile);
                if (p_stFile->p_stPrev == NULL)
                {
                        p_stFile->p_stBFLEx->p_stFileDesc = p_stFile->p_stNext;
                }
                else
                {
                                                p_stFile->p_stPrev->p_stNext = p_stFile->p_stNext;
                }
                if (p_stFile->p_stNext == NULL)
                {
                }
                else
                {
                        p_stFile->p_stNext->p_stPrev = p_stFile->p_stPrev;
                }
#ifdef _DEFINE_CPA_MMG_MEMORY_ALLOCATION_
                M_MrcFree( E_ucDynamic, p_stFile );
#else
                free( p_stFile );
#endif
        }
}

/*-----------------------------------------------------------------------------
 *  Description : Read synchronously part of file (Extended)
 *-----------------------------------------------------------------------------
 *  Input :     a pointer on a FileDescription
 *                                      pointer on an user-supplied character buffer
 *                                      length of bytes to read
 *  Output : number of character really read
 *-----------------------------------------------------------------------------
 *  Creation date : 06/06/96            Author : Ady & Prince
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/

long MRC_fn_lSyncReadFileEx( char *p_cBuffer, long lSize , long lCount , MRC_tdstFileDescription *p_stFile )
{
        if ( p_stFile->p_stBigFile != NULL)
        {
                return MRC_fn_lSyncReadFile( p_stFile, p_cBuffer, lSize , lCount );
        }
        else
        {
                return fread( p_cBuffer, lSize , lCount ,p_stFile->hpFile );
        }
}

/*-----------------------------------------------------------------------------
 *  Description : Function that return Length of a file ( Extended )
 *-----------------------------------------------------------------------------
 *  Input :     a pointer on a BigFile 
 *                      name of the File
 *  Output : length of a file or 0 if file is not found
 *-----------------------------------------------------------------------------
 *  Creation date : 06/06/96            Author : Ady & Prince.
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/


long MRC_fn_lFileLengthEx( MRC_tdstFileDescription *p_stFile )
{
        if ( p_stFile->p_stBigFile != NULL)
        {
                return MRC_fn_lFileLength( p_stFile );
        }
        else
        {
                return filelength(fileno(p_stFile->hpFile));
        }
}

/*-----------------------------------------------------------------------------
 *  Description : Change current position on the file (Extended)
 *-----------------------------------------------------------------------------
 *  Input :     a pointer on a description file
 *                                      origine of change (SO_SET, SO_CURRENT, SO_END )
 *                                      offset of change
 *  Output : length of a file or 0 if file is not found
 *-----------------------------------------------------------------------------
 *  Creation date : 06/06/96            Author : Ady & Prince
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/


long MRC_fn_lSeekEx( MRC_tdstFileDescription *p_stFile, long lOffset, MRC_tdeSeekOrigin eOrigin)
{
        if ( p_stFile->p_stBigFile != NULL)
        {
                return MRC_fn_lSeek( p_stFile, lOffset, eOrigin);
        }
        else
        {
                return fseek( p_stFile->hpFile, lOffset, eOrigin);
        }
}

/*-----------------------------------------------------------------------------
 *  Description : Function that return the position in a file
 *-----------------------------------------------------------------------------
 *  Input :     a pointer on a BigFile name of the File
 *  Output :    position in the file 
 *-----------------------------------------------------------------------------
 *  Creation date : 08/15/97            Author : Ady
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/

long MRC_fn_lTellEx ( MRC_tdstFileDescription *p_stFile )
{
        if ( p_stFile->p_stBigFile != NULL)
        {
                return MRC_fn_lTell( p_stFile );
        }
        else
        {
                return ftell( p_stFile->hpFile );
        }

}

/*-----------------------------------------------------------------------------
 *  Description : Function that return if 0 if end of file anything else otherwise (Extended)
 *-----------------------------------------------------------------------------
 *  Input :     a pointer on a BigFile name of the File
 *  Output :    0 if end of file anything else otherwise
 *-----------------------------------------------------------------------------
 *  Creation date : 08/15/97            Author : Ady
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/

int MRC_fn_nEofEx ( MRC_tdstFileDescription *p_stFile )
{
        if ( p_stFile->p_stBigFile != NULL)
        {
                return MRC_fn_nEof( p_stFile );
        }
        else
        {
                return feof( p_stFile->hpFile );
        }

}

/*-----------------------------------------------------------------------------
 *  Description : Function that returns 1 if the file exists 0 otherwise
 *-----------------------------------------------------------------------------
 *  Input :     a pointer on a BigFile , name of the File
 *  Output :    1 if file exists anything else otherwise
 *-----------------------------------------------------------------------------
 *  Creation date : 08/15/97            Author : Ady
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/

int MRC_fn_nFileExistsEx ( MRC_tdstBigFileListEx *p_stBigFileListEx , char* szFileName )
{
        int flag;
        MRC_tdstFileDescription *p_stFile;
        flag = 0;
        p_stFile = MRC_fn_p_stOpenFileInListEx( p_stBigFileListEx, szFileName , "rb");
        if ( p_stFile != NULL )
        {
            flag = 1;
            MRC_fn_vCloseFileEx( p_stFile );
        }
        return flag;
}



/*-----------------------------------------------------------------------------
 *  Description : Extended fscanf (limited implementation right now )
 *                                ( allows reading only one string)
 *-----------------------------------------------------------------------------
 *  Input :     the same as fscanf 
 *  Output :    the same as fscanf    
 *-----------------------------------------------------------------------------
 *  Creation date : 08/15/97            Author : Ady
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
/*
int MRC_fn_nFileScanfEx ( MRC_tdstFileDescription* p_stFile , char* fmt , char* buffer)
{
    char buf[MAX_BUFF];
    long d,i,n;
    if ( p_stFile->p_stBigFile != NULL)
    {
        n = MAX_BUFF;
        d = MRC_fn_lSyncReadFile( p_stFile, buf, sizeof ( char ), n);
        i = 0;
        while ( ( i < d ) && ( buf[i] != '\n') )
        {
            buffer[i] = buf[i];
            i++;
        }
//        if ( i==d )
//        {
            buffer[i] = '\0';
//        }
//        else
//        {
//            buffer[i] = '\n';
//            buffer[i+1] = '\0';
//        }
        if (MRC_fn_nEofEx(p_stFile))
        {
            return EOF;
        }
        else
        {
            if ( i==d )
            {
                return 0;
            }
            else
            {
                return 1;
            }
        }
    }
    else
    {
        return fscanf( p_stFile->hpFile, fmt , buffer );
    }
}*/

/*-----------------------------------------------------------------------------
 *  Description : The extended version of fgets
 *-----------------------------------------------------------------------------
 *  Input :     the same as fgets 
 *  Output :    the same as fgets    
 *-----------------------------------------------------------------------------
 *  Creation date : 08/15/97            Author : Ady
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
/*
char* MRC_fn_szFileGetsEx ( char* buffer ,int n , MRC_tdstFileDescription* p_stFile )
{
    char buf[MAX_BUFF];
    long d,i;
    if ( p_stFile->p_stBigFile != NULL)
    {
        d = MRC_fn_lSyncReadFile( p_stFile, buf, sizeof ( char ), n);
        i = 0;
        while ( ( i < d ) && ( buf[i] != '\n') )
        {
            buffer[i] = buf[i];
            i++;
        }
        if ( (i==d) || MRC_fn_nEofEx(p_stFile) )
        {
            buffer[i] = '\0';
        }
        else
        {
            buffer[i] = '\n';
            buffer[i+1] = '\0';
        }
        if (MRC_fn_nEofEx(p_stFile))
        {
            return NULL;
        }
        else
        {
            return buffer;
        }
    }
    else
    {
        return fgets( buffer , n , p_stFile->hpFile );
    }
}*/

