// The following ifdef block is the standard way of creating macros which make exporting 
// from a DLL simpler. All files within this DLL are compiled with the CONVERTER_EXPORTS
// symbol defined on the command line. this symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see 
// CONVERTER_API functions as being imported from a DLL, whereas this DLL sees symbols
// defined with this macro as being exported.
#ifdef CONVERTER_EXPORTS
#define CONVERTER_API extern "C" __declspec(dllexport)
#else
#define CONVERTER_API extern "C" __declspec(dllimport)
#endif

#include <windows.h>

#define CIPHERLAB_ERROR_SUCCESS                        0
#define CIPHERLAB_ERROR_INVALID_SOURCE_FILE            1
#define CIPHERLAB_ERROR_INVALID_TARGET_FILE            2
#define CIPHERLAB_ERROR_INVALID_TARGET_DIRECTORY       3
#define CIPHERLAB_ERROR_CANNOT_OPEN_SOURCE_FILE        4
#define CIPHERLAB_ERROR_CANNOT_OPEN_TARGET_FILE        5
#define CIPHERLAB_ERROR_CANNOT_CREATE_TEMP_FILE        6
#define CIPHERLAB_ERROR_CANNOT_OPEN_TEMP_FILE          7
#define CIPHERLAB_ERROR_INVALID_FILE_FORMAT            8
#define CIPHERLAB_ERROR_TOOLTYPE_NOT_SUPPORTED         9
#define CIPHERLAB_ERROR_FILETYPE_NOT_SUPPORTED        10
#define CIPHERLAB_ERROR_INVALID_NUMBER_RECORD_FIELDS  11
#define CIPHERLAB_ERROR_INVALID_DELIMITER             12
#define CIPHERLAB_ERROR_INVALID_RECORD_LENGTH         13
#define CIPHERLAB_ERROR_CONVERSION_STOPPED            14
#define CIPHERLAB_ERROR_CANNOT_OPEN_DBF_FILE          15
#define CIPHERLAB_ERROR_CANNOT_CREATE_DBF_INDEX       16
#define CIPHERLAB_ERROR_CANNOT_CLOSE_DBF_FILE         17
#define CIPHERLAB_ERROR_INVALID_DBF_FILENAME          18
#define CIPHERLAB_ERROR_CANNOT_ADD_DBF_MEMBER         19
#define CIPHERLAB_ERROR_CANNOT_ADD_DBF_DATA           20
#define CIPHERLAB_ERROR_INVALID_LOOKUP_FILE_TYPE      21
#define CIPHERLAB_ERROR_INVALID_KEY_INDEX             22
#define CIPHERLAB_ERROR_INVALID_SRCSTRUCT             23
#define CIPHERLAB_ERROR_INVALID_INPUT_SIZE            24
#define CIPHERLAB_ERROR_INVALID_WRONG_FORMAT_ACTION   25
#define CIPHERLAB_ERROR_CONVERSION_FAILED             26
#define CIPHERLAB_ERROR_OUT_OF_MEMORY                 27
#define CIPHERLAB_ERROR_CANNOT_OPEN_AGX_FILE          28
#define CIPHERLAB_ERROR_INVALID_AGX_FORMAT            29
#define CIPHERLAB_ERROR_INVALID_RECORD_OFFSET         30




typedef enum
{
	C_PROG_TYPE = 0,
	BASIC_PROG_TYPE,
	FORGE_AG_TYPE,
} TOOLTYPE;

typedef enum
{
	FIRST_LOOKUP_FILE = 1,
	SECOND_LOOKUP_FILE,
	THIRD_LOOKUP_FILE,
} FILETYPE_LOOKUP;

typedef enum
{
	STOP_CONVERSION = 0,
	REFORMAT_RECORD,
	SKIP_RECORD,
} ACTION_WRONGFMT;

typedef enum
{
	F1 = 1,
	F2,
	F3,
	F4,
	F5,
} FILENAME_DBF_BASIC;

typedef struct
{
	int offset;
	int length;
	BOOL key;
}
RECORDFLD, *PRECORDFLD;

typedef struct
{
	TCHAR *pSourceFile;
	TCHAR *pCProgDbfFilename;
	int numRecordFields;  // max 8 fields
	char *delim;
	RECORDFLD *pRecordField;
	ACTION_WRONGFMT action;
} SRCSTRUCT_PC2RAM_CPROG, *PSRCSTRUCT_PC2RAM_CPROG;

typedef struct
{
	TCHAR *pSourceFile;
	FILENAME_DBF_BASIC basicDbfFilename;
	int numRecordFields;  // max 8 fields
	char *delim;
	RECORDFLD *pRecordField;
	ACTION_WRONGFMT action;
} SRCSTRUCT_PC2RAM_BASIC, *PSRCSTRUCT_PC2RAM_BASIC;

typedef struct
{
	TCHAR *pSourceFile;
	int numRecordFields;  // max 8 fields
	char *delim;
	RECORDFLD *pRecordField;
	ACTION_WRONGFMT action;
} SRCSTRUCT_PC2SD_CPROG, *PSRCSTRUCT_PC2SD_CPROG, SRCSTRUCT_PC2RAM2_CPROG, *PSRCSTRUCT_PC2RAM2_CPROG;



typedef struct
{
	TCHAR *pSourceFile;
	FILENAME_DBF_BASIC dbfFilename;
	int numRecordFields;  // max 8 fields
	char *delim;  // set to NULL if record length is fixed
	RECORDFLD *pRecordField;
	ACTION_WRONGFMT action;	
} SRCSTRUCT_PC2SD_BASIC, *PSRCSTRUCT_PC2SD_BASIC, SRCSTRUCT_PC2RAM2_BASIC, *PSRCSTRUCT_PC2RAM2_BASIC;

typedef struct
{
	FILETYPE_LOOKUP lookup;
	int numRecordFields;  // max 8 record fields
	char *delim;  // set to NULL if record length is fixed
	RECORDFLD *pRecordField;
	ACTION_WRONGFMT action;
} AG_RECORD_FORMAT, *PAG_RECORD_FORMAT;

typedef struct
{
	TCHAR *pSourceFile;
	AG_RECORD_FORMAT format;
} SRCSTRUCT_PC2SD_FORGEAG, *PSRCSTRUCT_PC2SD_FORGEAG, SRCSTRUCT_PC2RAM_FORGEAG, *PSRCSTRUCT_PC2RAM_FORGEAG, SRCSTRUCT_PC2RAM2_FORGEAG, *PSRCSTRUCT_PC2RAM2_FORGEAG;

typedef struct
{
	int majorVersion;
	int minorVersion;
	int revisionNumber;
	TCHAR version[16]; 
} API_VERSION;

typedef void (CALLBACK *PROGRESS_FUNC) (float percent, int recordCount, LPCTSTR status);

// Function prototype
CONVERTER_API int Sd2PcCProg(LPTSTR lpSource, LPTSTR lpTarget, LPDWORD lpNumberOfRecordsConverted, PROGRESS_FUNC callback);
CONVERTER_API int Sd2PcBasicProg(LPTSTR lpSource, LPTSTR lpTarget, LPDWORD lpNumberOfRecordsConverted, PROGRESS_FUNC callback);

CONVERTER_API int Pc2SdCProg(SRCSTRUCT_PC2SD_CPROG source, LPTSTR lpTarget, LPDWORD lpNumberOfRecordsConverted, LPTSTR *pOutputFileName, PROGRESS_FUNC callback);
CONVERTER_API int Pc2SdBasicProg(SRCSTRUCT_PC2SD_BASIC source, LPTSTR pTargetDir, LPDWORD lpNumberOfRecordsConverted, LPTSTR *pOutputFileName, PROGRESS_FUNC callback);
CONVERTER_API int Pc2SdForgeAg(SRCSTRUCT_PC2SD_FORGEAG source, LPTSTR pTargetDir, LPDWORD lpNumberOfRecordsConverted, LPTSTR *pOutputFileName, PROGRESS_FUNC callback);

CONVERTER_API int Pc2RamCProg(PSRCSTRUCT_PC2RAM_CPROG pSource, int count, LPTSTR pTarget, LPDWORD lpNumberOfFilesConverted, LPDWORD lpNumberOfRecordsConverted, PROGRESS_FUNC callback);
CONVERTER_API int Pc2RamBasicProg(PSRCSTRUCT_PC2RAM_BASIC pSource, int count, LPTSTR pTarget, LPDWORD lpNumberOfFilesConverted, LPDWORD lpNumberOfRecordsConverted, PROGRESS_FUNC callback);
CONVERTER_API int Pc2RamForgeAg(PSRCSTRUCT_PC2RAM_FORGEAG pSource, int count, LPTSTR pTargetDir, LPDWORD lpNumberOfFilesConverted, LPDWORD lpNumberOfRecordsConverted, LPTSTR pOutputFileName, PROGRESS_FUNC callback);

CONVERTER_API int Pc2RamCProg2(SRCSTRUCT_PC2RAM2_CPROG source, LPTSTR lpTarget, LPDWORD lpNumberOfRecordsConverted, LPTSTR *pOutputFileName, PROGRESS_FUNC callback);
CONVERTER_API int Pc2RamBasicProg2(SRCSTRUCT_PC2RAM2_BASIC source, LPTSTR lpTarget, LPDWORD lpNumberOfRecordsConverted, LPTSTR *pOutputFileName, PROGRESS_FUNC callback);
CONVERTER_API int Pc2RamForgeAg2(SRCSTRUCT_PC2RAM2_FORGEAG source, LPTSTR lpTarget, LPDWORD lpNumberOfRecordsConverted, LPTSTR *pOutputFileName, PROGRESS_FUNC callback);

CONVERTER_API int AgxGetFormatInfo(LPTSTR pAgxPath, PAG_RECORD_FORMAT *pFormat, int *pCount);
CONVERTER_API void AgxReleaseFormatInfo(PAG_RECORD_FORMAT pFormat);

CONVERTER_API API_VERSION GetApiVersion();
CONVERTER_API LPTSTR GetErrorMessage(int errorCode);