//  ME5.H

#define false 0
#define true  1

#define BACKSPACE   (8)
#define TAB         (9)
#define LINEFEED   (10)
#define ENTER      (13)
#define RETURN     (13)
#define ESCAPE     (27)
#define SPACE      (32)

#define COMPRESS true
#define INNER_DEBUG false
#define MAX_NUM_SEGMENTS 200

#define BUFFSIZE       ((unsigned int)20480)     //   20K
//  A 10K buffer results in a memory problem with compression.

#define MIN_KEY_LENGTH  16      
#define MAX_KEY_LENGTH  64      

#define MIN_KEYTEXT_SEGMENT_LENGTH 200
#define MAX_KEYTEXT_SEGMENT_LENGTH 400

#define _MAX_PATH_     256

#include "md52.h"

struct MD5Context mh_mdContext;

int buffers_are_allocated;
int encrypt;                    //  true when encrypting 
int ifh;                        //  input file handle
int ofh;                        //  output file handle
int me5_expand_block;           //  true if block must be expanded 
int demo;                       //  true if and only if demo mode

unsigned int block_size;        //  size of block to be read
unsigned int block;             //  block number
unsigned int segment;           //  segment number    
unsigned int comp_fact;         //  compression factor
unsigned int keylength;         //  size of keytext segment 
unsigned int first_half_size;   //  size of first half of block for Russian copulation

unsigned int rnd_int_buff[MAX_KEYTEXT_SEGMENT_LENGTH];  //  Used in FOPS3.C and SHUFFLE.C.

//  unsigned long num_rnd;              //  total numbers of random numbers generated
//  unsigned long num_pm;               //  in each file encryption or decryption.

unsigned char key[MAX_KEY_LENGTH];  //  encryption key
unsigned char block_header[2]; 
unsigned char kt[MAX_KEYTEXT_SEGMENT_LENGTH];              //  keytext segment
unsigned char pt[MAX_KEYTEXT_SEGMENT_LENGTH];              //  plaintext segment

unsigned char input_file_path[_MAX_PATH_];
unsigned char output_file_path[_MAX_PATH_];
unsigned char v[80];                                        //  Used in KEY.C
unsigned char mh_scratch[MAX_KEYTEXT_SEGMENT_LENGTH*2];

unsigned char *buffer;                //  pointer to primary buffer  
unsigned char *buffer1;               //  pointer to secondary buffer 
unsigned char *pm_buff;               //  pointer to buffer for pm random numbers

#if INNER_DEBUG
unsigned char debug_buff[5][MAX_NUM_SEGMENTS][MAX_KEYTEXT_SEGMENT_LENGTH*2];
unsigned int ks[MAX_NUM_SEGMENTS][6];
#endif

//  Public functions:
//  -----------------

//  KEY.C

__declspec(dllexport) int _stdcall key_is_text(unsigned char *bytes, int n);


//  FOPS2.C

__declspec(dllexport) void _stdcall operation_initialization(unsigned char *vb_key, 
    int vb_encrypt, unsigned int filesize, int vb_demo);

__declspec(dllexport) int _stdcall encrypt_file(char *vb_input_filepath, char *vb_output_filepath);

__declspec(dllexport) int _stdcall decrypt_file(char *vb_input_filepath, char *vb_output_filepath);

//  ME5.C

//  __declspec(dllexport) void _stdcall me6_initialization(void);

__declspec(dllexport) int _stdcall allocate_buffers(void);

__declspec(dllexport) void _stdcall deallocate_buffers(void);


//  Private functions called by other modules:
//  ------------------------------------------

//  COMPR.C

int allocate_compression_space(void);
void free_compression_space(void);
unsigned int me5_compress_block(unsigned int n, unsigned int bits_value);
unsigned int me5_decompress_block(unsigned int n, unsigned int bits_value, int *err_flag);

//  FOPS3.C

void encrypt_block(void);
int decrypt_block(void);

//  KEY.C

void define_priming_key(void);
void define_next_keytext_segment(void);

//  RAND.C
void seed_rngs(void);
unsigned char rnd(void);
unsigned char pm(void);

//  SHUFFLE.C

void shuffle(unsigned char *buffer, unsigned int num_bytes);
void unshuffle(unsigned char *buffer, unsigned int *m_a, unsigned int num_bytes);