/*
 * =======================================================================
 * PROGRAMMER "BAHN, William"
 * TITLE      "Simple Utilty Functions"
 * CREATED    08 FEB 07
 * MODIFIED   08 FEB 07
 * FILENAME   "dirtyd.c"
 * =======================================================================
 */

/*
 * =======================================================================
 * GENERAL DESCRIPTION
 *
 * This file contains many useful functions - and more are added from time
 * to time.
 * =======================================================================
 */

/*
 * =======================================================================
 * REVISION HISTORY
 *
 * REV 2: 02 DEC 03
 * Added the GetBoundedInt() function
 * Added the InBounds() macro
 * Added the GetDouble() function
 *
 * REV 1: 28 NOV 03
 * Added the PI macro (good to 20 digits)
 * Added the StripCR() function.
 * Added the ClearBuffer() function.
 * Added the WaitForKey() function.
 *
 * REV 0: 09 NOV 03
 *
 * Initial Creation.
 * =======================================================================
 */


#ifndef _DirtyD_H
#define _DirtyD_H

// This directive prevents the prototypes and, most importantly, the
// function definitions (which would normally be in a separate .c file)
// from being included more than once.
//
// At the end of the excluded block of code, the identifier is defined.

//=========================================================================
//== INCLUDE FILES ========================================================
//=========================================================================
#include <stdio.h>  // FILE
#include "bytes.h"

//=========================================================================
//== MACRO DEFINITIONS ====================================================
//=========================================================================

#define FALSE (0)
#define TRUE  (!FALSE)

#define LO (FALSE)
#define HI (TRUE)

#define PI (3.1415926358979323846)

#define RET_DEFAULT (0)
#define RET_CLIPPED (1)

#define DD_CLIP_NONE   (0x00)
#define DD_CLIP_MIN    (0x01)
#define DD_CLIP_MAX    (0x02)
#define DD_CLIP_MINMAX (0x03)

#define BLANKLINE putc('\n', stdout);
#define EMPTYLOOP {}
#define NUL ('\0')

#define InBounds(min, test, max) ( ((min) <= (test)) && ((test) < (max)) )

//=========================================================================
//== FUNCTION PROTOTYPES ==================================================
//=========================================================================

// Get input from a stream
char     *fdgets(FILE *fp);
char      fdgetc(FILE *fp);
int       fdgeti(FILE *fp);
long int  fdgetl(FILE *fp);
float     fdgetf(FILE *fp);
double    fdgetd(FILE *fp);

// Get input from stdin
char     *dgets(void);
char      dgetc(void);
int       dgeti(void);
long int  dgetl(void);
float     dgetf(void);
double    dgetd(void);


void   PrintHeader(void);
char  *StripCR(char *s);
char  *GetFileName(char *name, char *ext, int size);
FILE  *OpenAndVerify(char *name, char *mode);
int    rand_int(int min, int max);
double rand_norm(void);
double rand_fp(double xmin, double max);
void   ExitIfError(int errcode);
int    GetBoundedInt(int min, int max, int def, int mode);
double GetBoundedDouble(double min, double max, double def, int mode);
double BoundedDouble(double x, double min, double max, int mode);
double StringToBoundedDouble(char *s, double def, double min, double max, int mode);

int    GetInt(int min, int max);
double GetDouble(double min, double max);

void *my_memory(FILE *log, void *p, size_t bytes, int action, char *s);
void free1D(void *p);
void *malloc1D(size_t cols, size_t size);
void free2D(void **p, size_t rows);
void **malloc2D(size_t rows, size_t cols, size_t size);
void free3D(void ***p, size_t sheets, size_t rows);
void ***malloc3D(size_t sheets, size_t rows, size_t cols, size_t size);

DWORD Bits2Bytes(DWORD bits);
BYTE *MemorySet(BYTE *p, DWORD bytes, BYTE v);
BYTE *MemoryCopy(BYTE *dest, BYTE *src, DWORD bytes);
void DisplayHEX(FILE *fp, BYTE *p, DWORD bytes, int mode);

BYTE GetBit(BYTE *d, size_t size, DWORD bit);
void SetBit(BYTE *d, size_t size, DWORD bit, int v);

char *ParseString(char *s, char* fdelim, char *tdelim);

DWORD rand_DWORD(DWORD max);

int memequal(char *s1, char *s2, DWORD bytes);

#endif